locking/ww_mutex/test: Fix potential workqueue corruption
[linux-2.6-microblaze.git] / kernel / locking / test-ww_mutex.c
index 9bceba6..358d661 100644 (file)
@@ -479,7 +479,6 @@ retry:
        } while (!time_after(jiffies, stress->timeout));
 
        kfree(order);
-       kfree(stress);
 }
 
 struct reorder_lock {
@@ -544,7 +543,6 @@ out:
        list_for_each_entry_safe(ll, ln, &locks, link)
                kfree(ll);
        kfree(order);
-       kfree(stress);
 }
 
 static void stress_one_work(struct work_struct *work)
@@ -565,8 +563,6 @@ static void stress_one_work(struct work_struct *work)
                        break;
                }
        } while (!time_after(jiffies, stress->timeout));
-
-       kfree(stress);
 }
 
 #define STRESS_INORDER BIT(0)
@@ -577,15 +573,24 @@ static void stress_one_work(struct work_struct *work)
 static int stress(int nlocks, int nthreads, unsigned int flags)
 {
        struct ww_mutex *locks;
-       int n;
+       struct stress *stress_array;
+       int n, count;
 
        locks = kmalloc_array(nlocks, sizeof(*locks), GFP_KERNEL);
        if (!locks)
                return -ENOMEM;
 
+       stress_array = kmalloc_array(nthreads, sizeof(*stress_array),
+                                    GFP_KERNEL);
+       if (!stress_array) {
+               kfree(locks);
+               return -ENOMEM;
+       }
+
        for (n = 0; n < nlocks; n++)
                ww_mutex_init(&locks[n], &ww_class);
 
+       count = 0;
        for (n = 0; nthreads; n++) {
                struct stress *stress;
                void (*fn)(struct work_struct *work);
@@ -609,9 +614,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags)
                if (!fn)
                        continue;
 
-               stress = kmalloc(sizeof(*stress), GFP_KERNEL);
-               if (!stress)
-                       break;
+               stress = &stress_array[count++];
 
                INIT_WORK(&stress->work, fn);
                stress->locks = locks;
@@ -626,6 +629,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags)
 
        for (n = 0; n < nlocks; n++)
                ww_mutex_destroy(&locks[n]);
+       kfree(stress_array);
        kfree(locks);
 
        return 0;