Commit 65e5a0e18e5fb5bc6cfabd8ef4b9fc1c8569ba62

Authored by Daniel Drake
Committed by David Woodhouse
1 parent b46daf7eb1

jffs2: Dynamically choose inocache hash size

When JFFS2 is used for large volumes, the mount times are quite long.
Increasing the hash size provides a significant speed boost on the OLPC
XO-1 laptop.

Add logic that dynamically selects a hash size based on the size of
the medium. A 64mb medium will result in a hash size of 128, and a 512mb
medium will result in a hash size of 1024.

Signed-off-by: Daniel Drake <dsd@laptop.org>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>

Showing 5 changed files with 29 additions and 7 deletions Side-by-side Diff

... ... @@ -23,7 +23,7 @@
23 23 static inline struct jffs2_inode_cache *
24 24 first_inode_chain(int *i, struct jffs2_sb_info *c)
25 25 {
26   - for (; *i < INOCACHE_HASHSIZE; (*i)++) {
  26 + for (; *i < c->inocache_hashsize; (*i)++) {
27 27 if (c->inocache_list[*i])
28 28 return c->inocache_list[*i];
29 29 }
... ... @@ -478,7 +478,26 @@
478 478 return inode;
479 479 }
480 480  
  481 +static int calculate_inocache_hashsize(uint32_t flash_size)
  482 +{
  483 + /*
  484 + * Pick a inocache hash size based on the size of the medium.
  485 + * Count how many megabytes we're dealing with, apply a hashsize twice
  486 + * that size, but rounding down to the usual big powers of 2. And keep
  487 + * to sensible bounds.
  488 + */
481 489  
  490 + int size_mb = flash_size / 1024 / 1024;
  491 + int hashsize = (size_mb * 2) & ~0x3f;
  492 +
  493 + if (hashsize < INOCACHE_HASHSIZE_MIN)
  494 + return INOCACHE_HASHSIZE_MIN;
  495 + if (hashsize > INOCACHE_HASHSIZE_MAX)
  496 + return INOCACHE_HASHSIZE_MAX;
  497 +
  498 + return hashsize;
  499 +}
  500 +
482 501 int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
483 502 {
484 503 struct jffs2_sb_info *c;
... ... @@ -524,7 +543,8 @@
524 543 if (ret)
525 544 return ret;
526 545  
527   - c->inocache_list = kcalloc(INOCACHE_HASHSIZE, sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
  546 + c->inocache_hashsize = calculate_inocache_hashsize(c->flash_size);
  547 + c->inocache_list = kcalloc(c->inocache_hashsize, sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
528 548 if (!c->inocache_list) {
529 549 ret = -ENOMEM;
530 550 goto out_wbuf;
fs/jffs2/jffs2_fs_sb.h
... ... @@ -100,6 +100,7 @@
100 100 wait_queue_head_t erase_wait; /* For waiting for erases to complete */
101 101  
102 102 wait_queue_head_t inocache_wq;
  103 + int inocache_hashsize;
103 104 struct jffs2_inode_cache **inocache_list;
104 105 spinlock_t inocache_lock;
105 106  
... ... @@ -420,7 +420,7 @@
420 420 {
421 421 struct jffs2_inode_cache *ret;
422 422  
423   - ret = c->inocache_list[ino % INOCACHE_HASHSIZE];
  423 + ret = c->inocache_list[ino % c->inocache_hashsize];
424 424 while (ret && ret->ino < ino) {
425 425 ret = ret->next;
426 426 }
... ... @@ -441,7 +441,7 @@
441 441  
442 442 dbg_inocache("add %p (ino #%u)\n", new, new->ino);
443 443  
444   - prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE];
  444 + prev = &c->inocache_list[new->ino % c->inocache_hashsize];
445 445  
446 446 while ((*prev) && (*prev)->ino < new->ino) {
447 447 prev = &(*prev)->next;
... ... @@ -462,7 +462,7 @@
462 462 dbg_inocache("del %p (ino #%u)\n", old, old->ino);
463 463 spin_lock(&c->inocache_lock);
464 464  
465   - prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
  465 + prev = &c->inocache_list[old->ino % c->inocache_hashsize];
466 466  
467 467 while ((*prev) && (*prev)->ino < old->ino) {
468 468 prev = &(*prev)->next;
... ... @@ -487,7 +487,7 @@
487 487 int i;
488 488 struct jffs2_inode_cache *this, *next;
489 489  
490   - for (i=0; i<INOCACHE_HASHSIZE; i++) {
  490 + for (i=0; i < c->inocache_hashsize; i++) {
491 491 this = c->inocache_list[i];
492 492 while (this) {
493 493 next = this->next;
... ... @@ -199,7 +199,8 @@
199 199 #define RAWNODE_CLASS_XATTR_DATUM 1
200 200 #define RAWNODE_CLASS_XATTR_REF 2
201 201  
202   -#define INOCACHE_HASHSIZE 128
  202 +#define INOCACHE_HASHSIZE_MIN 128
  203 +#define INOCACHE_HASHSIZE_MAX 1024
203 204  
204 205 #define write_ofs(c) ((c)->nextblock->offset + (c)->sector_size - (c)->nextblock->free_size)
205 206