Whamcloud - gitweb
- vmlist needs to be exported for modules support
[fs/lustre-release.git] / lustre / kernel_patches / patches / dynamic-locks-2.4.24.patch
index b80f057..bd4d2f4 100644 (file)
@@ -6,15 +6,21 @@
 Index: linux-2.4.24/include/linux/dynlocks.h
 ===================================================================
 --- linux-2.4.24.orig/include/linux/dynlocks.h 2003-01-30 13:24:37.000000000 +0300
-+++ linux-2.4.24/include/linux/dynlocks.h      2004-03-01 19:29:53.000000000 +0300
-@@ -0,0 +1,33 @@
++++ linux-2.4.24/include/linux/dynlocks.h      2004-07-16 14:17:00.000000000 +0400
+@@ -0,0 +1,46 @@
 +#ifndef _LINUX_DYNLOCKS_H
 +#define _LINUX_DYNLOCKS_H
 +
 +#include <linux/list.h>
 +#include <linux/wait.h>
 +
++#define DYNLOCK_MAGIC         0xd19a10c
++#define DYNLOCK_MAGIC2                0xd1956ee
++
++struct dynlock;
++
 +struct dynlock_member {
++      unsigned                dl_magic;
 +      struct list_head        dl_list;
 +      unsigned long           dl_value;       /* lock value */
 +      int                     dl_refcount;    /* number of users */
@@ -22,6 +28,7 @@ Index: linux-2.4.24/include/linux/dynlocks.h
 +      int                     dl_writers;
 +      int                     dl_pid;         /* holder of the lock */
 +      wait_queue_head_t       dl_wait;
++      struct dynlock          *dl_head;
 +};
 +
 +/*
@@ -29,9 +36,15 @@ Index: linux-2.4.24/include/linux/dynlocks.h
 + *   - list of locks
 + *   - lock to protect this list
 + */
++
++#define DYNLOCK_LIST_MAGIC    0x11ee91e6
++
 +struct dynlock {
++      unsigned dl_magic;
 +      struct list_head dl_list;
 +      spinlock_t dl_list_lock;
++      struct dynlock * dl_back;
++      int dl_locks;
 +};
 +
 +void dynlock_init(struct dynlock *dl);
@@ -44,8 +57,8 @@ Index: linux-2.4.24/include/linux/dynlocks.h
 Index: linux-2.4.24/lib/dynlocks.c
 ===================================================================
 --- linux-2.4.24.orig/lib/dynlocks.c   2003-01-30 13:24:37.000000000 +0300
