Whamcloud - gitweb
- James Newsome's dlm stress test
authorpschwan <pschwan>
Mon, 12 Aug 2002 21:57:43 +0000 (21:57 +0000)
committerpschwan <pschwan>
Mon, 12 Aug 2002 21:57:43 +0000 (21:57 +0000)
- Small warning fix in filter.c

lustre/include/linux/lustre_dlm.h
lustre/ldlm/ldlm_lockd.c
lustre/ldlm/ldlm_test.c
lustre/obdecho/echo.c
lustre/obdfilter/filter.c
lustre/osc/osc_request.c
lustre/tests/lldlm.sh
lustre/utils/lctl.c
lustre/utils/obd.c
lustre/utils/obdctl.h

index f8b4c21..22b6553 100644 (file)
@@ -287,7 +287,11 @@ void ldlm_reprocess_all(struct ldlm_resource *res);
 void ldlm_lock_dump(struct ldlm_lock *lock);
 
 /* ldlm_test.c */
-int ldlm_test(struct obd_device *device, struct ptlrpc_connection *conn);
+int ldlm_test(struct obd_device *device, struct lustre_handle *connh);
+int ldlm_regression_start(struct obd_device *obddev, 
+                struct lustre_handle *connh, int count);
+int ldlm_regression_stop(void);
+
 
 /* resource.c */
 struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 local);
@@ -358,6 +362,8 @@ int mds_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
 
 #define IOC_LDLM_TEST                   _IOWR('f', 40, long)
 #define IOC_LDLM_DUMP                   _IOWR('f', 41, long)
-#define IOC_LDLM_MAX_NR                 41
+#define IOC_LDLM_REGRESS_START          _IOWR('f', 42, long)
+#define IOC_LDLM_REGRESS_STOP           _IOWR('f', 43, long)
+#define IOC_LDLM_MAX_NR                 43
 
 #endif
index 0848a0f..457a420 100644 (file)
@@ -414,7 +414,7 @@ static int ldlm_iocontrol(long cmd, struct lustre_handle *conn, int len,
 
         switch (cmd) {
         case IOC_LDLM_TEST:
-                err = ldlm_test(obddev, connection);
+                err = ldlm_test(obddev, conn);
                 CERROR("-- done err %d\n", err);
                 GOTO(out, err);
         case IOC_LDLM_DUMP:
@@ -552,6 +552,8 @@ EXPORT_SYMBOL(ldlm_cli_cancel);
 EXPORT_SYMBOL(ldlm_match_or_enqueue);
 EXPORT_SYMBOL(ldlm_it2str);
 EXPORT_SYMBOL(ldlm_test);
+EXPORT_SYMBOL(ldlm_regression_start);
+EXPORT_SYMBOL(ldlm_regression_stop);
 EXPORT_SYMBOL(ldlm_lock_dump);
 EXPORT_SYMBOL(ldlm_namespace_new);
 EXPORT_SYMBOL(ldlm_namespace_free);
index c0c8f13..f2d9f13 100644 (file)
@@ -1,32 +1,87 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- * Copyright (C) 2002 Cluster File Systems, Inc.
+ * Copyright (c) 2002 Cluster File Systems, Inc. <info@clusterfs.com>
+ * Copyright (c) 2002 Lawrence Livermore National Laboratory
+ *  Author: James Newsome <newsome2@llnl.gov>
  *
- * This code is issued under the GNU General Public License.
- * See the file COPYING in this distribution
+ *   This file is part of Lustre, http://www.lustre.org.
  *
- * by Cluster File Systems, Inc.
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define DEBUG_SUBSYSTEM S_LDLM
 
+#include <asm/atomic.h>
 #include <linux/types.h>
 #include <linux/random.h>
 
 #include <linux/lustre_dlm.h>
 
 struct ldlm_test_thread {
+        struct lustre_handle *connh;
+        struct obd_device *obddev;
         struct ldlm_namespace *t_ns;
         struct list_head t_link;
-        __u32 t_flags; 
+        __u32 t_flags;
         wait_queue_head_t t_ctl_waitq;
 };
 
+struct ldlm_test_lock {
+        struct list_head l_link;
+        struct lustre_handle l_lockh;
+        ldlm_mode_t l_mode;
+};
+
+static const int max_locks = 10;
+
 static spinlock_t ctl_lock = SPIN_LOCK_UNLOCKED;
-static struct list_head ctl_threads;
+/* protect these with the ctl_lock */
+static LIST_HEAD(ctl_threads);
 static int regression_running = 0;
+static LIST_HEAD(lock_list);
+static int num_locks = 0;
+
+/* cumulative stats for regression test */
+static atomic_t locks_requested = ATOMIC_INIT(0);
+static atomic_t locks_granted = ATOMIC_INIT(0);
+static atomic_t locks_matched = ATOMIC_INIT(0);
+
+/*
+ * blocking ast for regression test.
+ * Just cancels lock
+ */
+static int ldlm_test_blocking_ast(struct ldlm_lock *lock,
+                                  struct ldlm_lock_desc *new,
+                                  void *data, __u32 data_len)
+{
+        int rc;
+        struct lustre_handle lockh;
+        ENTRY;
+
+        LDLM_DEBUG_NOLOCK("We're blocking. Cancelling lock");
+        ldlm_lock2handle(lock, &lockh);
+        rc = ldlm_cli_cancel(&lockh);
+        if (rc < 0) {
+                CERROR("ldlm_cli_cancel: %d\n", rc);
+                LBUG();
+        }
 
+        RETURN(0);
+}
+
+/* blocking ast for basic tests. noop */
 static int ldlm_blocking_ast(struct ldlm_lock *lock,
                              struct ldlm_lock_desc *new,
                              void *data, __u32 data_len)
@@ -36,6 +91,74 @@ static int ldlm_blocking_ast(struct ldlm_lock *lock,
         RETURN(0);
 }
 
+/* Completion ast for regression test.
+ * Does not sleep when blocked.
+ */
+static int ldlm_test_completion_ast(struct ldlm_lock *lock, int flags)
+{
+
+        ENTRY;
+
+        if (flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
+                      LDLM_FL_BLOCK_CONV)) {
+                /* Do nothing */
+                LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock");
+                ldlm_lock_dump(lock);
+        } else {
+                /* add to list of granted locks */
+                struct ldlm_test_lock *lock_info;
+
+                if (flags == LDLM_FL_WAIT_NOREPROC) {
+                        atomic_inc(&locks_matched);
+                        LDLM_DEBUG(lock, "lock matched");
+                } else if (flags == LDLM_FL_LOCK_CHANGED) {
+                        atomic_inc(&locks_granted);
+                        LDLM_DEBUG(lock, "lock changed and granted");
+                } else {
+                        atomic_inc(&locks_granted);
+                        LDLM_DEBUG(lock, "lock granted");
+                }
+
+                OBD_ALLOC(lock_info, sizeof(*lock_info));
+                if (lock_info == NULL) {
+                        LBUG();
+                        RETURN(-ENOMEM);
+                }
+
+                ldlm_lock2handle(lock, &lock_info->l_lockh);
+                lock_info->l_mode = lock->l_granted_mode;
+
+                spin_lock(&ctl_lock);
+                list_add_tail(&lock_info->l_link, &lock_list);
+                num_locks++;
+
+                /* if we're over the max of granted locks, decref some */
+                if (num_locks > max_locks) {
+                        /* delete from list */
+                        lock_info = list_entry(lock_list.next,
+                                               struct ldlm_test_lock, l_link);
+                        list_del(lock_list.next);
+                        num_locks--;
+                        spin_unlock(&ctl_lock);
+
+                        /* decrement and free the info
+                         * Don't hold ctl_lock here. The decref
+                         * may result in another lock being granted
+                         * and hence this function being called again.
+                         */
+                        LDLM_DEBUG_NOLOCK("Decrementing lock");
+                        ldlm_lock_decref(&lock_info->l_lockh,
+                                         lock_info->l_mode);
+                        OBD_FREE(lock_info, sizeof(*lock_info));
+
+                        spin_lock(&ctl_lock);
+                }
+                spin_unlock(&ctl_lock);
+        }
+
+        RETURN(0);
+}
+
 int ldlm_test_basics(struct obd_device *obddev)
 {
         struct ldlm_namespace *ns;
@@ -150,7 +273,7 @@ int ldlm_test_extents(struct obd_device *obddev)
 }
 
 static int ldlm_test_network(struct obd_device *obddev,
-                             struct ptlrpc_connection *conn)
+                             struct lustre_handle *connh)
 {
 
         __u64 res_id[RES_NAME_SIZE] = {1, 2, 3};
@@ -159,14 +282,18 @@ static int ldlm_test_network(struct obd_device *obddev,
         int flags = 0;
         ldlm_error_t err;
 
-        /* FIXME: this needs a connh as 3rd paramter, before it will work */
-
-        err = ldlm_cli_enqueue(NULL, NULL, obddev->obd_namespace, NULL, res_id,
+        err = ldlm_cli_enqueue(connh, NULL, obddev->obd_namespace, NULL, res_id,
                                LDLM_EXTENT, &ext, sizeof(ext), LCK_PR, &flags,
-                               NULL, NULL, NULL, 0, &lockh1);
+                               ldlm_completion_ast, NULL, NULL, 0, &lockh1);
+
         CERROR("ldlm_cli_enqueue: %d\n", err);
+
+        flags = 0;
+        err = ldlm_cli_convert(&lockh1, LCK_EX, &flags);
+        CERROR("ldlm_cli_convert: %d\n", err);
+
         if (err == ELDLM_OK)
-                ldlm_lock_decref(&lockh1, LCK_PR);
+                ldlm_lock_decref(&lockh1, LCK_EX);
 
         RETURN(err);
 }
@@ -174,7 +301,8 @@ static int ldlm_test_network(struct obd_device *obddev,
 static int ldlm_test_main(void *data)
 {
         struct ldlm_test_thread *thread = data;
-        struct ldlm_namespace *ns;
+        const unsigned int num_resources = 10;
+        const unsigned int num_extent = 10;
         ENTRY;
 
         lock_kernel();
@@ -186,49 +314,71 @@ static int ldlm_test_main(void *data)
 
         sprintf(current->comm, "ldlm_test");
 
-        ns = ldlm_namespace_new("ldlm_test", LDLM_NAMESPACE_CLIENT);
-        if (ns == NULL) {
-                LBUG();
-                GOTO(out, -ENOMEM);
-        }
-
         /* Record that the thread is running */
         thread->t_flags |= SVC_RUNNING;
         wake_up(&thread->t_ctl_waitq);
 
-        while (1) {
+        while (!(thread->t_flags & SVC_STOPPING)) {
                 struct lustre_handle lockh;
                 __u64 res_id[3] = {0};
                 __u32 lock_mode;
+                struct ldlm_extent ext;
                 char random;
-                int flags = 0, rc;
+                int flags = 0, rc = 0;
 
-                /* Pick a random resource from 1 to 10 */
+                /* Pick a random resource from 1 to num_resources */
                 get_random_bytes(&random, sizeof(random));
-                res_id[0] = random % 10 + 1;
+                res_id[0] = (unsigned char)random % num_resources;
 
                 /* Pick a random lock mode */
                 get_random_bytes(&random, sizeof(random));
-                lock_mode = random % LCK_NL + 1;
+                lock_mode = (unsigned char)random % LCK_NL + 1;
 
-                rc = ldlm_cli_enqueue(NULL, NULL, ns, NULL,
-                                      res_id, LDLM_PLAIN, NULL, 0, lock_mode,
-                                      &flags, ldlm_completion_ast,
-                                      ldlm_blocking_ast, NULL, 0, &lockh);
+                /* Pick a random extent */
+                get_random_bytes(&random, sizeof(random));
+                ext.start = (unsigned int)random % num_extent;
+                get_random_bytes(&random, sizeof(random));
+                ext.end = (unsigned int)random %
+                        (num_extent - (int)ext.start) + ext.start;
+
+                LDLM_DEBUG_NOLOCK("about to enqueue with resource %d, mode %d,"
+                                  " extent %d -> %d", (int)res_id[0], lock_mode,
+                                  (int)ext.start, (int)ext.end);
+
+                rc = ldlm_match_or_enqueue(thread->connh, NULL,
+                                           thread->obddev->obd_namespace, NULL,
+                                           res_id, LDLM_EXTENT, &ext,
+                                           sizeof(ext), lock_mode, &flags,
+                                           ldlm_test_completion_ast,
+                                           ldlm_test_blocking_ast, NULL, 0,
+                                           &lockh);
+
+                atomic_inc(&locks_requested);
                 if (rc < 0) {
                         CERROR("ldlm_cli_enqueue: %d\n", rc);
                         LBUG();
                 }
+
+                LDLM_DEBUG_NOLOCK("locks requested: %d, granted: %d, "
+                                  "matched: %d",
+                                  atomic_read(&locks_requested),
+                                  atomic_read(&locks_granted),
+                                  atomic_read(&locks_matched));
+
+                /* I think this may be necessary since we don't sleep
+                 * after a lock being blocked
+                 */
+                schedule();
         }
 
- out:
         thread->t_flags |= SVC_STOPPED;
         wake_up(&thread->t_ctl_waitq);
 
         RETURN(0);
 }
 
-static int ldlm_start_thread(void)
+static int ldlm_start_thread(struct obd_device *obddev,
+                             struct lustre_handle *connh)
 {
         struct ldlm_test_thread *test;
         int rc;
@@ -241,6 +391,9 @@ static int ldlm_start_thread(void)
         }
         init_waitqueue_head(&test->t_ctl_waitq);
 
+        test->connh = connh;
+        test->obddev = obddev;
+
         spin_lock(&ctl_lock);
         list_add(&test->t_link, &ctl_threads);
         spin_unlock(&ctl_lock);
@@ -257,7 +410,7 @@ static int ldlm_start_thread(void)
 }
 
 int ldlm_regression_start(struct obd_device *obddev,
-                          struct ptlrpc_connection *conn, int count)
+                          struct lustre_handle *connh, int count)
 {
         int i, rc = 0;
         ENTRY;
@@ -272,7 +425,7 @@ int ldlm_regression_start(struct obd_device *obddev,
         spin_unlock(&ctl_lock);
 
         for (i = 0; i < count; i++) {
-                rc = ldlm_start_thread();
+                rc = ldlm_start_thread(obddev, connh);
                 if (rc < 0)
                         GOTO(cleanup, rc);
         }
@@ -314,17 +467,18 @@ int ldlm_regression_stop(void)
         RETURN(0);
 }
 
-int ldlm_test(struct obd_device *obddev, struct ptlrpc_connection *conn)
+int ldlm_test(struct obd_device *obddev, struct lustre_handle *connh)
 {
         int rc;
-        rc = ldlm_test_basics(obddev);
+/*        rc = ldlm_test_basics(obddev);
         if (rc)
                 RETURN(rc);
 
         rc = ldlm_test_extents(obddev);
         if (rc)
                 RETURN(rc);
+*/
 
-        rc = ldlm_test_network(obddev, conn);
+        rc = ldlm_test_network(obddev, connh);
         RETURN(rc);
 }
index 79e30d7..efd5d8b 100644 (file)
@@ -11,8 +11,8 @@
  * by Peter Braam <braam@clusterfs.com>
  */
 
-static char rcsid[] __attribute ((unused)) = "$Id: echo.c,v 1.20 2002/08/07 21:46:32 shaver Exp $";
-#define OBDECHO_VERSION "$Revision: 1.20 $"
+static char rcsid[] __attribute ((unused)) = "$Id: echo.c,v 1.21 2002/08/12 21:57:42 pschwan Exp $";
+#define OBDECHO_VERSION "$Revision: 1.21 $"
 
 #define EXPORT_SYMTAB
 
@@ -32,6 +32,7 @@ static char rcsid[] __attribute ((unused)) = "$Id: echo.c,v 1.20 2002/08/07 21:4
 #include <linux/obd_support.h>
 #include <linux/obd_class.h>
 #include <linux/obd_echo.h>
+#include <linux/lustre_dlm.h>
 
 extern struct obd_device obd_dev[MAX_OBD_DEVICES];
 static struct obdo OA;
@@ -242,12 +243,26 @@ commitrw_cleanup:
         return rc;
 }
 
+static int echo_setup(struct obd_device *obddev, obd_count len, void *buf)
+{
+        ENTRY;
+
+        obddev->obd_namespace =
+                ldlm_namespace_new("echo-tgt", LDLM_NAMESPACE_SERVER);
+        if (obddev->obd_namespace == NULL)
+                LBUG();
+
+        RETURN(0);
+}
+
+
 struct obd_ops echo_obd_ops = {
         o_connect:     echo_connect,
         o_disconnect:  echo_disconnect,
         o_getattr:     echo_getattr,
         o_preprw:      echo_preprw,
         o_commitrw:    echo_commitrw,
+        o_setup:       echo_setup
 };
 
 static int __init obdecho_init(void)
index f5e13b2..da49f47 100644 (file)
@@ -724,9 +724,9 @@ static int filter_truncate(struct lustre_handle *conn, struct obdo *oa,
 }
 
 static int filter_pgcache_brw(int cmd, struct lustre_handle *conn, 
-                               struct lov_stripe_md *md, obd_count oa_bufs,
-                               struct brw_page *pga,
-                               brw_callback_t callback, void *data)
+                              struct lov_stripe_md *md, obd_count oa_bufs,
+                              struct brw_page *pga, brw_callback_t callback,
+                              struct io_cb_data *data)
 {
         struct obd_run_ctxt      saved;
         struct super_block      *sb;
index 8cb4050..58500f6 100644 (file)
@@ -693,6 +693,51 @@ static int osc_statfs(struct lustre_handle *conn, struct statfs *sfs)
         return rc;
 }
 
