All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com>
To: grub-devel@gnu.org
Subject: Re: ReiserFS reading performance patch
Date: Tue, 01 May 2012 19:59:49 +0200	[thread overview]
Message-ID: <4FA02495.7040405@gmail.com> (raw)
In-Reply-To: <CAO1Q+jcf-aQZ704GCoJYvWnM3gyssB9aZwtnRJWEp4VC8T3W3A@mail.gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 946 bytes --]

On 27.04.2012 16:05, Albert Zeyer wrote:
> Hi,
>
> A while ago, I improved the grub-mount patches a bit. Mostly:
You've based your work on abandonded branch. All grub-mount parts were
merged back in trunk a long time ago. At least half of the work you've
done was unnecessary with newer version.
> * Write a simplified compile.py script.
Custom compile scripts are likely to break often. If there were any
problem in our compile scripts for your platform it's better to announce
it here.
> * Remove nested functions. They don't work on Mac because of stack
> execution protection.
As I said, your approach isn't just ugly it results in bugs.
> * Improve ReiserFS reading performance.
I wrote reiserfs caching a long time ago but it didn'tmake any sizeable
difference. As for making offset search a logarithmic, here is a patch
by few simple modifications of get_item.


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: reiserspeed.diff --]
[-- Type: text/x-diff; name="reiserspeed.diff", Size: 14392 bytes --]

=== modified file 'grub-core/Makefile.am'
--- grub-core/Makefile.am	2012-02-29 14:08:08 +0000
+++ grub-core/Makefile.am	2012-05-01 14:19:39 +0000
@@ -96,6 +96,7 @@
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/time.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
 endif
 
 if COND_i386_coreboot
@@ -126,6 +127,7 @@
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/time.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
 endif
 
 if COND_ia64_efi

=== modified file 'grub-core/Makefile.core.def'
--- grub-core/Makefile.core.def	2012-04-01 19:35:18 +0000
+++ grub-core/Makefile.core.def	2012-05-01 13:59:06 +0000
@@ -139,11 +139,13 @@
 
   i386_efi = kern/i386/tsc.c;
   i386_efi = kern/i386/efi/init.c;
+  i386_efi = bus/pci.c;
 
   x86_64_efi = kern/i386/tsc.c;
   x86_64_efi = kern/x86_64/dl.c;
   x86_64_efi = kern/x86_64/efi/callwrap.S;
   x86_64_efi = kern/i386/efi/init.c;
+  x86_64_efi = bus/pci.c;
 
   ia64_efi = kern/ia64/efi/startup.S;
   ia64_efi = kern/ia64/efi/init.c;
@@ -475,8 +477,6 @@
   common = bus/pci.c;
 
   enable = i386_pc;
-  enable = i386_efi;
-  enable = x86_64_efi;
   enable = i386_ieee1275;
   enable = i386_coreboot;
   enable = i386_multiboot;

=== modified file 'grub-core/commands/legacycfg.c'
--- grub-core/commands/legacycfg.c	2012-03-06 13:11:10 +0000
+++ grub-core/commands/legacycfg.c	2012-05-01 12:23:30 +0000
@@ -123,7 +123,8 @@
 		return grub_errno;
 	      }
 	    args[0] = oldname;
-	    grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, NULL,
+	    grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy",
+					NULL, NULL,
 					entrysrc, 0);
 	    grub_free (args);
 	    entrysrc[0] = 0;

=== modified file 'grub-core/commands/menuentry.c'
--- grub-core/commands/menuentry.c	2012-03-19 09:56:43 +0000
+++ grub-core/commands/menuentry.c	2012-05-01 12:22:47 +0000
@@ -37,6 +37,8 @@
     {"source", 4, 0,
      N_("Use STRING as menu entry body."), N_("STRING"), ARG_TYPE_STRING},
     {"id", 0, 0, N_("Menu entry identifier."), N_("STRING"), ARG_TYPE_STRING},
+    {"unrestricted", 0, 0, N_("This entry can be booted by any user."),
+     0, ARG_TYPE_NONE},
     {0, 0, 0, 0, 0, 0}
   };
 
@@ -254,6 +256,7 @@
   char *prefix;
   unsigned len;
   grub_err_t r;
+  const char *users;
 
   if (! argc)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing arguments");
@@ -264,12 +267,19 @@
   if (! ctxt->state[3].set && ! ctxt->script)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition");
 
