Whamcloud - gitweb
LU-2332 osc: solve a race in client obd list lock
[fs/lustre-release.git] / lustre / include / linux / obd.h
index fccfd1d..0be9fa1 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 # include <linux/fs.h>
 # include <linux/list.h>
 # include <linux/sched.h>  /* for struct task_struct, for current.h */
-# include <asm/current.h>  /* for smp_lock.h */
-# include <linux/smp_lock.h>
 # include <linux/proc_fs.h>
 # include <linux/mount.h>
-# ifndef HAVE_VFS_INTENT_PATCHES
-#  include <linux/lustre_intent.h>
-# endif
+# include <linux/lustre_intent.h>
+#endif
+
+struct ll_iattr {
+       struct iattr    iattr;
+       unsigned int    ia_attr_flags;
+};
+
+#ifdef __KERNEL__
+#define CLIENT_OBD_LIST_LOCK_DEBUG 1
 #endif
 
 typedef struct {
-        spinlock_t          lock;
+       spinlock_t              lock;
 
 #ifdef CLIENT_OBD_LIST_LOCK_DEBUG
-        unsigned long       time;
-        struct task_struct *task;
-        const char         *func;
-        int                 line;
+       unsigned long       time;
+       struct task_struct *task;
+       const char         *func;
+       int                 line;
 #endif
-
 } client_obd_lock_t;
 
 #ifdef CLIENT_OBD_LIST_LOCK_DEBUG
 static inline void __client_obd_list_lock(client_obd_lock_t *lock,
-                                          const char *func,
-                                          int line)
+                                          const char *func, int line)
 {
-        unsigned long cur = jiffies;
-        while (1) {
-                if (spin_trylock(&lock->lock)) {
+       unsigned long cur = jiffies;
+       while (1) {
+               if (spin_trylock(&lock->lock)) {
                         LASSERT(lock->task == NULL);
                         lock->task = current;
                         lock->func = func;
@@ -84,22 +87,28 @@ static inline void __client_obd_list_lock(client_obd_lock_t *lock,
                         break;
                 }
 
-                if ((jiffies - cur > 5 * HZ) &&
-                    (jiffies - lock->time > 5 * HZ)) {
-                        LCONSOLE_WARN("LOCK UP! the lock %p was acquired"
-                                      " by <%s:%d:%s:%d> %lu time, I'm %s:%d\n",
-                                      lock, lock->task->comm, lock->task->pid,
+                if ((jiffies - cur > 5 * CFS_HZ) &&
+                    (jiffies - lock->time > 5 * CFS_HZ)) {
+                       struct task_struct *task = lock->task;
+
+                       if (task == NULL)
+                               continue;
+
+                        LCONSOLE_WARN("%s:%d: lock %p was acquired"
+                                      " by <%s:%d:%s:%d> for %lu seconds.\n",
+                                     current->comm, current->pid,
+                                      lock, task->comm, task->pid,
                                       lock->func, lock->line,
-                                      (jiffies - lock->time),
-                                      current->comm, current->pid);
+                                      (jiffies - lock->time) / CFS_HZ);
                         LCONSOLE_WARN("====== for process holding the "
                                       "lock =====\n");
-                        libcfs_debug_dumpstack(lock->task);
+                        libcfs_debug_dumpstack(task);
                         LCONSOLE_WARN("====== for current process =====\n");
                         libcfs_debug_dumpstack(NULL);
                         LCONSOLE_WARN("====== end =======\n");
-                        cfs_pause(1000HZ);
+                        cfs_pause(1000 * CFS_HZ);
                 }
+               cpu_relax();
         }
 }
 
@@ -108,13 +117,13 @@ static inline void __client_obd_list_lock(client_obd_lock_t *lock,
 
 static inline void client_obd_list_unlock(client_obd_lock_t *lock)
 {
-        LASSERT(lock->task != NULL);
-        lock->task = NULL;
-        lock->time = jiffies;
-        spin_unlock(&lock->lock);
+       LASSERT(lock->task != NULL);
+       lock->task = NULL;
+       lock->time = jiffies;
+       spin_unlock(&lock->lock);
 }
 
-#else /* ifdef CLIEBT_OBD_LIST_LOCK_DEBUG */
+#else /* ifdef CLIENT_OBD_LIST_LOCK_DEBUG */
 static inline void client_obd_list_lock(client_obd_lock_t *lock)
 {
        spin_lock(&lock->lock);
@@ -122,25 +131,19 @@ static inline void client_obd_list_lock(client_obd_lock_t *lock)
 
 static inline void client_obd_list_unlock(client_obd_lock_t *lock)
 {
-        spin_unlock(&lock->lock);
+       spin_unlock(&lock->lock);
 }
 
-#endif /* ifdef CLIEBT_OBD_LIST_LOCK_DEBUG */
+#endif /* ifdef CLIENT_OBD_LIST_LOCK_DEBUG */
 
 static inline void client_obd_list_lock_init(client_obd_lock_t *lock)
 {
-        spin_lock_init(&lock->lock);
+       spin_lock_init(&lock->lock);
 }
 
 static inline void client_obd_list_lock_done(client_obd_lock_t *lock)
 {}
 
-
-static inline int client_obd_list_is_locked(client_obd_lock_t *lock)
-{
-        return spin_is_locked(&lock->lock);
-}
-
 #if defined(__KERNEL__) && !defined(HAVE_ADLER)
 /* zlib_adler() is an inline function defined in zutil.h */
 #define HAVE_ADLER