-+++ linux-2.4.24/lib/dynlocks.c        2004-03-01 19:29:53.000000000 +0300
-@@ -0,0 +1,152 @@
++++ linux-2.4.24/lib/dynlocks.c        2004-07-16 15:31:06.000000000 +0400
+@@ -0,0 +1,247 @@
 +/*
 + * Dynamic Locks
 + *
@@ -60,6 +73,49 @@ Index: linux-2.4.24/lib/dynlocks.c
 +#include <linux/slab.h>
 +#include <linux/sched.h>
 +
++static kmem_cache_t * dynlock_cachep = NULL;
++
++void __init dynlock_cache_init(void)
++{
++      printk(KERN_INFO "init dynlocks cache\n");
++      dynlock_cachep = kmem_cache_create("dynlock_cache",
++                                       sizeof(struct dynlock_member),
++                                       0,
++                                       SLAB_HWCACHE_ALIGN,
++                                       NULL, NULL);
++      if (dynlock_cachep == NULL)
++              panic("Can't create dynlock cache");
++}
++
++static void dynlock_check_consistency(struct dynlock *dl)
++{
++      struct dynlock_member *hl; 
++      struct list_head *cur;
++      int num = 0;
++      
++      spin_lock(&dl->dl_list_lock);
++      BUG_ON(dl == NULL);
++      BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC);
++      BUG_ON(dl->dl_back != dl);
++      list_for_each(cur, &dl->dl_list) {
++              BUG_ON(cur->next == NULL);
++              BUG_ON(cur->prev == NULL);
++              hl = list_entry(cur, struct dynlock_member, dl_list);
++              if (hl->dl_magic != DYNLOCK_MAGIC || hl->dl_head != dl) {
++                      printk("corrupted lock 0x%p/%d: magic 0x%x (!=0x%x)\n",
++                              hl, num, hl->dl_magic, DYNLOCK_MAGIC);
++                      printk("  value 0x%lx, %d readers, %d writers, pid %d, %d refs\n",
++                              hl->dl_value, hl->dl_readers, hl->dl_writers,
++                              hl->dl_pid, hl->dl_refcount);
++                      printk("   head 0x%p\n", hl->dl_head);
++                      BUG();
++              }
++              num++;
++      }
++      BUG_ON(num != dl->dl_locks);
++      spin_unlock(&dl->dl_list_lock);
++}
++
 +/*
 + * dynlock_init
 + *
@@ -70,6 +126,9 @@ Index: linux-2.4.24/lib/dynlocks.c
 +{
 +      spin_lock_init(&dl->dl_list_lock);
 +      INIT_LIST_HEAD(&dl->dl_list);
++      dl->dl_magic = DYNLOCK_LIST_MAGIC;
++      dl->dl_back = dl;
++      dl->dl_locks = 0;
 +}
 +
 +/*
@@ -87,12 +146,33 @@ Index: linux-2.4.24/lib/dynlocks.c
 +      struct dynlock_member *nhl = NULL; 
 +      struct dynlock_member *hl; 
 +      struct list_head *cur;
++      int num = 0;
 +
++      BUG_ON(dl == NULL);
++      if (dl->dl_magic != DYNLOCK_LIST_MAGIC) {
++              printk("corrupted dynlock head 0x%p: magic 0x%x (!=0x%x)\n",
++                      dl, dl->dl_magic, DYNLOCK_LIST_MAGIC);
++              BUG();
++      }
++      BUG_ON(dl->dl_back != dl);
 +repeat:
 +      /* find requested lock in lockspace */
 +      spin_lock(&dl->dl_list_lock);
++      BUG_ON(dl->dl_list.next == NULL);
++      BUG_ON(dl->dl_list.prev == NULL);
 +      list_for_each(cur, &dl->dl_list) {
++              BUG_ON(cur->next == NULL);
++              BUG_ON(cur->prev == NULL);
 +              hl = list_entry(cur, struct dynlock_member, dl_list);
++              if (hl->dl_magic != DYNLOCK_MAGIC || hl->dl_head != dl) {
++                      printk("corrupted lock 0x%p/%d: magic 0x%x (!=0x%x)\n",
++                              hl, num, hl->dl_magic, DYNLOCK_MAGIC);
++                      printk("  value 0x%lx, %d readers, %d writers, pid %d, %d refs\n",
++                              hl->dl_value, hl->dl_readers, hl->dl_writers,
++                              hl->dl_pid, hl->dl_refcount);
++                      printk("   head 0x%p\n", hl->dl_head);
++                      BUG();
++              }
 +              if (hl->dl_value == value) {
 +                      /* lock is found */
 +                      if (nhl) {
@@ -100,31 +180,35 @@ Index: linux-2.4.24/lib/dynlocks.c
 +                               * lock we didn't find and just created
 +                               * so, we drop our lock
 +                               */
-+                              kfree(nhl);
++                              kmem_cache_free(dynlock_cachep, nhl);
 +                              nhl = NULL;
 +                      }
 +                      hl->dl_refcount++;
 +                      goto found;
 +              }
++              num++;
 +      }
 +      /* lock not found */
 +      if (nhl) {
 +              /* we already have allocated lock. use it */
 +              hl = nhl;
 +              nhl = NULL;
++              dl->dl_locks++;
 +              list_add(&hl->dl_list, &dl->dl_list);
 +              goto found;
 +      }
 +      spin_unlock(&dl->dl_list_lock);
 +      
 +      /* lock not found and we haven't allocated lock yet. allocate it */
-+      nhl = kmalloc(sizeof(struct dynlock_member), gfp);
++      nhl = kmem_cache_alloc(dynlock_cachep, gfp);
 +      if (nhl == NULL)
 +              return NULL;
 +      nhl->dl_refcount = 1;
 +      nhl->dl_value = value;
 +      nhl->dl_readers = 0;
 +      nhl->dl_writers = 0;