+  if (ctxt->state[1].set)
+    users = ctxt->state[1].arg;
+  else if (ctxt->state[5].set)
+    users = NULL;
+  else
+    users = "";
+
   if (! ctxt->script)
     return grub_normal_add_menu_entry (argc, (const char **) args,
 				       (ctxt->state[0].set ? ctxt->state[0].args
 					: NULL),
 				       ctxt->state[4].arg,
-				       ctxt->state[1].arg,
+				       users,
 				       ctxt->state[2].arg, 0,
 				       ctxt->state[3].arg,
 				       ctxt->extcmd->cmd->name[0] == 's');
@@ -287,7 +297,7 @@
 
   r = grub_normal_add_menu_entry (argc - 1, (const char **) args,
 				  ctxt->state[0].args, ctxt->state[4].arg,
-				  ctxt->state[1].arg,
+				  users,
 				  ctxt->state[2].arg, prefix, src + 1,
 				  ctxt->extcmd->cmd->name[0] == 's');
 

=== modified file 'grub-core/fs/reiserfs.c'
--- grub-core/fs/reiserfs.c	2012-02-27 20:36:58 +0000
+++ grub-core/fs/reiserfs.c	2012-05-01 15:44:15 +0000
@@ -468,7 +468,7 @@
 static grub_err_t
 grub_reiserfs_get_item (struct grub_reiserfs_data *data,
                         const struct grub_reiserfs_key *key,
-                        struct grub_fshelp_node *item)
+                        struct grub_fshelp_node *item, int exact)
 {
   grub_uint32_t block_number;
   struct grub_reiserfs_block_header *block_header = 0;
@@ -581,30 +581,47 @@
           item_headers
             = (struct grub_reiserfs_item_header *) (block_header + 1);
           for (i = 0;
-               i < item_count
-                 && (grub_reiserfs_compare_keys (key, &(item_headers[i].key))
-                     != 0);
+               i < item_count;
                i++)
-            {
-#ifdef GRUB_REISERFS_DEBUG
-              if (key->directory_id == item_headers[i].key.directory_id && \
-                  key->object_id == item_headers[i].key.object_id)
-                grub_printf("C");
-              else
-                grub_printf(" ");
-              grub_printf(" %03d/%03d ", i + 1, item_count);
-              grub_reiserfs_print_key (&(item_headers[i].key));
-#endif
-            }
-          if (i < item_count)
-            block_key = &(item_headers[i].key);
+	    {
+	      int val;
+	      val = grub_reiserfs_compare_keys (key, &(item_headers[i].key));
+	      if (val == 0)
+		{
+		  block_key = &(item_headers[i].key);
+		  break;
+		}
+	      if (val < 0 && exact)
+		break;
+	      if (val < 0)
+		{
+		  if (i == 0)
+		    {
+		      grub_error (GRUB_ERR_READ_ERROR, "unexpected btree node");
+		      goto fail;
+		    }
+		  i--;
+		  block_key = &(item_headers[i].key);
+		  break;
+		}
+	    }
+	  if (!exact && i == item_count)
+	    {
+	      if (i == 0)
+		{
+		  grub_error (GRUB_ERR_READ_ERROR, "unexpected btree node");
+		  goto fail;
+		}
+	      i--;
+	      block_key = &(item_headers[i].key);
+	    }
         }
     }
   while (current_level > 1);
 
   item->data = data;
 
