Whamcloud - gitweb
the first try at lock LRU
authorpschwan <pschwan>
Sat, 9 Nov 2002 19:40:59 +0000 (19:40 +0000)
committerpschwan <pschwan>
Sat, 9 Nov 2002 19:40:59 +0000 (19:40 +0000)
lustre/ChangeLog
lustre/include/linux/lustre_dlm.h
lustre/ldlm/ldlm_lock.c
lustre/ldlm/ldlm_request.c
lustre/ldlm/ldlm_resource.c
lustre/tests/ba-mount.sh [new file with mode: 0644]
lustre/tests/runtests

index ad23c1d..ac05e5c 100644 (file)
@@ -1,6 +1,9 @@
 TBD
        * version TBD
        * bug fixes
+         - fix null d_it dereference (346)
+         - fix full OST/dbench hang (333)
+         - fix permission problem with file removal (286)
          - fix removal of OSCs from LOV when they fail
          - fix NULL deref during bulk timeout (214)
          - fix problems related to multiple filesystems on one MDS (241)
@@ -12,6 +15,7 @@ TBD
          - data locks weren't cancelled at clear_inode time (290, 311)
          - intent locks could lead to unbounded lock growth (205)
        * protocol change
+          - Add capability to MDS protocol
          - LDLM cancellations and callbacks on different portals
 
 2002-10-28  Andreas Dilger  <adilger@clusterfs.com>
index b60032c..cc2c268 100644 (file)
@@ -44,6 +44,7 @@ typedef enum {
 #define LDLM_FL_LOCAL_ONLY     (1 << 11) /* see ldlm_cli_cancel_unused */
 #define LDLM_FL_NO_CALLBACK    (1 << 12) /* see ldlm_cli_cancel_unused */
 #define LDLM_FL_HAS_INTENT     (1 << 13) /* lock request has intent */
+#define LDLM_FL_REDUCE         (1 << 14) /* throw away unused locks */
 
 #define LDLM_CB_BLOCKING    1
 #define LDLM_CB_CANCELING   2
@@ -102,6 +103,10 @@ struct ldlm_namespace {
         struct list_head       ns_list_chain; /* position in global NS list */
         struct proc_dir_entry *ns_proc_dir;
 
+        struct list_head       ns_unused_list; /* all root resources in ns */
+        unsigned int           ns_nr_unused;
+        unsigned int           ns_max_unused;
+
         spinlock_t             ns_counter_lock;
         __u64                  ns_locks;
         __u64                  ns_resources;
@@ -132,6 +137,7 @@ struct ldlm_lock {
         struct ldlm_lock     *l_parent;
         struct list_head      l_children;
         struct list_head      l_childof;
+        struct list_head      l_lru;
         struct list_head      l_res_link; /*position in one of three res lists*/
         struct list_head      l_export_chain; /* per-export chain of locks */
         struct list_head      l_pending_chain; /* locks with callbacks pending*/
index 5798d6e..6ac4a4a 100644 (file)
@@ -215,6 +215,7 @@ void ldlm_lock_destroy(struct ldlm_lock *lock)
                 return;
         }
 
+        list_del_init(&lock->l_lru);
         list_del(&lock->l_export_chain);
         lock->l_export = NULL;
         lock->l_flags |= LDLM_FL_DESTROYED;
@@ -258,6 +259,7 @@ static struct ldlm_lock *ldlm_lock_new(struct ldlm_lock *parent,
         lock->l_refc = 1;
         INIT_LIST_HEAD(&lock->l_children);
         INIT_LIST_HEAD(&lock->l_res_link);
+        INIT_LIST_HEAD(&lock->l_lru);
         INIT_LIST_HEAD(&lock->l_export_chain);
         INIT_LIST_HEAD(&lock->l_pending_chain);
         init_waitqueue_head(&lock->l_waitq);
@@ -435,6 +437,13 @@ void ldlm_lock_addref(struct lustre_handle *lockh, __u32 mode)
 void ldlm_lock_addref_internal(struct ldlm_lock *lock, __u32 mode)
 {
         l_lock(&lock->l_resource->lr_namespace->ns_lock);
+
+        if (!list_empty(&lock->l_lru)) { 
+                list_del_init(&lock->l_lru);
+                lock->l_resource->lr_namespace->ns_nr_unused--;
+                LASSERT(lock->l_resource->lr_namespace->ns_nr_unused >= 0);
+        }
+
         if (mode == LCK_NL || mode == LCK_CR || mode == LCK_PR)
                 lock->l_readers++;
         else
@@ -445,15 +454,20 @@ void ldlm_lock_addref_internal(struct ldlm_lock *lock, __u32 mode)
 }
 
 /* Args: unlocked lock */
+int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns,
+                                    __u64 *res_id, int flags);
+
 void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode)
 {
         struct ldlm_lock *lock = __ldlm_handle2lock(lockh, 0);
+        struct ldlm_namespace *ns;
         ENTRY;
 
         if (lock == NULL)
                 LBUG();
 
         LDLM_DEBUG(lock, "ldlm_lock_decref(%s)", ldlm_lockname[mode]);
+        ns = lock->l_resource->lr_namespace;
         l_lock(&lock->l_resource->lr_namespace->ns_lock);
         if (mode == LCK_NL || mode == LCK_CR || mode == LCK_PR)
                 lock->l_readers--;
@@ -475,6 +489,18 @@ void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode)
                 /* FIXME: need a real 'desc' here */
                 lock->l_blocking_ast(lock, NULL, lock->l_data,
                                      lock->l_data_len, LDLM_CB_BLOCKING);
+        } else if (!lock->l_readers && !lock->l_writers) {
+                LASSERT(list_empty(&lock->l_lru));
+                LASSERT(ns->ns_nr_unused >= 0);
+                list_add_tail(&lock->l_lru, &ns->ns_unused_list);
+                ns->ns_nr_unused++;
+                if (ns->ns_client && ns->ns_nr_unused >= ns->ns_max_unused) {
+                        CDEBUG(D_DLMTRACE, "%d unused (max %d), cancelling "
+                               "LRU\n", ns->ns_nr_unused, ns->ns_max_unused);
+                        ldlm_cli_cancel_unused_resource
+                                (ns, lock->l_resource->lr_name, LDLM_FL_REDUCE);
+                }
+                l_unlock(&lock->l_resource->lr_namespace->ns_lock);
         } else
                 l_unlock(&lock->l_resource->lr_namespace->ns_lock);
 
