Skip to content
Snippets Groups Projects
Commit 3f3a4687 authored by alex's avatar alex
Browse files

b=3772

- race in dynlock_unlock() fixed: several threads may find refcount=0 and
  try to free lock member at the same time. thanks to Andreas!
parent 128352dc
No related branches found
No related tags found
No related merge requests found
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
Index: linux-2.4.24/include/linux/dynlocks.h 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.orig/include/linux/dynlocks.h 2003-01-30 13:24:37.000000000 +0300
+++ linux-2.4.24/include/linux/dynlocks.h 2004-07-16 14:17:00.000000000 +0400 +++ linux-2.4.24/include/linux/dynlocks.h 2004-07-18 11:09:33.000000000 +0400
@@ -0,0 +1,46 @@ @@ -0,0 +1,43 @@
+#ifndef _LINUX_DYNLOCKS_H +#ifndef _LINUX_DYNLOCKS_H
+#define _LINUX_DYNLOCKS_H +#define _LINUX_DYNLOCKS_H
+ +
...@@ -28,7 +28,6 @@ Index: linux-2.4.24/include/linux/dynlocks.h ...@@ -28,7 +28,6 @@ Index: linux-2.4.24/include/linux/dynlocks.h
+ int dl_writers; + int dl_writers;
+ int dl_pid; /* holder of the lock */ + int dl_pid; /* holder of the lock */
+ wait_queue_head_t dl_wait; + wait_queue_head_t dl_wait;
+ struct dynlock *dl_head;
+}; +};
+ +
+/* +/*
...@@ -43,8 +42,6 @@ Index: linux-2.4.24/include/linux/dynlocks.h ...@@ -43,8 +42,6 @@ Index: linux-2.4.24/include/linux/dynlocks.h
+ unsigned dl_magic; + unsigned dl_magic;
+ struct list_head dl_list; + struct list_head dl_list;
+ spinlock_t dl_list_lock; + spinlock_t dl_list_lock;
+ struct dynlock * dl_back;
+ int dl_locks;
+}; +};
+ +
+void dynlock_init(struct dynlock *dl); +void dynlock_init(struct dynlock *dl);
...@@ -57,8 +54,8 @@ Index: linux-2.4.24/include/linux/dynlocks.h ...@@ -57,8 +54,8 @@ Index: linux-2.4.24/include/linux/dynlocks.h
Index: linux-2.4.24/lib/dynlocks.c 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.orig/lib/dynlocks.c 2003-01-30 13:24:37.000000000 +0300
+++ linux-2.4.24/lib/dynlocks.c 2004-07-16 15:31:06.000000000 +0400 +++ linux-2.4.24/lib/dynlocks.c 2004-07-18 11:23:01.000000000 +0400
@@ -0,0 +1,247 @@ @@ -0,0 +1,187 @@
+/* +/*
+ * Dynamic Locks + * Dynamic Locks
+ * + *
...@@ -87,35 +84,6 @@ Index: linux-2.4.24/lib/dynlocks.c ...@@ -87,35 +84,6 @@ Index: linux-2.4.24/lib/dynlocks.c
+ panic("Can't create dynlock cache"); + 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 + * dynlock_init
+ * + *
...@@ -127,8 +95,6 @@ Index: linux-2.4.24/lib/dynlocks.c ...@@ -127,8 +95,6 @@ Index: linux-2.4.24/lib/dynlocks.c
+ spin_lock_init(&dl->dl_list_lock); + spin_lock_init(&dl->dl_list_lock);
+ INIT_LIST_HEAD(&dl->dl_list); + INIT_LIST_HEAD(&dl->dl_list);
+ dl->dl_magic = DYNLOCK_LIST_MAGIC; + dl->dl_magic = DYNLOCK_LIST_MAGIC;
+ dl->dl_back = dl;
+ dl->dl_locks = 0;
+} +}
+ +
+/* +/*
...@@ -149,12 +115,7 @@ Index: linux-2.4.24/lib/dynlocks.c ...@@ -149,12 +115,7 @@ Index: linux-2.4.24/lib/dynlocks.c
+ int num = 0; + int num = 0;
+ +
+ BUG_ON(dl == NULL); + BUG_ON(dl == NULL);
+ if (dl->dl_magic != DYNLOCK_LIST_MAGIC) { + BUG_ON(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: +repeat:
+ /* find requested lock in lockspace */ + /* find requested lock in lockspace */
+ spin_lock(&dl->dl_list_lock); + spin_lock(&dl->dl_list_lock);
...@@ -164,15 +125,7 @@ Index: linux-2.4.24/lib/dynlocks.c ...@@ -164,15 +125,7 @@ Index: linux-2.4.24/lib/dynlocks.c
+ BUG_ON(cur->next == NULL); + BUG_ON(cur->next == NULL);
+ BUG_ON(cur->prev == NULL); + BUG_ON(cur->prev == NULL);
+ hl = list_entry(cur, struct dynlock_member, dl_list); + hl = list_entry(cur, struct dynlock_member, dl_list);
+ if (hl->dl_magic != DYNLOCK_MAGIC || hl->dl_head != dl) { + BUG_ON(hl->dl_magic != DYNLOCK_MAGIC);
+ 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) { + if (hl->dl_value == value) {
+ /* lock is found */ + /* lock is found */
+ if (nhl) { + if (nhl) {
...@@ -193,7 +146,6 @@ Index: linux-2.4.24/lib/dynlocks.c ...@@ -193,7 +146,6 @@ Index: linux-2.4.24/lib/dynlocks.c
+ /* we already have allocated lock. use it */ + /* we already have allocated lock. use it */
+ hl = nhl; + hl = nhl;
+ nhl = NULL; + nhl = NULL;
+ dl->dl_locks++;
+ list_add(&hl->dl_list, &dl->dl_list); + list_add(&hl->dl_list, &dl->dl_list);
+ goto found; + goto found;
+ } + }
...@@ -208,7 +160,6 @@ Index: linux-2.4.24/lib/dynlocks.c ...@@ -208,7 +160,6 @@ Index: linux-2.4.24/lib/dynlocks.c
+ nhl->dl_readers = 0; + nhl->dl_readers = 0;
+ nhl->dl_writers = 0; + nhl->dl_writers = 0;
+ nhl->dl_magic = DYNLOCK_MAGIC; + nhl->dl_magic = DYNLOCK_MAGIC;
+ nhl->dl_head = dl;
+ init_waitqueue_head(&nhl->dl_wait); + init_waitqueue_head(&nhl->dl_wait);
+ +
+ /* while lock is being allocated, someone else may allocate it + /* while lock is being allocated, someone else may allocate it
...@@ -241,8 +192,6 @@ Index: linux-2.4.24/lib/dynlocks.c ...@@ -241,8 +192,6 @@ Index: linux-2.4.24/lib/dynlocks.c
+ hl->dl_pid = current->pid; + hl->dl_pid = current->pid;
+ spin_unlock(&dl->dl_list_lock); + spin_unlock(&dl->dl_list_lock);
+ +
+ BUG_ON(hl->dl_magic != DYNLOCK_MAGIC);
+ dynlock_check_consistency(dl);
+ return hl; + return hl;
+} +}
+ +
...@@ -262,16 +211,7 @@ Index: linux-2.4.24/lib/dynlocks.c ...@@ -262,16 +211,7 @@ Index: linux-2.4.24/lib/dynlocks.c
+ BUG_ON(dl == NULL); + BUG_ON(dl == NULL);
+ BUG_ON(hl == NULL); + BUG_ON(hl == NULL);
+ BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC); + BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC);
+ BUG_ON(dl->dl_back != dl); + BUG_ON(hl->dl_magic != DYNLOCK_MAGIC);
+ 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); + BUG_ON(current->pid != hl->dl_pid);
+ +
+ spin_lock(&dl->dl_list_lock); + spin_lock(&dl->dl_list_lock);
...@@ -294,12 +234,9 @@ Index: linux-2.4.24/lib/dynlocks.c ...@@ -294,12 +234,9 @@ Index: linux-2.4.24/lib/dynlocks.c
+ if (--(hl->dl_refcount) == 0) { + if (--(hl->dl_refcount) == 0) {
+ hl->dl_magic = DYNLOCK_MAGIC2; + hl->dl_magic = DYNLOCK_MAGIC2;
+ list_del(&hl->dl_list); + list_del(&hl->dl_list);
+ dl->dl_locks--; + kmem_cache_free(dynlock_cachep, hl);
+ } + }
+ spin_unlock(&dl->dl_list_lock); + spin_unlock(&dl->dl_list_lock);
+ if (hl->dl_refcount == 0)
+ kmem_cache_free(dynlock_cachep, hl);
+ dynlock_check_consistency(dl);
+} +}
+ +
+EXPORT_SYMBOL(dynlock_init); +EXPORT_SYMBOL(dynlock_init);
...@@ -309,7 +246,7 @@ Index: linux-2.4.24/lib/dynlocks.c ...@@ -309,7 +246,7 @@ Index: linux-2.4.24/lib/dynlocks.c
Index: linux-2.4.24/lib/Makefile Index: linux-2.4.24/lib/Makefile
=================================================================== ===================================================================
--- linux-2.4.24.orig/lib/Makefile 2004-06-24 09:06:32.000000000 +0400 --- 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 +++ linux-2.4.24/lib/Makefile 2004-07-16 15:54:06.000000000 +0400
@@ -9,10 +9,10 @@ @@ -9,10 +9,10 @@
L_TARGET := lib.a L_TARGET := lib.a
...@@ -326,7 +263,7 @@ Index: linux-2.4.24/lib/Makefile ...@@ -326,7 +263,7 @@ Index: linux-2.4.24/lib/Makefile
Index: linux-2.4.24/fs/dcache.c 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.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 +++ linux-2.4.24/fs/dcache.c 2004-07-16 15:54:06.000000000 +0400
@@ -1274,6 +1274,7 @@ @@ -1274,6 +1274,7 @@
extern void bdev_cache_init(void); extern void bdev_cache_init(void);
extern void cdev_cache_init(void); extern void cdev_cache_init(void);
......
...@@ -46,4 +46,3 @@ ext3-mds-num-2.4.24.patch ...@@ -46,4 +46,3 @@ ext3-mds-num-2.4.24.patch
export_lookup_create.patch export_lookup_create.patch
ext3-raw-lookup-pdirops.patch ext3-raw-lookup-pdirops.patch
kksymoops-2.4.24.vanilla.patch kksymoops-2.4.24.vanilla.patch
slab-use-after-free-debug-2.4.24.patch
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment