lib/test_lockup.c: add parameters for locking generic vfs locks
[linux-block.git] / lib / test_lockup.c
index 83683ec1f4295997c49d84d5e3c64cfd8f6bd0ec..ea09ca335b21451f964cc9f96ed35e15f46bc550 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/nmi.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
+#include <linux/file.h>
 
 static unsigned int time_secs;
 module_param(time_secs, uint, 0600);
@@ -140,6 +141,24 @@ static bool reallocate_pages;
 module_param(reallocate_pages, bool, 0400);
 MODULE_PARM_DESC(reallocate_pages, "free and allocate pages between iterations");
 
+struct file *test_file;
+struct inode *test_inode;
+static char test_file_path[256];
+module_param_string(file_path, test_file_path, sizeof(test_file_path), 0400);
+MODULE_PARM_DESC(file_path, "file path to test");
+
+static bool test_lock_inode;
+module_param_named(lock_inode, test_lock_inode, bool, 0400);
+MODULE_PARM_DESC(lock_inode, "lock file -> inode -> i_rwsem");
+
+static bool test_lock_mapping;
+module_param_named(lock_mapping, test_lock_mapping, bool, 0400);
+MODULE_PARM_DESC(lock_mapping, "lock file -> mapping -> i_mmap_rwsem");
+
+static bool test_lock_sb_umount;
+module_param_named(lock_sb_umount, test_lock_sb_umount, bool, 0400);
+MODULE_PARM_DESC(lock_sb_umount, "lock file -> sb -> s_umount");
+
 static atomic_t alloc_pages_failed = ATOMIC_INIT(0);
 
 static atomic64_t max_lock_wait = ATOMIC64_INIT(0);
@@ -490,6 +509,29 @@ static int __init test_lockup_init(void)
                return -EINVAL;
        }
 
+       if (test_file_path[0]) {
+               test_file = filp_open(test_file_path, O_RDONLY, 0);
+               if (IS_ERR(test_file)) {
+                       pr_err("cannot find file_path\n");
+                       return -EINVAL;
+               }
+               test_inode = file_inode(test_file);
+       } else if (test_lock_inode ||
+                  test_lock_mapping ||
+                  test_lock_sb_umount) {
+               pr_err("no file to lock\n");
+               return -EINVAL;
+       }
+
+       if (test_lock_inode && test_inode)
+               lock_rwsem_ptr = (unsigned long)&test_inode->i_rwsem;
+
+       if (test_lock_mapping && test_file && test_file->f_mapping)
+               lock_rwsem_ptr = (unsigned long)&test_file->f_mapping->i_mmap_rwsem;
+
+       if (test_lock_sb_umount && test_inode)
+               lock_rwsem_ptr = (unsigned long)&test_inode->i_sb->s_umount;
+
        pr_notice("START pid=%d time=%u +%u ns cooldown=%u +%u ns iterations=%u state=%s %s%s%s%s%s%s%s%s%s%s%s\n",
                  main_task->pid, time_secs, time_nsecs,
                  cooldown_secs, cooldown_nsecs, iterations, state,
@@ -542,6 +584,9 @@ static int __init test_lockup_init(void)
 
        pr_notice("FINISH in %llu ns\n", local_clock() - test_start);
 
+       if (test_file)
+               fput(test_file);
+
        if (signal_pending(main_task))
                return -EINTR;