]> git.proxmox.com Git - mirror_spl.git/blobdiff - module/splat/splat-rwlock.c
Refactor some splat macro to function
[mirror_spl.git] / module / splat / splat-rwlock.c
index a865fb3108c8e47cbfb3369719abea499cc9bee1..c11ab94f2a2de262ab558ca8ff9ecd2245eb39e5 100644 (file)
  *  Solaris Porting LAyer Tests (SPLAT) Read/Writer Lock Tests.
 \*****************************************************************************/
 
+#include <sys/random.h>
 #include <sys/rwlock.h>
 #include <sys/taskq.h>
-#include <sys/random.h>
+#include <linux/delay.h>
+#include <linux/mm_compat.h>
 #include "splat-internal.h"
 
 #define SPLAT_RWLOCK_NAME              "rwlock"
 #define SPLAT_RWLOCK_TEST5_DESC                "Write downgrade"
 
 #define SPLAT_RWLOCK_TEST6_ID          0x0706
-#define SPLAT_RWLOCK_TEST6_NAME                "rw_tryupgrade"
-#define SPLAT_RWLOCK_TEST6_DESC                "Read upgrade"
+#define SPLAT_RWLOCK_TEST6_NAME                "rw_tryupgrade-1"
+#define SPLAT_RWLOCK_TEST6_DESC                "rwsem->count value"
+
+#define SPLAT_RWLOCK_TEST7_ID          0x0707
+#define SPLAT_RWLOCK_TEST7_NAME                "rw_tryupgrade-2"
+#define SPLAT_RWLOCK_TEST7_DESC                "Read upgrade"
 
 #define SPLAT_RWLOCK_TEST_MAGIC                0x115599DDUL
 #define SPLAT_RWLOCK_TEST_NAME         "rwlock_test"
@@ -215,10 +221,10 @@ splat_rwlock_test1(struct file *file, void *arg)
 
                /* The first thread will be the writer */
                if (i == 0)
-                       rwt[i].rwt_thread = kthread_create(splat_rwlock_wr_thr,
+                       rwt[i].rwt_thread = spl_kthread_create(splat_rwlock_wr_thr,
                            &rwt[i], "%s/%d", SPLAT_RWLOCK_TEST_NAME, i);
                else
-                       rwt[i].rwt_thread = kthread_create(splat_rwlock_rd_thr,
+                       rwt[i].rwt_thread = spl_kthread_create(splat_rwlock_rd_thr,
                            &rwt[i], "%s/%d", SPLAT_RWLOCK_TEST_NAME, i);
 
                if (!IS_ERR(rwt[i].rwt_thread)) {
@@ -325,7 +331,7 @@ splat_rwlock_test2(struct file *file, void *arg)
 
        /* Create several threads allowing tasks to race with each other */
        tq = taskq_create(SPLAT_RWLOCK_TEST_TASKQ, num_online_cpus(),
-                         maxclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE);
+                         defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE);
        if (tq == NULL) {
                rc = -ENOMEM;
                goto out;
@@ -342,7 +348,8 @@ splat_rwlock_test2(struct file *file, void *arg)
         * rwlock is implemented right this will never happy, that's a pass.
         */
        for (i = 0; i < tq_count; i++) {
-               if (!taskq_dispatch(tq,splat_rwlock_test2_func,rwp,TQ_SLEEP)) {
+               if (taskq_dispatch(tq, splat_rwlock_test2_func, rwp,
+                   TQ_SLEEP) == TASKQID_INVALID) {
                        splat_vprint(file, SPLAT_RWLOCK_TEST2_NAME,
                                     "Failed to queue task %d\n", i);
                        rc = -EINVAL;
@@ -463,7 +470,7 @@ splat_rwlock_test4_type(taskq_t *tq, rw_priv_t *rwp, int expected_rc,
                rw_enter(&rwp->rw_rwlock, holder_type);
 
        id = taskq_dispatch(tq, splat_rwlock_test4_func, rwp, TQ_SLEEP);
-       if (id == 0) {
+       if (id == TASKQID_INVALID) {
                splat_vprint(rwp->rw_file, SPLAT_RWLOCK_TEST4_NAME, "%s",
                             "taskq_dispatch() failed\n");
                rc = -EINVAL;
@@ -498,7 +505,7 @@ splat_rwlock_test4(struct file *file, void *arg)
        if (rwp == NULL)
                return -ENOMEM;
 
-       tq = taskq_create(SPLAT_RWLOCK_TEST_TASKQ, 1, maxclsyspri,
+       tq = taskq_create(SPLAT_RWLOCK_TEST_TASKQ, 1, defclsyspri,
                          50, INT_MAX, TASKQ_PREPOPULATE);
        if (tq == NULL) {
                rc = -ENOMEM;
@@ -578,19 +585,65 @@ splat_rwlock_test6(struct file *file, void *arg)
        splat_init_rw_priv(rwp, file);
 
        rw_enter(&rwp->rw_rwlock, RW_READER);
-       if (!RW_READ_HELD(&rwp->rw_rwlock)) {
+       if (RWSEM_COUNT(SEM(&rwp->rw_rwlock)) !=
+           SPL_RWSEM_SINGLE_READER_VALUE) {
+               splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME,
+                   "We assumed single reader rwsem->count "
+                   "should be %ld, but is %ld\n",
+                   (long int)SPL_RWSEM_SINGLE_READER_VALUE,
+                   (long int)RWSEM_COUNT(SEM(&rwp->rw_rwlock)));
+               rc = -ENOLCK;
+               goto out;
+       }
+       rw_exit(&rwp->rw_rwlock);
+
+       rw_enter(&rwp->rw_rwlock, RW_WRITER);
+       if (RWSEM_COUNT(SEM(&rwp->rw_rwlock)) !=
+           SPL_RWSEM_SINGLE_WRITER_VALUE) {
                splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME,
+                   "We assumed single writer rwsem->count "
+                   "should be %ld, but is %ld\n",
+                   (long int)SPL_RWSEM_SINGLE_WRITER_VALUE,
+                   (long int)RWSEM_COUNT(SEM(&rwp->rw_rwlock)));
+               rc = -ENOLCK;
+               goto out;
+       }
+       rc = 0;
+       splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME, "%s",
+                    "rwsem->count same as we assumed\n");
+out:
+       rw_exit(&rwp->rw_rwlock);
+       rw_destroy(&rwp->rw_rwlock);
+       kfree(rwp);
+
+       return rc;
+}
+
+static int
+splat_rwlock_test7(struct file *file, void *arg)
+{
+       rw_priv_t *rwp;
+       int rc;
+
+       rwp = (rw_priv_t *)kmalloc(sizeof(*rwp), GFP_KERNEL);
+       if (rwp == NULL)
+               return -ENOMEM;
+
+       splat_init_rw_priv(rwp, file);
+
+       rw_enter(&rwp->rw_rwlock, RW_READER);
+       if (!RW_READ_HELD(&rwp->rw_rwlock)) {
+               splat_vprint(file, SPLAT_RWLOCK_TEST7_NAME,
                             "rwlock should be read lock: %d\n",
                             RW_READ_HELD(&rwp->rw_rwlock));
                rc = -ENOLCK;
                goto out;
        }
 
-#if defined(CONFIG_RWSEM_GENERIC_SPINLOCK)
        /* With one reader upgrade should never fail. */
        rc = rw_tryupgrade(&rwp->rw_rwlock);
        if (!rc) {
-               splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME,
+               splat_vprint(file, SPLAT_RWLOCK_TEST7_NAME,
                             "rwlock failed upgrade from reader: %d\n",
                             RW_READ_HELD(&rwp->rw_rwlock));
                rc = -ENOLCK;
@@ -598,7 +651,7 @@ splat_rwlock_test6(struct file *file, void *arg)
        }
 
        if (RW_READ_HELD(&rwp->rw_rwlock) || !RW_WRITE_HELD(&rwp->rw_rwlock)) {
-               splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME, "rwlock should "
+               splat_vprint(file, SPLAT_RWLOCK_TEST7_NAME, "rwlock should "
                           "have 0 (not %d) reader and 1 (not %d) writer\n",
                           RW_READ_HELD(&rwp->rw_rwlock),
                           RW_WRITE_HELD(&rwp->rw_rwlock));
@@ -606,13 +659,8 @@ splat_rwlock_test6(struct file *file, void *arg)
        }
 
        rc = 0;
-       splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME, "%s",
+       splat_vprint(file, SPLAT_RWLOCK_TEST7_NAME, "%s",
                     "rwlock properly upgraded\n");
-#else
-       rc = 0;
-       splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME, "%s",
-                    "rw_tryupgrade() is disabled for this arch\n");
-#endif
 out:
        rw_exit(&rwp->rw_rwlock);
        rw_destroy(&rwp->rw_rwlock);
@@ -638,18 +686,20 @@ splat_rwlock_init(void)
        spin_lock_init(&sub->test_lock);
        sub->desc.id = SPLAT_SUBSYSTEM_RWLOCK;
 
-       SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST1_NAME, SPLAT_RWLOCK_TEST1_DESC,
+       splat_test_init(sub, SPLAT_RWLOCK_TEST1_NAME, SPLAT_RWLOCK_TEST1_DESC,
                      SPLAT_RWLOCK_TEST1_ID, splat_rwlock_test1);
-       SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST2_NAME, SPLAT_RWLOCK_TEST2_DESC,
+       splat_test_init(sub, SPLAT_RWLOCK_TEST2_NAME, SPLAT_RWLOCK_TEST2_DESC,
                      SPLAT_RWLOCK_TEST2_ID, splat_rwlock_test2);
-       SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST3_NAME, SPLAT_RWLOCK_TEST3_DESC,
+       splat_test_init(sub, SPLAT_RWLOCK_TEST3_NAME, SPLAT_RWLOCK_TEST3_DESC,
                      SPLAT_RWLOCK_TEST3_ID, splat_rwlock_test3);
-       SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST4_NAME, SPLAT_RWLOCK_TEST4_DESC,
+       splat_test_init(sub, SPLAT_RWLOCK_TEST4_NAME, SPLAT_RWLOCK_TEST4_DESC,
                      SPLAT_RWLOCK_TEST4_ID, splat_rwlock_test4);
-       SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST5_NAME, SPLAT_RWLOCK_TEST5_DESC,
+       splat_test_init(sub, SPLAT_RWLOCK_TEST5_NAME, SPLAT_RWLOCK_TEST5_DESC,
                      SPLAT_RWLOCK_TEST5_ID, splat_rwlock_test5);
-       SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST6_NAME, SPLAT_RWLOCK_TEST6_DESC,
+       splat_test_init(sub, SPLAT_RWLOCK_TEST6_NAME, SPLAT_RWLOCK_TEST6_DESC,
                      SPLAT_RWLOCK_TEST6_ID, splat_rwlock_test6);
+       splat_test_init(sub, SPLAT_RWLOCK_TEST7_NAME, SPLAT_RWLOCK_TEST7_DESC,
+                     SPLAT_RWLOCK_TEST7_ID, splat_rwlock_test7);
 
        return sub;
 }
@@ -658,12 +708,13 @@ void
 splat_rwlock_fini(splat_subsystem_t *sub)
 {
        ASSERT(sub);
-       SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST6_ID);
-       SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST5_ID);
-       SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST4_ID);
-       SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST3_ID);
-       SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST2_ID);
-       SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST1_ID);
+       splat_test_fini(sub, SPLAT_RWLOCK_TEST7_ID);
+       splat_test_fini(sub, SPLAT_RWLOCK_TEST6_ID);
+       splat_test_fini(sub, SPLAT_RWLOCK_TEST5_ID);
+       splat_test_fini(sub, SPLAT_RWLOCK_TEST4_ID);
+       splat_test_fini(sub, SPLAT_RWLOCK_TEST3_ID);
+       splat_test_fini(sub, SPLAT_RWLOCK_TEST2_ID);
+       splat_test_fini(sub, SPLAT_RWLOCK_TEST1_ID);
        kfree(sub);
 }