+static int osc_iocontrol(long cmd, struct lustre_handle *conn, int len,
+                         void *karg, void *uarg)
+{
+        struct obd_device *obddev = class_conn2obd(conn);
+        struct obd_ioctl_data *data = karg;
+        int err = 0;
+        ENTRY;
+
+        if (_IOC_TYPE(cmd) != IOC_LDLM_TYPE || _IOC_NR(cmd) < 
+                        IOC_LDLM_MIN_NR || _IOC_NR(cmd) > IOC_LDLM_MAX_NR) {
+                CDEBUG(D_IOCTL, "invalid ioctl (type %ld, nr %ld, size %ld)\n",
+                        _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
+                RETURN(-EINVAL);
+        }
+
+        switch (cmd) {
+        case IOC_LDLM_TEST: {
+                err = ldlm_test(obddev, conn);
+                CERROR("-- done err %d\n", err);
+                GOTO(out, err);
+        }
+        case IOC_LDLM_REGRESS_START: {
+                unsigned int numthreads; 
+                
+                if (data->ioc_inllen1) 
+                        numthreads = simple_strtoul(data->ioc_inlbuf1, NULL, 0);
+                else 
+                        numthreads = 1;
+
+                err = ldlm_regression_start(obddev, conn, numthreads);
+                CERROR("-- done err %d\n", err);
+                GOTO(out, err);
+        }
+        case IOC_LDLM_REGRESS_STOP: {
+                err = ldlm_regression_stop();
+                CERROR("-- done err %d\n", err);
+                GOTO(out, err);
+        }
+        default:
+                GOTO(out, err = -EINVAL);
+        }
+out:
+        return err;
+}
+
 struct obd_ops osc_obd_ops = {
         o_setup:        client_obd_setup,
         o_cleanup:      client_obd_cleanup,
@@ -708,7 +753,8 @@ struct obd_ops osc_obd_ops = {
         o_brw:          osc_brw,
         o_punch:        osc_punch,
         o_enqueue:      osc_enqueue,
-        o_cancel:       osc_cancel
+        o_cancel:       osc_cancel,
+        o_iocontrol:    osc_iocontrol
 };
 
 static int __init osc_init(void)
index 6c575e1..3aac610 100755 (executable)
@@ -4,10 +4,24 @@ SRCDIR="`dirname $0`/"
 . $SRCDIR/common.sh
 
 export DEBUG_WAIT=yes
-. $SRCDIR/llsetup.sh $SRCDIR/net-local.cfg $SRCDIR/ldlm.cfg || exit 2
+. $SRCDIR/llsetup.sh $SRCDIR/net-local.cfg $SRCDIR/ldlm.cfg $SRCDIR/obdecho.cfg $SRCDIR/client-echo.cfg || exit 2
 
-$OBDCTL <<EOF
-name2dev LDLMDEV
+cat <<EOF
+**********************************************
+To run tests, use $OBDCTL.
+$OBDCTL
+device `$OBDCTL name2dev OSCDEV`
+probe
+
+To test basic locking functionality:
 test_ldlm
-quit
+
+The regression stress test will start some
+number of threads, each locking and unlocking
+extents from a set of resources. To run it:
+ldlm_regress_start [numthreads]
+
+And to stop it:
+ldlm_regress_stop
+**********************************************
 EOF
index 9bf5eaa..717ac5d 100644 (file)
@@ -133,6 +133,11 @@ command_t cmdlist[] = {
          "usage: test_brw <count> [write [verbose [pages [obdos]]]]"},
         {"test_ldlm", jt_obd_test_ldlm, 0, "perform lock manager test\n"
          "usage: test_ldlm"},
+        {"ldlm_regress_start", jt_obd_ldlm_regress_start, 0,
+         "start lock manager stress test (usage: ldlm_regress_start "
+         "[numthreads])\n"},
+        {"ldlm_regress_stop", jt_obd_ldlm_regress_stop, 0,
+         "stop lock manager stress test (no args)\n"},
         {"dump_ldlm", jt_obd_dump_ldlm, 0,
          "dump all lock manager state (no args)"},
 
index c63d950..7c628d3 100644 (file)
@@ -1170,6 +1170,56 @@ int jt_obd_dump_ldlm(int argc, char **argv)
         return rc;
 }
 
+int jt_obd_ldlm_regress_start(int argc, char **argv)
+{
+        int rc;
+        struct obd_ioctl_data data;
+
+        IOCINIT(data);
+
+        if (argc > 2) {
+                fprintf(stderr, "usage: %s [numthreads]\n", cmdname(argv[0]));
+                return 1;
+        } else if (argc == 2) {
+                data.ioc_inllen1 =  strlen(argv[1]) + 1;
+                data.ioc_inlbuf1 = argv[1];
+        } else {
+                data.ioc_inllen1 = 0;
+        }
+
+        if (obd_ioctl_pack(&data, &buf, max)) {
+                fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
+                return -2;
+        }
+
+        rc = ioctl(fd, IOC_LDLM_REGRESS_START, buf);
+
+        if (rc)
+                fprintf(stderr, "error: %s: test failed: %s\n",
+                        cmdname(argv[0]), strerror(rc = errno));
+
+        return rc;
+}
+
+int jt_obd_ldlm_regress_stop(int argc, char **argv)
+{
+        int rc;
+        struct obd_ioctl_data data;
+        IOCINIT(data);
+
+        if (argc != 1) {
+                fprintf(stderr, "usage: %s\n", cmdname(argv[0]));
+                return 1;
+        }
+
+        rc = ioctl(fd, IOC_LDLM_REGRESS_STOP, &data);
+
+        if (rc)
+                fprintf(stderr, "error: %s: test failed: %s\n",
+                        cmdname(argv[0]), strerror(rc = errno));
+        return rc;
+}
+
 int jt_obd_newconn(int argc, char **argv)
 {
         int rc;
index c075261..eb907b9 100644 (file)
@@ -51,6 +51,8 @@ int jt_obd_test_getattr(int argc, char **argv);
 int jt_obd_test_brw(int argc, char **argv);
 int jt_obd_lov_config(int argc, char **argv);
 int jt_obd_test_ldlm(int argc, char **argv);
+int jt_obd_ldlm_regress_start(int argc, char **argv);
+int jt_obd_ldlm_regress_stop(int argc, char **argv);
 int jt_obd_dump_ldlm(int argc, char **argv);
 int jt_obd_newconn(int argc, char **argv);