index c4089bf..7aa9694 100644 (file)
@@ -492,14 +492,18 @@ int ldlm_cli_cancel(struct lustre_handle *lockh)
         return rc;
 }
 
-static int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns,
-                                           __u64 *res_id, int flags)
+int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns,
+                                    __u64 *res_id, int flags)
 {
         struct ldlm_resource *res;
         struct list_head *tmp, *next, list = LIST_HEAD_INIT(list);
         struct ldlm_ast_work *w;
         ENTRY;
 
+        if ((flags & LDLM_FL_REDUCE) && 
+            ns->ns_max_unused > ns->ns_nr_unused)
+                RETURN(0);
+
         res = ldlm_resource_get(ns, NULL, res_id, 0, 0);
         if (res == NULL) {
                 /* This is not a problem. */
@@ -522,11 +526,14 @@ static int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns,
                  * won't see this flag and call l_blocking_ast */
                 lock->l_flags |= LDLM_FL_CBPENDING;
 
-                OBD_ALLOC(w, sizeof(*w));
+                 OBD_ALLOC(w, sizeof(*w));
                 LASSERT(w);
 
                 w->w_lock = LDLM_LOCK_GET(lock);
                 list_add(&w->w_list, &list);
+                if ((flags & LDLM_FL_REDUCE) && 
+                    ns->ns_max_unused > ns->ns_nr_unused)
+                        break;
         }
         l_unlock(&ns->ns_lock);
 
index 8b850df..494b74e 100644 (file)
@@ -52,6 +52,7 @@ static int ldlm_proc_ll_rd(char *page, char **start, off_t off,
         return len;
 }
 
+#define LDLM_MAX_UNUSED 20
 struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 client)
 {
         struct ldlm_namespace *ns = NULL;
@@ -90,6 +91,10 @@ struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 client)
              bucket--)
                 INIT_LIST_HEAD(bucket);
 
+        INIT_LIST_HEAD(&ns->ns_unused_list);
+        ns->ns_nr_unused = 0;
+        ns->ns_max_unused = LDLM_MAX_UNUSED;
+
         spin_lock(&ldlm_namespace_lock);
         list_add(&ns->ns_list_chain, &ldlm_namespace_list);
         spin_unlock(&ldlm_namespace_lock);
diff --git a/lustre/tests/ba-mount.sh b/lustre/tests/ba-mount.sh
new file mode 100644 (file)
index 0000000..fe0a8e2
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+# There are configurations for three machines in this config file: the OST,
+# the MDS/client, other clients
+#
+# To start your cluster using the ba-mount.xml file that this produces, first
+# run:
+# > lconf ba-mount.xml
+# on the MDS/client, and then run:
+# > lconf --node client ba-mount.xml
+# on any other clients.
+
+config=${1:-ba-mount.xml}
+
+LMC="save_cmd"
+LMC_REAL="../../lustre/utils/lmc -m $config"
+
+PORT=2432
+TCPBUF=1048576
+OST=ba-ost-1
+MDS=mds-hostname
+UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt}
+
+h2ip () {
+    echo "${1}"
+}
+BATCH=/tmp/lmc-batch.$$
+save_cmd() {
+    echo "$@" >> $BATCH
+}
+
+[ -f $config ] && rm $config
+
+# MDS/client node
+${LMC} --node $MDS --tcpbuf $TCPBUF --net '*' tcp $PORT
+${LMC} --node $MDS --mds mds1 /tmp/mds1 50000
+
+OBD_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST`
+[ "$OBD_UUID" ] && OBD_UUID="--obduuid=$OBD_UUID" || echo "$OST: no UUID"
+
+# server node
+${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp $PORT
+${LMC} --node $OST $OBD_UUID --ost bluearc
+
+# mount point on the MDS/client
+${LMC} --node $MDS --mtpt /mnt/lustre mds1 OSC_$OST
+
+# other clients
+${LMC} --node client --tcpbuf $TCPBUF --net '*' tcp $PORT
+${LMC} --node client --mtpt /mnt/lustre mds1 OSC_$OST
+
+$LMC_REAL --batch $BATCH
+rm -f $BATCH
index 5c80ea5..28288aa 100755 (executable)
@@ -89,6 +89,8 @@ done
 [ "$ERROR" ] && fail "old and new files are different" $ERROR
 
 cleanup || exit 19
+sync
+
 $LCONF $OPTS || exit 20
 
 echo "comparing previously copied files"
@@ -100,6 +102,7 @@ done
 [ "$ERROR" ] && fail "old and new files are different on second diff" $ERROR
 
 cleanup || exit 29
+sync
 $LCONF $OPTS || exit 30
 
 echo "renaming $HOSTS.ren to $HOSTS"
@@ -118,3 +121,4 @@ if [ $NOWUSED -gt $USED ]; then
 fi
 
 cleanup $OPTS || exit 29
+sync