-  if (i == item_count || grub_reiserfs_compare_keys (key, block_key))
+  if (!block_key)
     {
       item->block_number = 0;
       item->block_position = 0;
@@ -654,7 +671,7 @@
   grub_reiserfs_set_key_type (&key, GRUB_REISERFS_DIRECT,
                               grub_reiserfs_get_key_version (&key));
 
-  if (grub_reiserfs_get_item (node->data, &key, &found) != GRUB_ERR_NONE)
+  if (grub_reiserfs_get_item (node->data, &key, &found, 1) != GRUB_ERR_NONE)
     goto fail;
 
   if (found.block_number == 0)
@@ -797,7 +814,7 @@
               if (! entry_item)
                 goto fail;
 
-              if (grub_reiserfs_get_item (data, &entry_key, entry_item)
+              if (grub_reiserfs_get_item (data, &entry_key, entry_item, 1)
                   != GRUB_ERR_NONE)
                 {
                   grub_free (entry_item);
@@ -816,7 +833,7 @@
                   grub_reiserfs_set_key_offset (&entry_key, 0);
                   grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_STAT,
                                               2);
-                  if (grub_reiserfs_get_item (data, &entry_key, entry_item)
+                  if (grub_reiserfs_get_item (data, &entry_key, entry_item, 1)
                       != GRUB_ERR_NONE)
                     {
                       grub_free (entry_item);
@@ -959,7 +976,7 @@
       grub_reiserfs_set_key_offset (&(item_headers[block_position].key),
                                     next_offset);
       if (grub_reiserfs_get_item (data, &(item_headers[block_position].key),
-                                  &directory_item) != GRUB_ERR_NONE)
+                                  &directory_item, 1) != GRUB_ERR_NONE)
         goto fail;
       block_number = directory_item.block_number;
       block_position = directory_item.block_position;
@@ -1001,7 +1018,7 @@
   key.u.v2.offset_type = 0;
   grub_reiserfs_set_key_type (&key, GRUB_REISERFS_DIRECTORY, 2);
   grub_reiserfs_set_key_offset (&key, 1);
-  if (grub_reiserfs_get_item (data, &key, &root) != GRUB_ERR_NONE)
+  if (grub_reiserfs_get_item (data, &key, &root, 1) != GRUB_ERR_NONE)
     goto fail;
   if (root.block_number == 0)
     {
@@ -1017,7 +1034,7 @@
   key.object_id = found->header.key.object_id;
   grub_reiserfs_set_key_type (&key, GRUB_REISERFS_STAT, 2);
   grub_reiserfs_set_key_offset (&key, 0);
-  if (grub_reiserfs_get_item (data, &key, &info) != GRUB_ERR_NONE)
+  if (grub_reiserfs_get_item (data, &key, &info, 1) != GRUB_ERR_NONE)
     goto fail;
   if (info.block_number == 0)
     {
@@ -1097,11 +1114,27 @@
 		(unsigned long long) final_position,
 		(unsigned long long) (final_position - initial_position),
 		(unsigned long) len);
+
+  grub_reiserfs_set_key_offset (&key, initial_position + 1);
+
+  if (grub_reiserfs_get_item (data, &key, &found, 0) != GRUB_ERR_NONE)
+    goto fail;
+
+  if (found.block_number == 0)
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "offset %lld not found",
+		  (unsigned long long) initial_position);
+      goto fail;
+    }
+
+  current_key_offset = grub_reiserfs_get_key_offset (&found.header.key);
+  current_position = current_key_offset - 1;
+
   while (current_position < final_position)
     {
       grub_reiserfs_set_key_offset (&key, current_key_offset);
 
-      if (grub_reiserfs_get_item (data, &key, &found) != GRUB_ERR_NONE)
+      if (grub_reiserfs_get_item (data, &key, &found, 1) != GRUB_ERR_NONE)
         goto fail;
       if (found.block_number == 0)
         goto fail;
@@ -1245,7 +1278,7 @@
 
  fail:
   grub_free (indirect_block_ptr);
-  return 0;
+  return -1;
 }
 
 /* Close the file FILE.  */
@@ -1296,7 +1329,7 @@
   root_key.u.v2.offset_type = 0;
   grub_reiserfs_set_key_type (&root_key, GRUB_REISERFS_DIRECTORY, 2);
   grub_reiserfs_set_key_offset (&root_key, 1);
-  if (grub_reiserfs_get_item (data, &root_key, &root) != GRUB_ERR_NONE)
+  if (grub_reiserfs_get_item (data, &root_key, &root, 1) != GRUB_ERR_NONE)
     goto fail;
   if (root.block_number == 0)
     {

=== modified file 'grub-core/kern/efi/mm.c'
--- grub-core/kern/efi/mm.c	2011-05-15 09:22:59 +0000
+++ grub-core/kern/efi/mm.c	2012-04-28 16:11:38 +0000
@@ -22,6 +22,10 @@
 #include <grub/efi/api.h>
 #include <grub/efi/efi.h>
 
+#if defined (__i386__) || defined (__x86_64__)
+#include <grub/pci.h>
+#endif
+
 #define NEXT_MEMORY_DESCRIPTOR(desc, size)	\
   ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
 
@@ -103,6 +107,74 @@
   efi_call_2 (b->free_pages, address, pages);
 }
 
+#if defined (__i386__) || defined (__x86_64__)
+
+static grub_uint8_t
+find_cap (grub_pci_device_t dev, grub_uint8_t cap)
+{
+  grub_uint8_t pos = 0x34;
+  int ttl = 48;
+
+  while (ttl--)
+    {
+      grub_uint8_t id;
+      grub_pci_address_t addr;
+
+      addr = grub_pci_make_address (dev, pos);
+      pos = grub_pci_read_byte (addr);
+      if (pos < 0x40)
+	break;
+
+      pos &= ~3;
+
+      addr = grub_pci_make_address (dev, pos);      
+      id = grub_pci_read_byte (addr);
+
+      if (id == 0xff)
+	break;
+      
+      if (id == cap)
+	return pos;
+      pos++;
+    }
+  return 0;
+}
+
+static void
+stop_broadcom (void)
+{
+  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
+				       grub_pci_id_t pciid);
+
+  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
+				  grub_pci_id_t pciid)
+    {
+      grub_pci_address_t addr;
+      grub_uint8_t cap;
+      grub_uint16_t pm_state;
+
+      if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM)
+	return 0;
+
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+      if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK)
+	return 0;
+      cap = find_cap (dev, GRUB_PCI_CAP_POWER_MANAGEMENT);
+      if (!cap)
+	return 0;
+      addr = grub_pci_make_address (dev, cap + 4);
+      pm_state = grub_pci_read_word (addr);
+      pm_state = pm_state | 0x03;
+      grub_pci_write_word (addr, pm_state);
+      grub_pci_read_word (addr);
+      return 0;
+    }
+
+  grub_pci_iterate (find_card);
+}
+
+#endif
+
 grub_err_t
 grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf,
 			       grub_efi_uintn_t *map_key,