++      nhl->dl_magic = DYNLOCK_MAGIC;
++      nhl->dl_head = dl;
 +      init_waitqueue_head(&nhl->dl_wait);
 +
 +      /* while lock is being allocated, someone else may allocate it
@@ -157,6 +241,8 @@ Index: linux-2.4.24/lib/dynlocks.c
 +      hl->dl_pid = current->pid;
 +      spin_unlock(&dl->dl_list_lock);
 +
++      BUG_ON(hl->dl_magic != DYNLOCK_MAGIC);
++      dynlock_check_consistency(dl);
 +      return hl;
 +}
 +
@@ -173,25 +259,47 @@ Index: linux-2.4.24/lib/dynlocks.c
 +      struct dynlock_member *hl = lock;
 +      int wakeup = 0;
 +      
++      BUG_ON(dl == NULL);
++      BUG_ON(hl == NULL);
++      BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC);
++      BUG_ON(dl->dl_back != dl);
++      if (hl->dl_magic != DYNLOCK_MAGIC || hl->dl_head != dl) {
++              printk("corrupted lock 0x%p: magic 0x%x (!=0x%x)\n",
++                              hl, hl->dl_magic, DYNLOCK_MAGIC);
++              printk("  value 0x%lx, %d readers, %d writers, pid %d, %d refs\n",
++                              hl->dl_value, hl->dl_readers, hl->dl_writers,
++                              hl->dl_pid, hl->dl_refcount);
++              printk("   head 0x%p\n", hl->dl_head);
++              BUG();
++      }
++      BUG_ON(current->pid != hl->dl_pid);
++
 +      spin_lock(&dl->dl_list_lock);
 +      if (hl->dl_writers) {
++              BUG_ON(hl->dl_readers > 0 || hl->dl_readers < 0);
 +              hl->dl_writers--;
 +              if (hl->dl_writers == 0)
 +                      wakeup = 1;
-+      } else {
++      } else if (hl->dl_readers) {
 +              hl->dl_readers--;
 +              if (hl->dl_readers == 0)
 +                      wakeup = 1;
++      } else {
++              BUG_ON(1);
 +      }
 +      if (wakeup) {
 +              hl->dl_pid = 0;
 +              wake_up(&hl->dl_wait);
 +      }
-+      if (--(hl->dl_refcount) == 0) 
++      if (--(hl->dl_refcount) == 0) {
++              hl->dl_magic = DYNLOCK_MAGIC2;
 +              list_del(&hl->dl_list);
++              dl->dl_locks--;
++      }
 +      spin_unlock(&dl->dl_list_lock);
 +      if (hl->dl_refcount == 0)
-+              kfree(hl);
++              kmem_cache_free(dynlock_cachep, hl);
++      dynlock_check_consistency(dl);
 +}
 +
 +EXPORT_SYMBOL(dynlock_init);
@@ -200,8 +308,8 @@ Index: linux-2.4.24/lib/dynlocks.c
 +
 Index: linux-2.4.24/lib/Makefile
 ===================================================================
---- linux-2.4.24.orig/lib/Makefile     2004-02-02 21:52:31.000000000 +0300
-+++ linux-2.4.24/lib/Makefile  2004-03-01 19:30:25.000000000 +0300
+--- linux-2.4.24.orig/lib/Makefile     2004-06-24 09:06:32.000000000 +0400
++++ linux-2.4.24/lib/Makefile  2004-07-14 18:14:28.000000000 +0400
 @@ -9,10 +9,10 @@
  L_TARGET := lib.a
  
@@ -215,3 +323,21 @@ Index: linux-2.4.24/lib/Makefile
  
  obj-$(CONFIG_FW_LOADER) += firmware_class.o
  obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
+Index: linux-2.4.24/fs/dcache.c
+===================================================================
+--- linux-2.4.24.orig/fs/dcache.c      2004-07-16 12:35:54.000000000 +0400
++++ linux-2.4.24/fs/dcache.c   2004-07-16 12:36:14.000000000 +0400
+@@ -1274,6 +1274,7 @@
+ extern void bdev_cache_init(void);
+ extern void cdev_cache_init(void);
+ extern void iobuf_cache_init(void);
++extern void dynlock_cache_init(void);
+ void __init vfs_caches_init(unsigned long mempages)
+ {
+@@ -1310,4 +1311,5 @@
+       bdev_cache_init();
+       cdev_cache_init();
+       iobuf_cache_init();
++      dynlock_cache_init();
+ }