@@ -112,6 +184,14 @@
   grub_efi_boot_services_t *b;
   grub_efi_status_t status;
 
+#if defined (__i386__) || defined (__x86_64__)
+  const grub_uint16_t apple[] = { 'A', 'p', 'p', 'l', 'e' };
+  int is_apple;
+
+  is_apple = (grub_memcmp (grub_efi_system_table->firmware_vendor,
+			   apple, sizeof (apple)) == 0);
+#endif
+
   if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
 			       &finish_desc_size, &finish_desc_version) < 0)
     return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
@@ -145,6 +225,11 @@
   if (efi_desc_version)
     *efi_desc_version = finish_desc_version;
 
+#if defined (__i386__) || defined (__x86_64__)
+  if (is_apple)
+    stop_broadcom ();
+#endif
+
   return GRUB_ERR_NONE;
 }
 

=== modified file 'grub-core/lib/relocator.c'
--- grub-core/lib/relocator.c	2012-04-13 14:55:20 +0000
+++ grub-core/lib/relocator.c	2012-05-01 12:30:35 +0000
@@ -368,7 +368,7 @@
 							    GRUB_MM_ALIGN);
 	h->size
 	  = ((subchu->start + subchu->size + GRUB_MM_ALIGN - 1) / GRUB_MM_ALIGN)
-	  - (subchu->start / GRUB_MM_ALIGN) - 1;
+	  - (subchu->start / GRUB_MM_ALIGN);
 	h->next = h;
 	h->magic = GRUB_MM_ALLOC_MAGIC;
 	grub_free (h + 1);

=== modified file 'include/grub/pci.h'
--- include/grub/pci.h	2011-10-01 19:37:02 +0000
+++ include/grub/pci.h	2012-04-28 15:59:34 +0000
@@ -81,6 +81,19 @@
 #define  GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT 9
 #define  GRUB_PCI_STATUS_DEVSEL_TIMING_MASK 0x0600
 #define  GRUB_PCI_CLASS_SUBCLASS_VGA  0x0300
+enum
+  {
+    GRUB_PCI_CLASS_NETWORK = 0x02
+  };
+enum
+  {
+    GRUB_PCI_CAP_POWER_MANAGEMENT = 0x01
+  };
+
+enum
+  {
+    GRUB_PCI_VENDOR_BROADCOM = 0x14e4
+  };
 
 #ifndef ASM_FILE
 typedef grub_uint32_t grub_pci_id_t;

=== modified file 'util/grub.d/00_header.in'
--- util/grub.d/00_header.in	2012-03-04 13:55:13 +0000
+++ util/grub.d/00_header.in	2012-04-29 19:49:48 +0000
@@ -278,9 +278,15 @@
 	else
 	    verbose=" --verbose"
 	fi
+	timeout="$2"
+	if [ "x${timeout}" = "x0" ]; then
+	    timeout=10
+	fi  
 	cat << EOF
 if sleep$verbose --interruptible ${1} ; then
-  set timeout=${2}
+  set timeout=0
+else
+  set timeout=${timeout}
 fi
 EOF
     else


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

  parent reply	other threads:[~2012-05-01 18:00 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-27 14:05 ReiserFS reading performance patch Albert Zeyer
2012-04-27 18:36 ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-04-27 20:31   ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-04-28 10:06     ` Bean
2012-04-28 11:08       ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-05-01 17:59 ` Vladimir 'φ-coder/phcoder' Serbinenko [this message]
2012-05-01 18:16   ` Vladimir 'φ-coder/phcoder' Serbinenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4FA02495.7040405@gmail.com \
    --to=phcoder@gmail.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.