All of lore.kernel.org
 help / color / mirror / Atom feed
* [Ocfs2-devel] [PATCH 11/12] ocfs2/dlm: Move dlm_print_one_mle() from dlmmaster.c to dlmdebug.c
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 09/12] ocfs2/dlm: Dumps the purgelist into a debugfs file Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 02/12] ocfs2/dlm: Creates slabcaches for lock and lockres Sunil Mushran
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

This patch helps in consolidating debugging related functions in dlmdebug.c.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
---
 fs/ocfs2/dlm/dlmdebug.c  |   15 +++++++-
 fs/ocfs2/dlm/dlmdebug.h  |    2 +
 fs/ocfs2/dlm/dlmmaster.c |   89 +---------------------------------------------
 3 files changed, 17 insertions(+), 89 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index b45eeb7..ef91a10 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -58,6 +58,8 @@ void dlm_print_one_lock_resource(struct dlm_lock_resource *res)
 	spin_unlock(&res->spinlock);
 }
 
+int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len);
+
 static void dlm_print_lockres_refmap(struct dlm_lock_resource *res)
 {
 	int bit;
@@ -166,6 +168,17 @@ void dlm_dump_lock_resources(struct dlm_ctxt *dlm)
 }
 #endif  /*  0  */
 
+void dlm_print_one_mle(struct dlm_master_list_entry *mle)
+{
+	char *buf;
+
+	buf = (char *) get_zeroed_page(GFP_NOFS);
+	if (buf) {
+		dump_mle(mle, buf, PAGE_SIZE - 1);
+		free_page((unsigned long)buf);
+	}
+}
+
 static const char *dlm_errnames[] = {
 	[DLM_NORMAL] =			"DLM_NORMAL",
 	[DLM_GRANTED] =			"DLM_GRANTED",
@@ -538,7 +551,7 @@ static struct file_operations debug_purgelist_fops = {
 /* end - purge list funcs */
 
 /* begin - debug mle funcs */
-static int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len)
+int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len)
 {
 	int out = 0;
 	unsigned int namelen;
diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
index 6c6ac72..d197640 100644
--- a/fs/ocfs2/dlm/dlmdebug.h
+++ b/fs/ocfs2/dlm/dlmdebug.h
@@ -55,4 +55,6 @@ void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm);
 int dlm_create_debugfs_root(void);
 void dlm_destroy_debugfs_root(void);
 
+void dlm_print_one_mle(struct dlm_master_list_entry *mle);
+
 #endif
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 74b5283..0e84f28 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -48,6 +48,7 @@
 #include "dlmapi.h"
 #include "dlmcommon.h"
 #include "dlmdomain.h"
+#include "dlmdebug.h"
 
 #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_MASTER)
 #include "cluster/masklog.h"
@@ -90,94 +91,6 @@ static inline int dlm_mle_equal(struct dlm_ctxt *dlm,
 	return 1;
 }
 
-#define dlm_print_nodemap(m)  _dlm_print_nodemap(m,#m)
-static void _dlm_print_nodemap(unsigned long *map, const char *mapname)
-{
-	int i;
-	printk("%s=[ ", mapname);
-	for (i=0; i<O2NM_MAX_NODES; i++)
-		if (test_bit(i, map))
-			printk("%d ", i);
-	printk("]");
-}
-
-static void dlm_print_one_mle(struct dlm_master_list_entry *mle)
-{
-	int refs;
-	char *type;
-	char attached;
-	u8 master;
-	unsigned int namelen;
-	const char *name;
-	struct kref *k;
-	unsigned long *maybe = mle->maybe_map,
-		      *vote = mle->vote_map,
-		      *resp = mle->response_map,
-		      *node = mle->node_map;
-
-	k = &mle->mle_refs;
-	if (mle->type == DLM_MLE_BLOCK)
-		type = "BLK";
-	else if (mle->type == DLM_MLE_MASTER)
-		type = "MAS";
-	else
-		type = "MIG";
-	refs = atomic_read(&k->refcount);
-	master = mle->master;
-	attached = (list_empty(&mle->hb_events) ? 'N' : 'Y');
-
-	if (mle->type != DLM_MLE_MASTER) {
-		namelen = mle->u.name.len;
-		name = mle->u.name.name;
-	} else {
-		namelen = mle->u.res->lockname.len;
-		name = mle->u.res->lockname.name;
-	}
-
-	mlog(ML_NOTICE, "%.*s: %3s refs=%3d mas=%3u new=%3u evt=%c inuse=%d ",
-		  namelen, name, type, refs, master, mle->new_master, attached,
-		  mle->inuse);
-	dlm_print_nodemap(maybe);
-	printk(", ");
-	dlm_print_nodemap(vote);
-	printk(", ");
-	dlm_print_nodemap(resp);
-	printk(", ");
-	dlm_print_nodemap(node);
-	printk(", ");
-	printk("\n");
-}
-
-#if 0
-/* Code here is included but defined out as it aids debugging */
-
-static void dlm_dump_mles(struct dlm_ctxt *dlm)
-{
-	struct dlm_master_list_entry *mle;
-	
-	mlog(ML_NOTICE, "dumping all mles for domain %s:\n", dlm->name);
-	spin_lock(&dlm->master_lock);
-	list_for_each_entry(mle, &dlm->master_list, list)
-		dlm_print_one_mle(mle);
-	spin_unlock(&dlm->master_lock);
-}
-
-int dlm_dump_all_mles(const char __user *data, unsigned int len)
-{
-	struct dlm_ctxt *dlm;
-
-	spin_lock(&dlm_domain_lock);
-	list_for_each_entry(dlm, &dlm_domains, list) {
-		mlog(ML_NOTICE, "found dlm: %p, name=%s\n", dlm, dlm->name);
-		dlm_dump_mles(dlm);
-	}
-	spin_unlock(&dlm_domain_lock);
-	return len;
-}
-EXPORT_SYMBOL_GPL(dlm_dump_all_mles);
-
-#endif  /*  0  */
-
 static struct kmem_cache *dlm_lockres_cache = NULL;
 static struct kmem_cache *dlm_lockname_cache = NULL;
 static struct kmem_cache *dlm_mle_cache = NULL;
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 09/12] ocfs2/dlm: Dumps the purgelist into a debugfs file
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-05 11:09   ` Joel Becker
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 11/12] ocfs2/dlm: Move dlm_print_one_mle() from dlmmaster.c to dlmdebug.c Sunil Mushran
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

This patch dumps all the lockres' on the purgelist it can fit in one page
into a debugfs file. Useful for debugging.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
---
 fs/ocfs2/dlm/dlmdebug.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++
 fs/ocfs2/dlm/dlmdebug.h |    1 +
 2 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index f792af5..0842e1b 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -302,6 +302,7 @@ static int stringify_lockname(const char *lockname, int locklen,
 #define DLM_DEBUGFS_DLM_STATE			"dlm_state"
 #define DLM_DEBUGFS_LOCKING_STATE		"locking_state"
 #define DLM_DEBUGFS_MLE_STATE			"mle_state"
+#define DLM_DEBUGFS_PURGE_LIST			"purge_list"
 
 #ifdef CONFIG_DEBUG_FS
 /* begin - utils funcs */
@@ -396,6 +397,63 @@ static int debug_buffer_release(struct inode *inode, struct file *file)
 }
 /* end - util funcs */
 
+/* begin - purge list funcs */
+static int debug_purgelist_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
+{
+	struct dlm_lock_resource *res;
+	int out = 0;
+	unsigned long total = 0;
+
+	out += snprintf(db->buf + out, db->len - out,
+			"Dumping Purgelist for Domain: %s\n", dlm->name);
+
+	spin_lock(&dlm->spinlock);
+	list_for_each_entry(res, &dlm->purge_list, purge) {
+		++total;
+		if (db->len - out < 100)
+			continue;
+		spin_lock(&res->spinlock);
+		out += stringify_lockname(res->lockname.name,
+					  res->lockname.len,
+					  db->buf + out, db->len - out);
+		out += snprintf(db->buf + out, db->len - out, "\t%ld\n",
+				(jiffies - res->last_used)/HZ);
+		spin_unlock(&res->spinlock);
+	}
+	spin_unlock(&dlm->spinlock);
+
+	out += snprintf(db->buf + out, db->len - out,
+			"Total on list: %ld\n", total);
+
+	return out;
+}
+
+static int debug_purgelist_open(struct inode *inode, struct file *file)
+{
+	struct dlm_ctxt *dlm = inode->i_private;
+	struct debug_buffer *db;
+
+	db = debug_buffer_allocate();
+	if (!db)
+		goto bail;
+
+	db->len = debug_purgelist_print(dlm, db);
+
+	file->private_data = db;
+
+	return 0;
+bail:
+	return -ENOMEM;
+}
+
+static struct file_operations debug_purgelist_fops = {
+	.open =		debug_purgelist_open,
+	.release =	debug_buffer_release,
+	.read =		debug_buffer_read,
+	.llseek =	debug_buffer_llseek,
+};
+/* end - purge list funcs */
+
 /* begin - debug mle funcs */
 static int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len)
 {
@@ -909,6 +967,17 @@ int dlm_debug_init(struct dlm_ctxt *dlm)
 		goto bail;
 	}
 
+	/* for dumping lockres on the purge list */
+	dc->debug_purgelist_dentry =
+			debugfs_create_file(DLM_DEBUGFS_PURGE_LIST,
+					    S_IFREG|S_IRUSR,
+					    dlm->dlm_debugfs_subroot,
+					    dlm, &debug_purgelist_fops);
+	if (!dc->debug_purgelist_dentry) {
+		mlog_errno(-ENOMEM);
+		goto bail;
+	}
+
 	dlm_debug_get(dc);
 	return 0;
 
@@ -925,6 +994,8 @@ void dlm_debug_shutdown(struct dlm_ctxt *dlm)
 	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
 
 	if (dc) {
+		if (dc->debug_purgelist_dentry)
+			debugfs_remove(dc->debug_purgelist_dentry);
 		if (dc->debug_mle_dentry)
 			debugfs_remove(dc->debug_mle_dentry);
 		if (dc->debug_lockres_dentry)
diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
index 313af2a..974a6be 100644
--- a/fs/ocfs2/dlm/dlmdebug.h
+++ b/fs/ocfs2/dlm/dlmdebug.h
@@ -30,6 +30,7 @@ struct dlm_debug_ctxt {
 	struct dentry *debug_state_dentry;
 	struct dentry *debug_lockres_dentry;
 	struct dentry *debug_mle_dentry;
+	struct dentry *debug_purgelist_dentry;
 };
 
 struct debug_buffer {
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 02/12] ocfs2/dlm: Creates slabcaches for lock and lockres
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 09/12] ocfs2/dlm: Dumps the purgelist into a debugfs file Sunil Mushran
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 11/12] ocfs2/dlm: Move dlm_print_one_mle() from dlmmaster.c to dlmdebug.c Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-05 10:53   ` Joel Becker
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 08/12] ocfs2/dlm: Dumps the mles into a debugfs file Sunil Mushran
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

This patch makes the o2dlm allocate memory for lockres, lockname and lock
structures from slabcaches rather than kmalloc. This allows us to not only
make these allocs more efficient but also allows us to track the memory being
consumed by these structures.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
---
 fs/ocfs2/dlm/dlmcommon.h |    7 +++++
 fs/ocfs2/dlm/dlmdomain.c |   26 +++++++++++++++++--
 fs/ocfs2/dlm/dlmlock.c   |   22 +++++++++++++++-
 fs/ocfs2/dlm/dlmmaster.c |   61 +++++++++++++++++++++++++++++++++++++---------
 4 files changed, 99 insertions(+), 17 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index 5b3607c..c281618 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -961,9 +961,16 @@ static inline void __dlm_wait_on_lockres(struct dlm_lock_resource *res)
 					  DLM_LOCK_RES_MIGRATING));
 }
 
+/* create/destroy slab caches */
+int dlm_init_master_caches(void);
+void dlm_destroy_master_caches(void);
+
+int dlm_init_lock_cache(void);
+void dlm_destroy_lock_cache(void);
 
 int dlm_init_mle_cache(void);
 void dlm_destroy_mle_cache(void);
+
 void dlm_hb_event_notify_attached(struct dlm_ctxt *dlm, int idx, int node_up);
 int dlm_drop_lockres_ref(struct dlm_ctxt *dlm,
 			 struct dlm_lock_resource *res);
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 2f15944..c8a4e08 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -1789,21 +1789,41 @@ static int __init dlm_init(void)
 	status = dlm_init_mle_cache();
 	if (status) {
 		mlog(ML_ERROR, "Could not create o2dlm_mle slabcache\n");
-		return -1;
+		goto error;
+	}
+
+	status = dlm_init_master_caches();
+	if (status) {
+		mlog(ML_ERROR, "Could not create o2dlm_lockres and "
+		     "o2dlm_lockname slabcaches\n");
+		goto error;
+	}
+
+	status = dlm_init_lock_cache();
+	if (status) {
+		mlog(ML_ERROR, "Count not create o2dlm_lock slabcache\n");
+		goto error;
 	}
 
 	status = dlm_register_net_handlers();
 	if (status) {
-		dlm_destroy_mle_cache();
-		return -1;
+		mlog(ML_ERROR, "Unable to register network handlers\n");
+		goto error;
 	}
 
 	return 0;
+error:
+	dlm_destroy_lock_cache();
+	dlm_destroy_master_caches();
+	dlm_destroy_mle_cache();
+	return -1;
 }
 
 static void __exit dlm_exit (void)
 {
 	dlm_unregister_net_handlers();
+	dlm_destroy_lock_cache();
+	dlm_destroy_master_caches();
 	dlm_destroy_mle_cache();
 }
 
diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c
index 52578d9..e8e19eb 100644
--- a/fs/ocfs2/dlm/dlmlock.c
+++ b/fs/ocfs2/dlm/dlmlock.c
@@ -53,6 +53,8 @@
 #define MLOG_MASK_PREFIX ML_DLM
 #include "cluster/masklog.h"
 
+static struct kmem_cache *dlm_lock_cache = NULL;
+
 static DEFINE_SPINLOCK(dlm_cookie_lock);
 static u64 dlm_next_cookie = 1;
 
@@ -64,6 +66,22 @@ static void dlm_init_lock(struct dlm_lock *newlock, int type,
 static void dlm_lock_release(struct kref *kref);
 static void dlm_lock_detach_lockres(struct dlm_lock *lock);
 
+int dlm_init_lock_cache(void)
+{
+	dlm_lock_cache = kmem_cache_create("o2dlm_lock",
+					   sizeof(struct dlm_lock), 0,
+					   SLAB_HWCACHE_ALIGN, NULL);
+	if (dlm_lock_cache == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
+void dlm_destroy_lock_cache(void)
+{
+	if (dlm_lock_cache)
+		kmem_cache_destroy(dlm_lock_cache);
+}
+
 /* Tell us whether we can grant a new lock request.
  * locking:
  *   caller needs:  res->spinlock
@@ -353,7 +371,7 @@ static void dlm_lock_release(struct kref *kref)
 		mlog(0, "freeing kernel-allocated lksb\n");
 		kfree(lock->lksb);
 	}
-	kfree(lock);
+	kmem_cache_free(dlm_lock_cache, lock);
 }
 
 /* associate a lock with it's lockres, getting a ref on the lockres */
@@ -412,7 +430,7 @@ struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie,
 	struct dlm_lock *lock;
 	int kernel_allocated = 0;
 
-	lock = kzalloc(sizeof(*lock), GFP_NOFS);
+	lock = (struct dlm_lock *) kmem_cache_zalloc(dlm_lock_cache, GFP_NOFS);
 	if (!lock)
 		return NULL;
 
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 90797c5..ac9ed31 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -216,10 +216,10 @@ EXPORT_SYMBOL_GPL(dlm_dump_all_mles);
 
 #endif  /*  0  */
 
-
+static struct kmem_cache *dlm_lockres_cache = NULL;
+static struct kmem_cache *dlm_lockname_cache = NULL;
 static struct kmem_cache *dlm_mle_cache = NULL;
 
-
 static void dlm_mle_release(struct kref *kref);
 static void dlm_init_mle(struct dlm_master_list_entry *mle,
 			enum dlm_mle_type type,
@@ -560,6 +560,35 @@ static void dlm_mle_release(struct kref *kref)
  * LOCK RESOURCE FUNCTIONS
  */
 
+int dlm_init_master_caches(void)
+{
+	dlm_lockres_cache = kmem_cache_create("o2dlm_lockres",
+					      sizeof(struct dlm_lock_resource),
+					      0, SLAB_HWCACHE_ALIGN, NULL);
+	if (!dlm_lockres_cache)
+		goto bail;
+
+	dlm_lockname_cache = kmem_cache_create("o2dlm_lockname",
+					       DLM_LOCKID_NAME_MAX, 0,
+					       SLAB_HWCACHE_ALIGN, NULL);
+	if (!dlm_lockname_cache)
+		goto bail;
+
+	return 0;
+bail:
+	dlm_destroy_master_caches();
+	return -ENOMEM;
+}
+
+void dlm_destroy_master_caches(void)
+{
+	if (dlm_lockname_cache)
+		kmem_cache_destroy(dlm_lockname_cache);
+
+	if (dlm_lockres_cache)
+		kmem_cache_destroy(dlm_lockres_cache);
+}
+
 static void dlm_set_lockres_owner(struct dlm_ctxt *dlm,
 				  struct dlm_lock_resource *res,
 				  u8 owner)
@@ -642,9 +671,9 @@ static void dlm_lockres_release(struct kref *kref)
 	BUG_ON(!list_empty(&res->recovering));
 	BUG_ON(!list_empty(&res->purge));
 
-	kfree(res->lockname.name);
+	kmem_cache_free(dlm_lockname_cache, (void *)res->lockname.name);
 
-	kfree(res);
+	kmem_cache_free(dlm_lockres_cache, res);
 }
 
 void dlm_lockres_put(struct dlm_lock_resource *res)
@@ -700,20 +729,28 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
 				   const char *name,
 				   unsigned int namelen)
 {
-	struct dlm_lock_resource *res;
+	struct dlm_lock_resource *res = NULL;
 
-	res = kmalloc(sizeof(struct dlm_lock_resource), GFP_NOFS);
+	res = (struct dlm_lock_resource *)
+				kmem_cache_zalloc(dlm_lockres_cache, GFP_NOFS);
 	if (!res)
-		return NULL;
+		goto error;
 
-	res->lockname.name = kmalloc(namelen, GFP_NOFS);
-	if (!res->lockname.name) {
-		kfree(res);
-		return NULL;
-	}
+	res->lockname.name = (char *)
+				kmem_cache_zalloc(dlm_lockname_cache, GFP_NOFS);
+	if (!res->lockname.name)
+		goto error;
 
 	dlm_init_lockres(dlm, res, name, namelen);
 	return res;
+
+error:
+	if (res && res->lockname.name)
+		kmem_cache_free(dlm_lockname_cache, (void *)res->lockname.name);
+
+	if (res)
+		kmem_cache_free(dlm_lockres_cache, res);
+	return NULL;
 }
 
 void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 08/12] ocfs2/dlm: Dumps the mles into a debugfs file
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
                   ` (2 preceding siblings ...)
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 02/12] ocfs2/dlm: Creates slabcaches for lock and lockres Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-05 11:09   ` Joel Becker
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 05/12] ocfs2/dlm: Dump the dlm state in " Sunil Mushran
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

This patch dumps all mles it can fit in one page into a debugfs file.
Useful for debugging.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
---
 fs/ocfs2/dlm/dlmdebug.c |  119 +++++++++++++++++++++++++++++++++++++++++++++++
 fs/ocfs2/dlm/dlmdebug.h |    1 +
 2 files changed, 120 insertions(+), 0 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index 5afc723..f792af5 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -301,6 +301,7 @@ static int stringify_lockname(const char *lockname, int locklen,
 #define DLM_DEBUGFS_DIR				"o2dlm"
 #define DLM_DEBUGFS_DLM_STATE			"dlm_state"
 #define DLM_DEBUGFS_LOCKING_STATE		"locking_state"
+#define DLM_DEBUGFS_MLE_STATE			"mle_state"
 
 #ifdef CONFIG_DEBUG_FS
 /* begin - utils funcs */
@@ -395,6 +396,112 @@ static int debug_buffer_release(struct inode *inode, struct file *file)
 }
 /* end - util funcs */
 
+/* begin - debug mle funcs */
+static int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len)
+{
+	int out = 0;
+	unsigned int namelen;
+	const char *name;
+	char *mle_type;
+
+	if (mle->type != DLM_MLE_MASTER) {
+		namelen = mle->u.name.len;
+		name = mle->u.name.name;
+	} else {
+		namelen = mle->u.res->lockname.len;
+		name = mle->u.res->lockname.name;
+	}
+
+	if (mle->type == DLM_MLE_BLOCK)
+		mle_type = "BLK";
+	else if (mle->type == DLM_MLE_MASTER)
+		mle_type = "MAS";
+	else
+		mle_type = "MIG";
+
+	out += stringify_lockname(name, namelen, buf + out, len - out);
+	out += snprintf(buf + out, len - out,
+			"\t%3s\tmas=%3u\tnew=%3u\tevt=%1d\tuse=%1d\tref=%3d\n",
+			mle_type, mle->master, mle->new_master,
+			!list_empty(&mle->hb_events),
+			!!mle->inuse,
+			atomic_read(&mle->mle_refs.refcount));
+
+	out += snprintf(buf + out, len - out, "Maybe=");
+	out += stringify_nodemap(mle->maybe_map, O2NM_MAX_NODES,
+				 buf + out, len - out);
+	out += snprintf(buf + out, len - out, "\n");
+
+	out += snprintf(buf + out, len - out, "Vote=");
+	out += stringify_nodemap(mle->vote_map, O2NM_MAX_NODES,
+				 buf + out, len - out);
+	out += snprintf(buf + out, len - out, "\n");
+
+	out += snprintf(buf + out, len - out, "Response=");
+	out += stringify_nodemap(mle->response_map, O2NM_MAX_NODES,
+				 buf + out, len - out);
+	out += snprintf(buf + out, len - out, "\n");
+
+	out += snprintf(buf + out, len - out, "Node=");
+	out += stringify_nodemap(mle->node_map, O2NM_MAX_NODES,
+				 buf + out, len - out);
+	out += snprintf(buf + out, len - out, "\n");
+
+	out += snprintf(buf + out, len - out, "\n");
+
+	return out;
+}
+
+static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
+{
+	struct dlm_master_list_entry *mle;
+	int out = 0;
+	unsigned long total = 0;
+
+	out += snprintf(db->buf + out, db->len - out,
+			"Dumping MLEs for Domain: %s\n", dlm->name);
+
+	spin_lock(&dlm->master_lock);
+	list_for_each_entry(mle, &dlm->master_list, list) {
+		++total;
+		if (db->len - out < 200)
+			continue;
+		out += dump_mle(mle, db->buf + out, db->len - out);
+	}
+	spin_unlock(&dlm->master_lock);
+
+	out += snprintf(db->buf + out, db->len - out,
+			"Total on list: %ld\n", total);
+	return out;
+}
+
+static int debug_mle_open(struct inode *inode, struct file *file)
+{
+	struct dlm_ctxt *dlm = inode->i_private;
+	struct debug_buffer *db;
+
+	db = debug_buffer_allocate();
+	if (!db)
+		goto bail;
+
+	db->len = debug_mle_print(dlm, db);
+
+	file->private_data = db;
+
+	return 0;
+bail:
+	return -ENOMEM;
+}
+
+static struct file_operations debug_mle_fops = {
+	.open =		debug_mle_open,
+	.release =	debug_buffer_release,
+	.read =		debug_buffer_read,
+	.llseek =	debug_buffer_llseek,
+};
+
+/* end - debug mle funcs */
+
 /* begin - debug lockres funcs */
 static int dump_lock(struct dlm_lock *lock, int list_type, char *buf, int len)
 {
@@ -792,6 +899,16 @@ int dlm_debug_init(struct dlm_ctxt *dlm)
 		goto bail;
 	}
 
+	/* for dumping mles */
+	dc->debug_mle_dentry = debugfs_create_file(DLM_DEBUGFS_MLE_STATE,
+						   S_IFREG|S_IRUSR,
+						   dlm->dlm_debugfs_subroot,
+						   dlm, &debug_mle_fops);
+	if (!dc->debug_mle_dentry) {
+		mlog_errno(-ENOMEM);
+		goto bail;
+	}
+
 	dlm_debug_get(dc);
 	return 0;
 
@@ -808,6 +925,8 @@ void dlm_debug_shutdown(struct dlm_ctxt *dlm)
 	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
 
 	if (dc) {
+		if (dc->debug_mle_dentry)
+			debugfs_remove(dc->debug_mle_dentry);
 		if (dc->debug_lockres_dentry)
 			debugfs_remove(dc->debug_lockres_dentry);
 		if (dc->debug_state_dentry)
diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
index 6676a50..313af2a 100644
--- a/fs/ocfs2/dlm/dlmdebug.h
+++ b/fs/ocfs2/dlm/dlmdebug.h
@@ -29,6 +29,7 @@ struct dlm_debug_ctxt {
 	struct kref debug_refcnt;
 	struct dentry *debug_state_dentry;
 	struct dentry *debug_lockres_dentry;
+	struct dentry *debug_mle_dentry;
 };
 
 struct debug_buffer {
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 05/12] ocfs2/dlm: Dump the dlm state in a debugfs file
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
                   ` (3 preceding siblings ...)
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 08/12] ocfs2/dlm: Dumps the mles into a debugfs file Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-05 11:05   ` Joel Becker
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 04/12] ocfs2/dlm: Create debugfs dirs Sunil Mushran
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

This patch dumps the dlm state (dlm_ctxt) into a debugfs file.
Useful for debugging.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
---
 fs/ocfs2/dlm/dlmcommon.h |    1 +
 fs/ocfs2/dlm/dlmdebug.c  |  304 ++++++++++++++++++++++++++++++++++++++++++++++
 fs/ocfs2/dlm/dlmdebug.h  |   13 ++
 fs/ocfs2/dlm/dlmdomain.c |    8 ++
 4 files changed, 326 insertions(+), 0 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index a20d093..c772a7f 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -123,6 +123,7 @@ struct dlm_ctxt
 	atomic_t remote_resources;
 	atomic_t unknown_resources;
 
+	struct dlm_debug_ctxt *dlm_debug_ctxt;
 	struct dentry *dlm_debugfs_subroot;
 
 	/* NOTE: Next three are protected by dlm_domain_lock */
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index be63024..540c4f8 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -273,6 +273,302 @@ const char *dlm_errname(enum dlm_status err)
 EXPORT_SYMBOL_GPL(dlm_errname);
 
 #define DLM_DEBUGFS_DIR				"o2dlm"
+#define DLM_DEBUGFS_DLM_STATE			"dlm_state"
+
+#ifdef CONFIG_DEBUG_FS
+/* begin - utils funcs */
+static void dlm_debug_free(struct kref *kref)
+{
+	struct dlm_debug_ctxt *dc;
+
+	dc = container_of(kref, struct dlm_debug_ctxt, debug_refcnt);
+
+	kfree(dc);
+}
+
+void dlm_debug_put(struct dlm_debug_ctxt *dc)
+{
+	if (dc)
+		kref_put(&dc->debug_refcnt, dlm_debug_free);
+}
+
+static void dlm_debug_get(struct dlm_debug_ctxt *dc)
+{
+	kref_get(&dc->debug_refcnt);
+}
+
+static int stringify_nodemap(unsigned long *nodemap, int maxnodes,
+			     char *buf, int len)
+{
+	int out = 0;
+	int i = -1;
+
+	while ((i = find_next_bit(nodemap, maxnodes, i + 1)) < maxnodes)
+		out += snprintf(buf + out, len - out, "%d ", i);
+
+	return out;
+}
+
+static struct debug_buffer *debug_buffer_allocate(void)
+{
+	struct debug_buffer *db = NULL;
+
+	db = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
+	if (!db)
+		goto bail;
+
+	db->len = PAGE_SIZE;
+	db->buf = kmalloc(db->len, GFP_KERNEL);
+	if (!db->buf)
+		goto bail;
+
+	return db;
+bail:
+	kfree(db);
+	return NULL;
+}
+
+static ssize_t debug_buffer_read(struct file *file, char __user *buf,
+				 size_t nbytes, loff_t *ppos)
+{
+	struct debug_buffer *db = file->private_data;
+
+	return simple_read_from_buffer(buf, nbytes, ppos, db->buf, db->len);
+}
+
+static loff_t debug_buffer_llseek(struct file *file, loff_t off, int whence)
+{
+	struct debug_buffer *db = file->private_data;
+	loff_t new = -1;
+
+	switch (whence) {
+	case 0:
+		new = off;
+		break;
+	case 1:
+		new = file->f_pos + off;
+		break;
+	}
+
+	if (new < 0 || new > db->len)
+		return -EINVAL;
+
+	return (file->f_pos = new);
+}
+
+static int debug_buffer_release(struct inode *inode, struct file *file)
+{
+	struct debug_buffer *db = (struct debug_buffer *)file->private_data;
+
+	if (db)
+		kfree(db->buf);
+	kfree(db);
+
+	return 0;
+}
+/* end - util funcs */
+
+/* begin - debug state funcs */
+static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
+{
+	int out = 0;
+	struct dlm_reco_node_data *node;
+	char *state;
+	int lres, rres, ures, tres;
+
+	lres = atomic_read(&dlm->local_resources);
+	rres = atomic_read(&dlm->remote_resources);
+	ures = atomic_read(&dlm->unknown_resources);
+	tres = lres + rres + ures;
+
+	spin_lock(&dlm->spinlock);
+
+	switch (dlm->dlm_state) {
+	case DLM_CTXT_NEW:
+		state = "NEW"; break;
+	case DLM_CTXT_JOINED:
+		state = "JOINED"; break;
+	case DLM_CTXT_IN_SHUTDOWN:
+		state = "SHUTDOWN"; break;
+	case DLM_CTXT_LEAVING:
+		state = "LEAVING"; break;
+	default:
+		state = "UNKNOWN"; break;
+	}
+
+	/* Domain: xxxxxxxxxx  Key: 0xdfbac769 */
+	out += snprintf(db->buf + out, db->len - out,
+			"Domain: %s  Key: 0x%08x\n", dlm->name, dlm->key);
+
+	/* Thread Pid: xxx  Node: xxx  State: xxxxx */
+	out += snprintf(db->buf + out, db->len - out,
+			"Thread Pid: %d  Node: %d  State: %s\n",
+			task_pid_nr(dlm->dlm_thread_task), dlm->node_num,
+			state);
+
+	/* Number of Joins: xxx  Joining Node: xxx */
+	out += snprintf(db->buf + out, db->len - out,
+			"Number of Joins: %d  Joining Node: %d\n",
+			dlm->num_joins, dlm->joining_node);
+
+	/* Domain Map: xx xx xx */
+	out += snprintf(db->buf + out, db->len - out, "Domain Map: ");
+	out += stringify_nodemap(dlm->domain_map, O2NM_MAX_NODES,
+				 db->buf + out, db->len - out);
+	out += snprintf(db->buf + out, db->len - out, "\n");
+
+	/* Live Map: xx xx xx */
+	out += snprintf(db->buf + out, db->len - out, "Live Map: ");
+	out += stringify_nodemap(dlm->live_nodes_map, O2NM_MAX_NODES,
+				 db->buf + out, db->len - out);
+	out += snprintf(db->buf + out, db->len - out, "\n");
+
+	/* Mastered Resources Total: xxx  Locally: xxx  Remotely: ... */
+	out += snprintf(db->buf + out, db->len - out,
+			"Mastered Resources Total: %d  Locally: %d  "
+			"Remotely: %d  Unknown: %d\n",
+			tres, lres, rres, ures);
+
+	/* Lists: Dirty=Empty  Purge=InUse  PendingASTs=Empty  ... */
+	out += snprintf(db->buf + out, db->len - out,
+			"Lists: Dirty=%s  Purge=%s  PendingASTs=%s  "
+			"PendingBASTs=%s  Master=%s\n",
+			(list_empty(&dlm->dirty_list) ? "Empty" : "InUse"),
+			(list_empty(&dlm->purge_list) ? "Empty" : "InUse"),
+			(list_empty(&dlm->pending_asts) ? "Empty" : "InUse"),
+			(list_empty(&dlm->pending_basts) ? "Empty" : "InUse"),
+			(list_empty(&dlm->master_list) ? "Empty" : "InUse"));
+
+	/* Purge Count: xxx  Refs: xxx */
+	out += snprintf(db->buf + out, db->len - out,
+			"Purge Count: %d  Refs: %d\n", dlm->purge_count,
+			atomic_read(&dlm->dlm_refs.refcount));
+
+	/* Dead Node: xxx */
+	out += snprintf(db->buf + out, db->len - out,
+			"Dead Node: %d\n", dlm->reco.dead_node);
+
+	/* What about DLM_RECO_STATE_FINALIZE? */
+	if (dlm->reco.state == DLM_RECO_STATE_ACTIVE)
+		state = "ACTIVE";
+	else
+		state = "INACTIVE";
+
+	/* Recovery Pid: xxxx  Master: xxx  State: xxxx */
+	out += snprintf(db->buf + out, db->len - out,
+			"Recovery Pid: %d  Master: %d  State: %s\n",
+			task_pid_nr(dlm->dlm_reco_thread_task),
+			dlm->reco.new_master, state);
+
+	/* Recovery Map: xx xx */
+	out += snprintf(db->buf + out, db->len - out, "Recovery Map: ");
+	out += stringify_nodemap(dlm->recovery_map, O2NM_MAX_NODES,
+				 db->buf + out, db->len - out);
+	out += snprintf(db->buf + out, db->len - out, "\n");
+
+	/* Recovery Node State: */
+	out += snprintf(db->buf + out, db->len - out, "Recovery Node State:\n");
+	list_for_each_entry(node, &dlm->reco.node_data, list) {
+		switch (node->state) {
+		case DLM_RECO_NODE_DATA_INIT:
+			state = "INIT";
+			break;
+		case DLM_RECO_NODE_DATA_REQUESTING:
+			state = "REQUESTING";
+			break;
+		case DLM_RECO_NODE_DATA_DEAD:
+			state = "DEAD";
+			break;
+		case DLM_RECO_NODE_DATA_RECEIVING:
+			state = "RECEIVING";
+			break;
+		case DLM_RECO_NODE_DATA_REQUESTED:
+			state = "REQUESTED";
+			break;
+		case DLM_RECO_NODE_DATA_DONE:
+			state = "DONE";
+			break;
+		case DLM_RECO_NODE_DATA_FINALIZE_SENT:
+			state = "FINALIZE-SENT";
+			break;
+		default:
+			state = "BAD";
+			break;
+		}
+		out += snprintf(db->buf + out, db->len - out, "\t%u - %s\n",
+				node->node_num, state);
+	}
+
+	spin_unlock(&dlm->spinlock);
+
+	return out;
+}
+
+static int debug_state_open(struct inode *inode, struct file *file)
+{
+	struct dlm_ctxt *dlm = inode->i_private;
+	struct debug_buffer *db = NULL;
+
+	db = debug_buffer_allocate();
+	if (!db)
+		goto bail;
+
+	db->len = debug_state_print(dlm, db);
+
+	file->private_data = db;
+
+	return 0;
+bail:
+	return -ENOMEM;
+}
+
+static struct file_operations debug_state_fops = {
+	.open =		debug_state_open,
+	.release =	debug_buffer_release,
+	.read =		debug_buffer_read,
+	.llseek =	debug_buffer_llseek,
+};
+/* end  - debug state funcs */
+#endif
+
+/* files in subroot */
+int dlm_debug_init(struct dlm_ctxt *dlm)
+{
+#ifdef CONFIG_DEBUG_FS
+	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
+
+	/* for dumping dlm_ctxt */
+	dc->debug_state_dentry = debugfs_create_file(DLM_DEBUGFS_DLM_STATE,
+						     S_IFREG|S_IRUSR,
+						     dlm->dlm_debugfs_subroot,
+						     dlm, &debug_state_fops);
+	if (!dc->debug_state_dentry) {
+		mlog_errno(-ENOMEM);
+		goto bail;
+	}
+
+	dlm_debug_get(dc);
+	return 0;
+
+bail:
+	dlm_debug_shutdown(dlm);
+	return -ENOMEM;
+#endif
+	return 0;
+}
+
+void dlm_debug_shutdown(struct dlm_ctxt *dlm)
+{
+#ifdef CONFIG_DEBUG_FS
+	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
+
+	if (dc) {
+		if (dc->debug_state_dentry)
+			debugfs_remove(dc->debug_state_dentry);
+		dlm_debug_put(dc);
+	}
+#endif
+}
 
 /* subroot - domain dir */
 int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm)
@@ -285,6 +581,14 @@ int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm)
 		goto bail;
 	}
 
+	dlm->dlm_debug_ctxt = kzalloc(sizeof(struct dlm_debug_ctxt),
+				      GFP_KERNEL);
+	if (!dlm->dlm_debug_ctxt) {
+		mlog_errno(-ENOMEM);
+		goto bail;
+	}
+	kref_init(&dlm->dlm_debug_ctxt->debug_refcnt);
+
 	return 0;
 bail:
 	dlm_destroy_debugfs_subroot(dlm);
diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
index eb397d5..e6e3cd0 100644
--- a/fs/ocfs2/dlm/dlmdebug.h
+++ b/fs/ocfs2/dlm/dlmdebug.h
@@ -25,6 +25,19 @@
 #ifndef DLMDEBUG_H
 #define DLMDEBUG_H
 
+struct dlm_debug_ctxt {
+	struct kref debug_refcnt;
+	struct dentry *debug_state_dentry;
+};
+
+struct debug_buffer {
+	int len;
+	char *buf;
+};
+
+int dlm_debug_init(struct dlm_ctxt *dlm);
+void dlm_debug_shutdown(struct dlm_ctxt *dlm);
+
 int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm);
 void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm);
 
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 2fd17a4..133617e 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -399,6 +399,7 @@ static void dlm_destroy_dlm_worker(struct dlm_ctxt *dlm)
 static void dlm_complete_dlm_shutdown(struct dlm_ctxt *dlm)
 {
 	dlm_unregister_domain_handlers(dlm);
+	dlm_debug_shutdown(dlm);
 	dlm_complete_thread(dlm);
 	dlm_complete_recovery_thread(dlm);
 	dlm_destroy_dlm_worker(dlm);
@@ -1390,6 +1391,12 @@ static int dlm_join_domain(struct dlm_ctxt *dlm)
 		goto bail;
 	}
 
+	status = dlm_debug_init(dlm);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
 	status = dlm_launch_thread(dlm);
 	if (status < 0) {
 		mlog_errno(status);
@@ -1457,6 +1464,7 @@ bail:
 
 	if (status) {
 		dlm_unregister_domain_handlers(dlm);
+		dlm_debug_shutdown(dlm);
 		dlm_complete_thread(dlm);
 		dlm_complete_recovery_thread(dlm);
 		dlm_destroy_dlm_worker(dlm);
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 04/12] ocfs2/dlm: Create debugfs dirs
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
                   ` (4 preceding siblings ...)
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 05/12] ocfs2/dlm: Dump the dlm state in " Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-05 10:55   ` Joel Becker
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 10/12] ocfs2/dlm: Dumps the workqueue into a debugfs file Sunil Mushran
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

This patch creates the debugfs directories that will hold the
files to be used to dump the dlm state.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
---
 fs/ocfs2/dlm/dlmcommon.h |    2 +
 fs/ocfs2/dlm/dlmdebug.c  |   57 +++++++++++++++++++++++++++++++++++++++++++++-
 fs/ocfs2/dlm/dlmdebug.h  |   34 +++++++++++++++++++++++++++
 fs/ocfs2/dlm/dlmdomain.c |   20 ++++++++++++++++
 4 files changed, 112 insertions(+), 1 deletions(-)
 create mode 100644 fs/ocfs2/dlm/dlmdebug.h

diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index e2a2b7a..a20d093 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -123,6 +123,8 @@ struct dlm_ctxt
 	atomic_t remote_resources;
 	atomic_t unknown_resources;
 
+	struct dentry *dlm_debugfs_subroot;
+
 	/* NOTE: Next three are protected by dlm_domain_lock */
 	struct kref dlm_refs;
 	enum dlm_ctxt_state dlm_state;
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index 64239b3..be63024 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -30,6 +30,7 @@
 #include <linux/utsname.h>
 #include <linux/sysctl.h>
 #include <linux/spinlock.h>
+#include <linux/debugfs.h>
 
 #include "cluster/heartbeat.h"
 #include "cluster/nodemanager.h"
@@ -37,12 +38,16 @@
 
 #include "dlmapi.h"
 #include "dlmcommon.h"
-
 #include "dlmdomain.h"
+#include "dlmdebug.h"
 
 #define MLOG_MASK_PREFIX ML_DLM
 #include "cluster/masklog.h"
 
+#ifdef CONFIG_DEBUG_FS
+static struct dentry *dlm_debugfs_root = NULL;
+#endif
+
 void dlm_print_one_lock_resource(struct dlm_lock_resource *res)
 {
 	mlog(ML_NOTICE, "lockres: %.*s, owner=%u, state=%u\n",
@@ -266,3 +271,53 @@ const char *dlm_errname(enum dlm_status err)
 	return dlm_errnames[err];
 }
 EXPORT_SYMBOL_GPL(dlm_errname);
+
+#define DLM_DEBUGFS_DIR				"o2dlm"
+
+/* subroot - domain dir */
+int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm)
+{
+#ifdef CONFIG_DEBUG_FS
+	dlm->dlm_debugfs_subroot = debugfs_create_dir(dlm->name,
+						      dlm_debugfs_root);
+	if (!dlm->dlm_debugfs_subroot) {
+		mlog_errno(-ENOMEM);
+		goto bail;
+	}
+
+	return 0;
+bail:
+	dlm_destroy_debugfs_subroot(dlm);
+	return -ENOMEM;
+#endif
+	return 0;
+}
+
+void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm)
+{
+#ifdef CONFIG_DEBUG_FS
+	if (dlm->dlm_debugfs_subroot)
+		debugfs_remove(dlm->dlm_debugfs_subroot);
+#endif
+}
+
+/* debugfs root */
+int dlm_create_debugfs_root(void)
+{
+#ifdef CONFIG_DEBUG_FS
+	dlm_debugfs_root = debugfs_create_dir(DLM_DEBUGFS_DIR, NULL);
+	if (!dlm_debugfs_root) {
+		mlog_errno(-ENOMEM);
+		return -ENOMEM;
+	}
+#endif
+	return 0;
+}
+
+void dlm_destroy_debugfs_root(void)
+{
+#ifdef CONFIG_DEBUG_FS
+	if (dlm_debugfs_root)
+		debugfs_remove(dlm_debugfs_root);
+#endif
+}
diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
new file mode 100644
index 0000000..eb397d5
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmdebug.h
@@ -0,0 +1,34 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmdebug.h
+ *
+ * Copyright (C) 2008 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef DLMDEBUG_H
+#define DLMDEBUG_H
+
+int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm);
+void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm);
+
+int dlm_create_debugfs_root(void);
+void dlm_destroy_debugfs_root(void);
+
+#endif
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 6b62211..2fd17a4 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -33,6 +33,7 @@
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/debugfs.h>
 
 #include "cluster/heartbeat.h"
 #include "cluster/nodemanager.h"
@@ -42,6 +43,7 @@
 #include "dlmcommon.h"
 
 #include "dlmdomain.h"
+#include "dlmdebug.h"
 
 #include "dlmver.h"
 
@@ -298,6 +300,8 @@ static int dlm_wait_on_domain_helper(const char *domain)
 
 static void dlm_free_ctxt_mem(struct dlm_ctxt *dlm)
 {
+	dlm_destroy_debugfs_subroot(dlm);
+
 	if (dlm->lockres_hash)
 		dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
 
@@ -1465,6 +1469,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
 				u32 key)
 {
 	int i;
+	int ret;
 	struct dlm_ctxt *dlm = NULL;
 
 	dlm = kzalloc(sizeof(*dlm), GFP_KERNEL);
@@ -1497,6 +1502,15 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
 	dlm->key = key;
 	dlm->node_num = o2nm_this_node();
 
+	ret = dlm_create_debugfs_subroot(dlm);
+	if (ret < 0) {
+		dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
+		kfree(dlm->name);
+		kfree(dlm);
+		dlm = NULL;
+		goto leave;
+	}
+
 	spin_lock_init(&dlm->spinlock);
 	spin_lock_init(&dlm->master_lock);
 	spin_lock_init(&dlm->ast_lock);
@@ -1822,8 +1836,13 @@ static int __init dlm_init(void)
 		goto error;
 	}
 
+	status = dlm_create_debugfs_root();
+	if (status)
+		goto error;
+
 	return 0;
 error:
+	dlm_unregister_net_handlers();
 	dlm_destroy_lock_cache();
 	dlm_destroy_master_caches();
 	dlm_destroy_mle_cache();
@@ -1832,6 +1851,7 @@ error:
 
 static void __exit dlm_exit (void)
 {
+	dlm_destroy_debugfs_root();
 	dlm_unregister_net_handlers();
 	dlm_destroy_lock_cache();
 	dlm_destroy_master_caches();
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 10/12] ocfs2/dlm: Dumps the workqueue into a debugfs file
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
                   ` (5 preceding siblings ...)
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 04/12] ocfs2/dlm: Create debugfs dirs Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-05 11:12   ` Joel Becker
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 07/12] ocfs2/dlm: Move struct dlm_master_list_entry to dlmcommon.h Sunil Mushran
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

This patch dumps all the tasks on the workqueue it can fit in one page
into a debugfs file. Useful for debugging.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
---
 fs/ocfs2/dlm/dlmcommon.h   |    3 +
 fs/ocfs2/dlm/dlmdebug.c    |   96 ++++++++++++++++++++++++++++++++++++++++++++
 fs/ocfs2/dlm/dlmdebug.h    |    1 +
 fs/ocfs2/dlm/dlmmaster.c   |    3 +-
 fs/ocfs2/dlm/dlmrecovery.c |    7 +--
 5 files changed, 103 insertions(+), 7 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index 3a59fdc..08d8a7f 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -975,6 +975,9 @@ int dlm_finalize_reco_handler(struct o2net_msg *msg, u32 len, void *data,
 int dlm_do_master_requery(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
 			  u8 nodenum, u8 *real_master);
 
+void dlm_request_all_locks_worker(struct dlm_work_item *item, void *data);
+void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data);
+void dlm_assert_master_worker(struct dlm_work_item *item, void *data);
 
 int dlm_dispatch_assert_master(struct dlm_ctxt *dlm,
 			       struct dlm_lock_resource *res,
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index 0842e1b..b45eeb7 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -303,6 +303,7 @@ static int stringify_lockname(const char *lockname, int locklen,
 #define DLM_DEBUGFS_LOCKING_STATE		"locking_state"
 #define DLM_DEBUGFS_MLE_STATE			"mle_state"
 #define DLM_DEBUGFS_PURGE_LIST			"purge_list"
+#define DLM_DEBUGFS_WORK_QUEUE			"work_queue"
 
 #ifdef CONFIG_DEBUG_FS
 /* begin - utils funcs */
@@ -397,6 +398,88 @@ static int debug_buffer_release(struct inode *inode, struct file *file)
 }
 /* end - util funcs */
 
+/* begin - work queue funcs */
+static int debug_workqueue_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
+{
+	struct dlm_work_item *wi;
+	int out = 0;
+	unsigned long total = 0;
+	struct qstr *lockname;
+
+	out += snprintf(db->buf + out, db->len - out,
+			"Dumping Workqueue for Domain: %s\n", dlm->name);
+
+	spin_lock(&dlm->work_lock);
+	list_for_each_entry(wi, &dlm->work_list, list) {
+		++total;
+		if (db->len - out < 100)
+			continue;
+		if (wi->func == dlm_request_all_locks_worker) {
+			out += snprintf(db->buf + out, db->len - out,
+					"RequestAllLocks, "
+					"recomaster=%d, deadnode=%d\n",
+					wi->u.ral.reco_master,
+					wi->u.ral.dead_node);
+		} else if (wi->func == dlm_mig_lockres_worker) {
+			out += snprintf(db->buf + out, db->len - out,
+					"MigrateLockres,  ");
+			lockname = &(wi->u.ml.lockres->lockname);
+			out += stringify_lockname(lockname->name,
+						  lockname->len,
+						  db->buf + out, db->len - out);
+			out += snprintf(db->buf + out, db->len - out,
+					"  master=%d\n", wi->u.ml.real_master);
+		} else if (wi->func == dlm_assert_master_worker) {
+			out += snprintf(db->buf + out, db->len - out,
+					"AssertMaster, ");
+			lockname = &(wi->u.am.lockres->lockname);
+			out += stringify_lockname(lockname->name,
+						  lockname->len,
+						  db->buf + out, db->len - out);
+			out += snprintf(db->buf + out, db->len - out,
+					" from=%d, flags=0x%X, ignore=%d\n",
+					wi->u.am.request_from,
+					wi->u.am.flags,
+					wi->u.am.ignore_higher);
+		} else {
+			out += snprintf(db->buf + out, db->len - out,
+					"Unknown, 0x%p\n", wi->func);
+		}
+	}
+	spin_unlock(&dlm->work_lock);
+
+	out += snprintf(db->buf + out, db->len - out,
+			"Total on list: %ld\n", total);
+
+	return out;
+}
+
+static int debug_workqueue_open(struct inode *inode, struct file *file)
+{
+	struct dlm_ctxt *dlm = inode->i_private;
+	struct debug_buffer *db;
+
+	db = debug_buffer_allocate();
+	if (!db)
+		goto bail;
+
+	db->len = debug_workqueue_print(dlm, db);
+
+	file->private_data = db;
+
+	return 0;
+bail:
+	return -ENOMEM;
+}
+
+static struct file_operations debug_workqueue_fops = {
+	.open =		debug_workqueue_open,
+	.release =	debug_buffer_release,
+	.read =		debug_buffer_read,
+	.llseek =	debug_buffer_llseek,
+};
+/* end - work queue funcs */
+
 /* begin - purge list funcs */
 static int debug_purgelist_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
 {
@@ -978,6 +1061,17 @@ int dlm_debug_init(struct dlm_ctxt *dlm)
 		goto bail;
 	}
 
+	/* for dumping the dlm work queue */
+	dc->debug_workqueue_dentry =
+			debugfs_create_file(DLM_DEBUGFS_WORK_QUEUE,
+					    S_IFREG|S_IRUSR,
+					    dlm->dlm_debugfs_subroot,
+					    dlm, &debug_workqueue_fops);
+	if (!dc->debug_workqueue_dentry) {
+		mlog_errno(-ENOMEM);
+		goto bail;
+	}
+
 	dlm_debug_get(dc);
 	return 0;
 
@@ -994,6 +1088,8 @@ void dlm_debug_shutdown(struct dlm_ctxt *dlm)
 	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
 
 	if (dc) {
+		if (dc->debug_workqueue_dentry)
+			debugfs_remove(dc->debug_workqueue_dentry);
 		if (dc->debug_purgelist_dentry)
 			debugfs_remove(dc->debug_purgelist_dentry);
 		if (dc->debug_mle_dentry)
diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
index 974a6be..6c6ac72 100644
--- a/fs/ocfs2/dlm/dlmdebug.h
+++ b/fs/ocfs2/dlm/dlmdebug.h
@@ -31,6 +31,7 @@ struct dlm_debug_ctxt {
 	struct dentry *debug_lockres_dentry;
 	struct dentry *debug_mle_dentry;
 	struct dentry *debug_purgelist_dentry;
+	struct dentry *debug_workqueue_dentry;
 };
 
 struct debug_buffer {
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 94cadcb..74b5283 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -61,7 +61,6 @@ static void dlm_mle_node_up(struct dlm_ctxt *dlm,
 			    struct o2nm_node *node,
 			    int idx);
 
-static void dlm_assert_master_worker(struct dlm_work_item *item, void *data);
 static int dlm_do_assert_master(struct dlm_ctxt *dlm,
 				struct dlm_lock_resource *res,
 				void *nodemap, u32 flags);
@@ -2139,7 +2138,7 @@ int dlm_dispatch_assert_master(struct dlm_ctxt *dlm,
 	return 0;
 }
 
-static void dlm_assert_master_worker(struct dlm_work_item *item, void *data)
+void dlm_assert_master_worker(struct dlm_work_item *item, void *data)
 {
 	struct dlm_ctxt *dlm = data;
 	int ret = 0;
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c
index bcb9260..d0a17c6 100644
--- a/fs/ocfs2/dlm/dlmrecovery.c
+++ b/fs/ocfs2/dlm/dlmrecovery.c
@@ -92,9 +92,6 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm,
 static void dlm_reco_ast(void *astdata);
 static void dlm_reco_bast(void *astdata, int blocked_type);
 static void dlm_reco_unlock_ast(void *astdata, enum dlm_status st);
-static void dlm_request_all_locks_worker(struct dlm_work_item *item,
-					 void *data);
-static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data);
 static int dlm_lockres_master_requery(struct dlm_ctxt *dlm,
 				      struct dlm_lock_resource *res,
 				      u8 *real_master);
@@ -862,7 +859,7 @@ int dlm_request_all_locks_handler(struct o2net_msg *msg, u32 len, void *data,
 	return 0;
 }
 
-static void dlm_request_all_locks_worker(struct dlm_work_item *item, void *data)
+void dlm_request_all_locks_worker(struct dlm_work_item *item, void *data)
 {
 	struct dlm_migratable_lockres *mres;
 	struct dlm_lock_resource *res;
@@ -1480,7 +1477,7 @@ leave:
 }
 
 
-static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data)
+void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data)
 {
 	struct dlm_ctxt *dlm;
 	struct dlm_migratable_lockres *mres;
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 07/12] ocfs2/dlm: Move struct dlm_master_list_entry to dlmcommon.h
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
                   ` (6 preceding siblings ...)
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 10/12] ocfs2/dlm: Dumps the workqueue into a debugfs file Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-05 11:08   ` Joel Becker
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 01/12] ocfs2/dlm: Rename slabcache dlm_mle_cache to o2dlm_mle Sunil Mushran
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

This patch moves some mle related definitions from dlmmaster.c
to dlmcommon.h.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
---
 fs/ocfs2/dlm/dlmcommon.h |   35 +++++++++++++++++++++++++++++++++++
 fs/ocfs2/dlm/dlmmaster.c |   37 -------------------------------------
 2 files changed, 35 insertions(+), 37 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index c772a7f..3a59fdc 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -49,6 +49,41 @@
 /* Intended to make it easier for us to switch out hash functions */
 #define dlm_lockid_hash(_n, _l) full_name_hash(_n, _l)
 
+enum dlm_mle_type {
+	DLM_MLE_BLOCK,
+	DLM_MLE_MASTER,
+	DLM_MLE_MIGRATION
+};
+
+struct dlm_lock_name {
+	u8 len;
+	u8 name[DLM_LOCKID_NAME_MAX];
+};
+
+struct dlm_master_list_entry {
+	struct list_head list;
+	struct list_head hb_events;
+	struct dlm_ctxt *dlm;
+	spinlock_t spinlock;
+	wait_queue_head_t wq;
+	atomic_t woken;
+	struct kref mle_refs;
+	int inuse;
+	unsigned long maybe_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	unsigned long vote_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	unsigned long response_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	unsigned long node_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	u8 master;
+	u8 new_master;
+	enum dlm_mle_type type;
+	struct o2hb_callback_func mle_hb_up;
+	struct o2hb_callback_func mle_hb_down;
+	union {
+		struct dlm_lock_resource *res;
+		struct dlm_lock_name name;
+	} u;
+};
+
 enum dlm_ast_type {
 	DLM_AST = 0,
 	DLM_BAST,
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 9713346..94cadcb 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -52,43 +52,6 @@
 #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_MASTER)
 #include "cluster/masklog.h"
 
-enum dlm_mle_type {
-	DLM_MLE_BLOCK,
-	DLM_MLE_MASTER,
-	DLM_MLE_MIGRATION
-};
-
-struct dlm_lock_name
-{
-	u8 len;
-	u8 name[DLM_LOCKID_NAME_MAX];
-};
-
-struct dlm_master_list_entry
-{
-	struct list_head list;
-	struct list_head hb_events;
-	struct dlm_ctxt *dlm;
-	spinlock_t spinlock;
-	wait_queue_head_t wq;
-	atomic_t woken;
-	struct kref mle_refs;
-	int inuse;
-	unsigned long maybe_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
-	unsigned long vote_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
-	unsigned long response_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
-	unsigned long node_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
-	u8 master;
-	u8 new_master;
-	enum dlm_mle_type type;
-	struct o2hb_callback_func mle_hb_up;
-	struct o2hb_callback_func mle_hb_down;
-	union {
-		struct dlm_lock_resource *res;
-		struct dlm_lock_name name;
-	} u;
-};
-
 static void dlm_mle_node_down(struct dlm_ctxt *dlm,
 			      struct dlm_master_list_entry *mle,
 			      struct o2nm_node *node,
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 01/12] ocfs2/dlm: Rename slabcache dlm_mle_cache to o2dlm_mle
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
                   ` (7 preceding siblings ...)
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 07/12] ocfs2/dlm: Move struct dlm_master_list_entry to dlmcommon.h Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 03/12] ocfs2/dlm: Link all lockres' to a tracking list Sunil Mushran
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

This patch renames dlm_mle_slabcache to prevent namespace clashes with fs/dlm.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
---
 fs/ocfs2/dlm/dlmdomain.c |    4 +++-
 fs/ocfs2/dlm/dlmmaster.c |    2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 638d2eb..2f15944 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -1787,8 +1787,10 @@ static int __init dlm_init(void)
 	dlm_print_version();
 
 	status = dlm_init_mle_cache();
-	if (status)
+	if (status) {
+		mlog(ML_ERROR, "Could not create o2dlm_mle slabcache\n");
 		return -1;
+	}
 
 	status = dlm_register_net_handlers();
 	if (status) {
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index ea6b895..90797c5 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -507,7 +507,7 @@ static void dlm_mle_node_up(struct dlm_ctxt *dlm,
 
 int dlm_init_mle_cache(void)
 {
-	dlm_mle_cache = kmem_cache_create("dlm_mle_cache",
+	dlm_mle_cache = kmem_cache_create("o2dlm_mle",
 					  sizeof(struct dlm_master_list_entry),
 					  0, SLAB_HWCACHE_ALIGN,
 					  NULL);
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 03/12] ocfs2/dlm: Link all lockres' to a tracking list
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
                   ` (8 preceding siblings ...)
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 01/12] ocfs2/dlm: Rename slabcache dlm_mle_cache to o2dlm_mle Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 06/12] ocfs2/dlm: Dumps the lockres' into a debugfs file Sunil Mushran
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 12/12] ocfs2/dlm: Fix lockname in lockres print function Sunil Mushran
  11 siblings, 0 replies; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

This patch links all the lockres' to a tracking list in dlm_ctxt.
We will use this in the upcoming patch that will walk the entire
list and to dump the lockres states to a debugfs file.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
---
 fs/ocfs2/dlm/dlmcommon.h |    4 ++++
 fs/ocfs2/dlm/dlmdomain.c |   11 +++++++++++
 fs/ocfs2/dlm/dlmmaster.c |   11 +++++++++++
 3 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index c281618..e2a2b7a 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -101,6 +101,7 @@ struct dlm_ctxt
 	struct list_head purge_list;
 	struct list_head pending_asts;
 	struct list_head pending_basts;
+	struct list_head tracking_list;
 	unsigned int purge_count;
 	spinlock_t spinlock;
 	spinlock_t ast_lock;
@@ -270,6 +271,9 @@ struct dlm_lock_resource
 	struct list_head dirty;
 	struct list_head recovering; // dlm_recovery_ctxt.resources list
 
+	/* Added during init and removed during release */
+	struct list_head tracking;	/* dlm->tracking_list */
+
 	/* unused lock resources have their last_used stamped and are
 	 * put on a list for the dlm thread to run. */
 	unsigned long    last_used;
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index c8a4e08..6b62211 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -644,6 +644,7 @@ int dlm_shutting_down(struct dlm_ctxt *dlm)
 void dlm_unregister_domain(struct dlm_ctxt *dlm)
 {
 	int leave = 0;
+	struct dlm_lock_resource *res;
 
 	spin_lock(&dlm_domain_lock);
 	BUG_ON(dlm->dlm_state != DLM_CTXT_JOINED);
@@ -673,6 +674,15 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm)
 			msleep(500);
 			mlog(0, "%s: more migration to do\n", dlm->name);
 		}
+
+		/* This list should be empty. If not, print remaining lockres */
+		if (!list_empty(&dlm->tracking_list)) {
+			mlog(ML_ERROR, "Following lockres' are still on the "
+			     "tracking list:\n");
+			list_for_each_entry(res, &dlm->tracking_list, tracking)
+				dlm_print_one_lock_resource(res);
+		}
+
 		dlm_mark_domain_leaving(dlm);
 		dlm_leave_domain(dlm);
 		dlm_complete_dlm_shutdown(dlm);
@@ -1497,6 +1507,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
 	INIT_LIST_HEAD(&dlm->reco.node_data);
 	INIT_LIST_HEAD(&dlm->purge_list);
 	INIT_LIST_HEAD(&dlm->dlm_domain_handlers);
+	INIT_LIST_HEAD(&dlm->tracking_list);
 	dlm->reco.state = 0;
 
 	INIT_LIST_HEAD(&dlm->pending_asts);
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index ac9ed31..9713346 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -639,6 +639,14 @@ static void dlm_lockres_release(struct kref *kref)
 	mlog(0, "destroying lockres %.*s\n", res->lockname.len,
 	     res->lockname.name);
 
+	if (!list_empty(&res->tracking))
+		list_del_init(&res->tracking);
+	else {
+		mlog(ML_ERROR, "Resource %.*s not on the Tracking list\n",
+		     res->lockname.len, res->lockname.name);
+		dlm_print_one_lock_resource(res);
+	}
+
 	if (!hlist_unhashed(&res->hash_node) ||
 	    !list_empty(&res->granted) ||
 	    !list_empty(&res->converting) ||
@@ -706,6 +714,7 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm,
 	INIT_LIST_HEAD(&res->dirty);
 	INIT_LIST_HEAD(&res->recovering);
 	INIT_LIST_HEAD(&res->purge);
+	INIT_LIST_HEAD(&res->tracking);
 	atomic_set(&res->asts_reserved, 0);
 	res->migration_pending = 0;
 	res->inflight_locks = 0;
@@ -721,6 +730,8 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm,
 
 	res->last_used = 0;
 
+	list_add_tail(&res->tracking, &dlm->tracking_list);
+
 	memset(res->lvb, 0, DLM_LVB_LEN);
 	memset(res->refmap, 0, sizeof(res->refmap));
 }
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 06/12] ocfs2/dlm: Dumps the lockres' into a debugfs file
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
                   ` (9 preceding siblings ...)
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 03/12] ocfs2/dlm: Link all lockres' to a tracking list Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-05 11:07   ` Joel Becker
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 12/12] ocfs2/dlm: Fix lockname in lockres print function Sunil Mushran
  11 siblings, 1 reply; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

This patch dumps all the lockres' alongwith all the locks into
a debugfs file. Useful for debugging.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
---
 fs/ocfs2/dlm/dlmdebug.c |  247 +++++++++++++++++++++++++++++++++++++++++++++++
 fs/ocfs2/dlm/dlmdebug.h |    8 ++
 2 files changed, 255 insertions(+), 0 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index 540c4f8..5afc723 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -272,8 +272,35 @@ const char *dlm_errname(enum dlm_status err)
 }
 EXPORT_SYMBOL_GPL(dlm_errname);
 
+/* NOTE: This function converts a lockname into a string. It uses knowledge
+ * of the format of the lockname that should be outside the purview of the dlm.
+ * We are adding only to make dlm debugging slightly easier.
+ *
+ * For more on lockname formats, please refer to dlmglue.c and ocfs2_lockid.h.
+ */
+static int stringify_lockname(const char *lockname, int locklen,
+			      char *buf, int len)
+{
+	int out = 0;
+	__be64 inode_blkno_be;
+
+#define OCFS2_DENTRY_LOCK_INO_START	18
+	if (*lockname == 'N') {
+		memcpy((__be64 *)&inode_blkno_be,
+		       (char *)&lockname[OCFS2_DENTRY_LOCK_INO_START],
+		       sizeof(__be64));
+		out += snprintf(buf + out, len - out, "%.*s%08x",
+				OCFS2_DENTRY_LOCK_INO_START - 1, lockname,
+				(unsigned int)be64_to_cpu(inode_blkno_be));
+	} else
+		out += snprintf(buf + out, len - out, "%.*s",
+				locklen, lockname);
+	return out;
+}
+
 #define DLM_DEBUGFS_DIR				"o2dlm"
 #define DLM_DEBUGFS_DLM_STATE			"dlm_state"
+#define DLM_DEBUGFS_LOCKING_STATE		"locking_state"
 
 #ifdef CONFIG_DEBUG_FS
 /* begin - utils funcs */
@@ -368,6 +395,213 @@ static int debug_buffer_release(struct inode *inode, struct file *file)
 }
 /* end - util funcs */
 
+/* begin - debug lockres funcs */
+static int dump_lock(struct dlm_lock *lock, int list_type, char *buf, int len)
+{
+	int out;
+
+#define DEBUG_LOCK_VERSION	1
+	spin_lock(&lock->spinlock);
+	out = snprintf(buf, len, "LOCK:%d,%d,%d,%d,%d,%d:%lld,%d,%d,%d,%d,%d,"
+		       "%d,%d,%d,%d\n",
+		       DEBUG_LOCK_VERSION,
+		       list_type, lock->ml.type, lock->ml.convert_type,
+		       lock->ml.node,
+		       dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+		       dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
+		       !list_empty(&lock->ast_list),
+		       !list_empty(&lock->bast_list),
+		       lock->ast_pending, lock->bast_pending,
+		       lock->convert_pending, lock->lock_pending,
+		       lock->cancel_pending, lock->unlock_pending,
+		       atomic_read(&lock->lock_refs.refcount));
+	spin_unlock(&lock->spinlock);
+
+	return out;
+}
+
+static int dump_lockres(struct dlm_lock_resource *res, char *buf, int len)
+{
+	struct dlm_lock *lock;
+	int i;
+	int out = 0;
+
+	out += snprintf(buf + out, len - out, "NAME:");
+	out += stringify_lockname(res->lockname.name, res->lockname.len,
+				  buf + out, len - out);
+	out += snprintf(buf + out, len - out, "\n");
+
+#define DEBUG_LRES_VERSION	1
+	out += snprintf(buf + out, len - out,
+			"LRES:%d,%d,%d,%ld,%d,%d,%d,%d,%d,%d,%d\n",
+			DEBUG_LRES_VERSION,
+			res->owner, res->state, res->last_used,
+			!list_empty(&res->purge),
+			!list_empty(&res->dirty),
+			!list_empty(&res->recovering),
+			res->inflight_locks, res->migration_pending,
+			atomic_read(&res->asts_reserved),
+			atomic_read(&res->refs.refcount));
+
+	/* refmap */
+	out += snprintf(buf + out, len - out, "RMAP:");
+	out += stringify_nodemap(res->refmap, O2NM_MAX_NODES,
+				 buf + out, len - out);
+	out += snprintf(buf + out, len - out, "\n");
+
+	/* lvb */
+	out += snprintf(buf + out, len - out, "LVBX:");
+	for (i = 0; i < DLM_LVB_LEN; i++)
+		out += snprintf(buf + out, len - out,
+					"%02x", (unsigned char)res->lvb[i]);
+	out += snprintf(buf + out, len - out, "\n");
+
+	/* granted */
+	list_for_each_entry(lock, &res->granted, list)
+		out += dump_lock(lock, 0, buf + out, len - out);
+
+	/* converting */
+	list_for_each_entry(lock, &res->converting, list)
+		out += dump_lock(lock, 1, buf + out, len - out);
+
+	/* blocked */
+	list_for_each_entry(lock, &res->blocked, list)
+		out += dump_lock(lock, 2, buf + out, len - out);
+
+	out += snprintf(buf + out, len - out, "\n");
+
+	return out;
+}
+
+static void *lockres_seq_start(struct seq_file *m, loff_t *pos)
+{
+	struct debug_lockres *dl = m->private;
+	struct dlm_ctxt *dlm = dl->dl_ctxt;
+	struct dlm_lock_resource *res = NULL;
+
+	spin_lock(&dlm->spinlock);
+
+	if (dl->dl_res) {
+		list_for_each_entry(res, &dl->dl_res->tracking, tracking) {
+			if (dl->dl_res) {
+				dlm_lockres_put(dl->dl_res);
+				dl->dl_res = NULL;
+			}
+			if (&res->tracking == &dlm->tracking_list) {
+				mlog(0, "End of list found, %p\n", res);
+				dl = NULL;
+				break;
+			}
+			dlm_lockres_get(res);
+			dl->dl_res = res;
+			break;
+		}
+	} else {
+		if (!list_empty(&dlm->tracking_list)) {
+			list_for_each_entry(res, &dlm->tracking_list, tracking)
+				break;
+			dlm_lockres_get(res);
+			dl->dl_res = res;
+		} else
+			dl = NULL;
+	}
+
+	if (dl) {
+		spin_lock(&dl->dl_res->spinlock);
+		dump_lockres(dl->dl_res, dl->dl_buf, dl->dl_len - 1);
+		spin_unlock(&dl->dl_res->spinlock);
+	}
+
+	spin_unlock(&dlm->spinlock);
+
+	return dl;
+}
+
+static void lockres_seq_stop(struct seq_file *m, void *v)
+{
+}
+
+static void *lockres_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	return NULL;
+}
+
+static int lockres_seq_show(struct seq_file *s, void *v)
+{
+	struct debug_lockres *dl = (struct debug_lockres *)v;
+
+	seq_printf(s, "%s", dl->dl_buf);
+
+	return 0;
+}
+
+static struct seq_operations debug_lockres_ops = {
+	.start =	lockres_seq_start,
+	.stop =		lockres_seq_stop,
+	.next =		lockres_seq_next,
+	.show =		lockres_seq_show,
+};
+
+static int debug_lockres_open(struct inode *inode, struct file *file)
+{
+	struct dlm_ctxt *dlm = inode->i_private;
+	int ret = -ENOMEM;
+	struct seq_file *seq;
+	struct debug_lockres *dl = NULL;
+
+	dl = kzalloc(sizeof(struct debug_lockres), GFP_KERNEL);
+	if (!dl) {
+		mlog_errno(ret);
+		goto bail;
+	}
+
+	dl->dl_len = PAGE_SIZE;
+	dl->dl_buf = kmalloc(dl->dl_len, GFP_KERNEL);
+	if (!dl->dl_buf) {
+		mlog_errno(ret);
+		goto bail;
+	}
+
+	ret = seq_open(file, &debug_lockres_ops);
+	if (ret) {
+		mlog_errno(ret);
+		goto bail;
+	}
+
+	seq = (struct seq_file *) file->private_data;
+	seq->private = dl;
+
+	dlm_grab(dlm);
+	dl->dl_ctxt = dlm;
+
+	return 0;
+bail:
+	if (dl)
+		kfree(dl->dl_buf);
+	kfree(dl);
+	return ret;
+}
+
+static int debug_lockres_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq = (struct seq_file *)file->private_data;
+	struct debug_lockres *dl = (struct debug_lockres *)seq->private;
+
+	if (dl->dl_res)
+		dlm_lockres_put(dl->dl_res);
+	dlm_put(dl->dl_ctxt);
+	kfree(dl->dl_buf);
+	return seq_release_private(inode, file);
+}
+
+static struct file_operations debug_lockres_fops = {
+	.open =		debug_lockres_open,
+	.release =	debug_lockres_release,
+	.read =		seq_read,
+	.llseek =	seq_lseek,
+};
+/* end - debug lockres funcs */
+
 /* begin - debug state funcs */
 static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
 {
@@ -547,6 +781,17 @@ int dlm_debug_init(struct dlm_ctxt *dlm)
 		goto bail;
 	}
 
+	/* for dumping lockres */
+	dc->debug_lockres_dentry =
+			debugfs_create_file(DLM_DEBUGFS_LOCKING_STATE,
+					    S_IFREG|S_IRUSR,
+					    dlm->dlm_debugfs_subroot,
+					    dlm, &debug_lockres_fops);
+	if (!dc->debug_lockres_dentry) {
+		mlog_errno(-ENOMEM);
+		goto bail;
+	}
+
 	dlm_debug_get(dc);
 	return 0;
 
@@ -563,6 +808,8 @@ void dlm_debug_shutdown(struct dlm_ctxt *dlm)
 	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
 
 	if (dc) {
+		if (dc->debug_lockres_dentry)
+			debugfs_remove(dc->debug_lockres_dentry);
 		if (dc->debug_state_dentry)
 			debugfs_remove(dc->debug_state_dentry);
 		dlm_debug_put(dc);
diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
index e6e3cd0..6676a50 100644
--- a/fs/ocfs2/dlm/dlmdebug.h
+++ b/fs/ocfs2/dlm/dlmdebug.h
@@ -28,6 +28,7 @@
 struct dlm_debug_ctxt {
 	struct kref debug_refcnt;
 	struct dentry *debug_state_dentry;
+	struct dentry *debug_lockres_dentry;
 };
 
 struct debug_buffer {
@@ -35,6 +36,13 @@ struct debug_buffer {
 	char *buf;
 };
 
+struct debug_lockres {
+	int dl_len;
+	char *dl_buf;
+	struct dlm_ctxt *dl_ctxt;
+	struct dlm_lock_resource *dl_res;
+};
+
 int dlm_debug_init(struct dlm_ctxt *dlm);
 void dlm_debug_shutdown(struct dlm_ctxt *dlm);
 
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 12/12] ocfs2/dlm: Fix lockname in lockres print function
  2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
                   ` (10 preceding siblings ...)
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 06/12] ocfs2/dlm: Dumps the lockres' into a debugfs file Sunil Mushran
@ 2008-03-04 16:50 ` Sunil Mushran
  2008-03-05 11:13   ` Joel Becker
  11 siblings, 1 reply; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

__dlm_print_one_lock_resource was printing lockname incorrectly.
Also, we now use printk directly instead of mlog as the latter prints
the line context which is not useful for this print.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
---
 fs/ocfs2/dlm/dlmdebug.c |  111 +++++++++++++++++++----------------------------
 1 files changed, 45 insertions(+), 66 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index ef91a10..baf2374 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -50,22 +50,20 @@ static struct dentry *dlm_debugfs_root = NULL;
 
 void dlm_print_one_lock_resource(struct dlm_lock_resource *res)
 {
-	mlog(ML_NOTICE, "lockres: %.*s, owner=%u, state=%u\n",
-	       res->lockname.len, res->lockname.name,
-	       res->owner, res->state);
 	spin_lock(&res->spinlock);
 	__dlm_print_one_lock_resource(res);
 	spin_unlock(&res->spinlock);
 }
 
 int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len);
+int stringify_lockname(const char *lockname, int locklen, char *buf, int len);
 
 static void dlm_print_lockres_refmap(struct dlm_lock_resource *res)
 {
 	int bit;
 	assert_spin_locked(&res->spinlock);
 
-	mlog(ML_NOTICE, "  refmap nodes: [ ");
+	printk(KERN_NOTICE "  refmap nodes: [ ");
 	bit = 0;
 	while (1) {
 		bit = find_next_bit(res->refmap, O2NM_MAX_NODES, bit);
@@ -77,62 +75,69 @@ static void dlm_print_lockres_refmap(struct dlm_lock_resource *res)
 	printk("], inflight=%u\n", res->inflight_locks);
 }
 
+static void __dlm_print_lock(struct dlm_lock *lock)
+{
+	assert_spin_locked(&lock->spinlock);
+
+	printk(KERN_NOTICE "    type=%d, conv=%d, node=%u, cookie=%u:%llu, "
+	       "ref=%u, ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c), "
+	       "pending=(conv=%c,lock=%c,cancel=%c,unlock=%c)\n",
+	       lock->ml.type, lock->ml.convert_type, lock->ml.node,
+	       dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+	       dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
+	       atomic_read(&lock->lock_refs.refcount),
+	       (list_empty(&lock->ast_list) ? 'y' : 'n'),
+	       (lock->ast_pending ? 'y' : 'n'),
+	       (list_empty(&lock->bast_list) ? 'y' : 'n'),
+	       (lock->bast_pending ? 'y' : 'n'),
+	       (lock->convert_pending ? 'y' : 'n'),
+	       (lock->lock_pending ? 'y' : 'n'),
+	       (lock->cancel_pending ? 'y' : 'n'),
+	       (lock->unlock_pending ? 'y' : 'n'));
+}
+
 void __dlm_print_one_lock_resource(struct dlm_lock_resource *res)
 {
 	struct list_head *iter2;
 	struct dlm_lock *lock;
+	char buf[DLM_LOCKID_NAME_MAX];
 
 	assert_spin_locked(&res->spinlock);
 
-	mlog(ML_NOTICE, "lockres: %.*s, owner=%u, state=%u\n",
-	       res->lockname.len, res->lockname.name,
-	       res->owner, res->state);
-	mlog(ML_NOTICE, "  last used: %lu, on purge list: %s\n",
-	     res->last_used, list_empty(&res->purge) ? "no" : "yes");
+	stringify_lockname(res->lockname.name, res->lockname.len,
+			   buf, sizeof(buf) - 1);
+	printk(KERN_NOTICE "lockres: %s, owner=%u, state=%u\n",
+	       buf, res->owner, res->state);
+	printk(KERN_NOTICE "  last used: %lu, refcnt: %u, on purge list: %s\n",
+	       res->last_used, atomic_read(&res->refs.refcount),
+	       list_empty(&res->purge) ? "no" : "yes");
+	printk(KERN_NOTICE "  on dirty list: %s, on reco list: %s, "
+	       "migrating pending: %s\n",
+	       list_empty(&res->dirty) ? "no" : "yes",
+	       list_empty(&res->recovering) ? "no" : "yes",
+	       res->migration_pending ? "yes" : "no");
+	printk(KERN_NOTICE "  inflight locks: %d, asts reserved: %d\n",
+	       res->inflight_locks, atomic_read(&res->asts_reserved));
 	dlm_print_lockres_refmap(res);
-	mlog(ML_NOTICE, "  granted queue: \n");
+	printk(KERN_NOTICE "  granted queue:\n");
 	list_for_each(iter2, &res->granted) {
 		lock = list_entry(iter2, struct dlm_lock, list);
 		spin_lock(&lock->spinlock);
-		mlog(ML_NOTICE, "    type=%d, conv=%d, node=%u, "
-		       "cookie=%u:%llu, ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c)\n", 
-		       lock->ml.type, lock->ml.convert_type, lock->ml.node, 
-		     dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
-		     dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
-		       list_empty(&lock->ast_list) ? 'y' : 'n',
-		       lock->ast_pending ? 'y' : 'n',
-		       list_empty(&lock->bast_list) ? 'y' : 'n',
-		       lock->bast_pending ? 'y' : 'n');
+		__dlm_print_lock(lock);
 		spin_unlock(&lock->spinlock);
 	}
-	mlog(ML_NOTICE, "  converting queue: \n");
+	printk(KERN_NOTICE "  converting queue:\n");
 	list_for_each(iter2, &res->converting) {
 		lock = list_entry(iter2, struct dlm_lock, list);
 		spin_lock(&lock->spinlock);
-		mlog(ML_NOTICE, "    type=%d, conv=%d, node=%u, "
-		       "cookie=%u:%llu, ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c)\n", 
-		       lock->ml.type, lock->ml.convert_type, lock->ml.node, 
-		     dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
-		     dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
-		       list_empty(&lock->ast_list) ? 'y' : 'n',
-		       lock->ast_pending ? 'y' : 'n',
-		       list_empty(&lock->bast_list) ? 'y' : 'n',
-		       lock->bast_pending ? 'y' : 'n');
+		__dlm_print_lock(lock);
 		spin_unlock(&lock->spinlock);
 	}
-	mlog(ML_NOTICE, "  blocked queue: \n");
+	printk(KERN_NOTICE "  blocked queue:\n");
 	list_for_each(iter2, &res->blocked) {
 		lock = list_entry(iter2, struct dlm_lock, list);
 		spin_lock(&lock->spinlock);
-		mlog(ML_NOTICE, "    type=%d, conv=%d, node=%u, "
-		       "cookie=%u:%llu, ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c)\n", 
-		       lock->ml.type, lock->ml.convert_type, lock->ml.node, 
-		     dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
-		     dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
-		       list_empty(&lock->ast_list) ? 'y' : 'n',
-		       lock->ast_pending ? 'y' : 'n',
-		       list_empty(&lock->bast_list) ? 'y' : 'n',
-		       lock->bast_pending ? 'y' : 'n');
+		__dlm_print_lock(lock);
 		spin_unlock(&lock->spinlock);
 	}
 }
@@ -143,31 +148,6 @@ void dlm_print_one_lock(struct dlm_lock *lockid)
 }
 EXPORT_SYMBOL_GPL(dlm_print_one_lock);
 
-#if 0
-void dlm_dump_lock_resources(struct dlm_ctxt *dlm)
-{
-	struct dlm_lock_resource *res;
-	struct hlist_node *iter;
-	struct hlist_head *bucket;
-	int i;
-
-	mlog(ML_NOTICE, "struct dlm_ctxt: %s, node=%u, key=%u\n",
-		  dlm->name, dlm->node_num, dlm->key);
-	if (!dlm || !dlm->name) {
-		mlog(ML_ERROR, "dlm=%p\n", dlm);
-		return;
-	}
-
-	spin_lock(&dlm->spinlock);
-	for (i=0; i<DLM_HASH_BUCKETS; i++) {
-		bucket = dlm_lockres_hash(dlm, i);
-		hlist_for_each_entry(res, iter, bucket, hash_node)
-			dlm_print_one_lock_resource(res);
-	}
-	spin_unlock(&dlm->spinlock);
-}
-#endif  /*  0  */
-
 void dlm_print_one_mle(struct dlm_master_list_entry *mle)
 {
 	char *buf;
@@ -291,8 +271,7 @@ EXPORT_SYMBOL_GPL(dlm_errname);
  *
  * For more on lockname formats, please refer to dlmglue.c and ocfs2_lockid.h.
  */
-static int stringify_lockname(const char *lockname, int locklen,
-			      char *buf, int len)
+int stringify_lockname(const char *lockname, int locklen, char *buf, int len)
 {
 	int out = 0;
 	__be64 inode_blkno_be;
-- 
1.5.3.6

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt
@ 2008-03-04 16:50 Sunil Mushran
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 09/12] ocfs2/dlm: Dumps the purgelist into a debugfs file Sunil Mushran
                   ` (11 more replies)
  0 siblings, 12 replies; 24+ messages in thread
From: Sunil Mushran @ 2008-03-04 16:50 UTC (permalink / raw)
  To: ocfs2-devel

The patches include the following changes:

1. Rename dlm_mle_cache to o2dlm_mle
2. Create o2dlm_lock, o2dlm_lockres and o2dlm_lockname slabcaches.
3. Add debugfs interface to allow users to dump dlm_state, locking_state, etc.

Changes suggested by Joel Becker have been made.

This patch series has been tested with the latest mainline kernel tree (2.6.25-rc3+).

Sunil

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 02/12] ocfs2/dlm: Creates slabcaches for lock and lockres
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 02/12] ocfs2/dlm: Creates slabcaches for lock and lockres Sunil Mushran
@ 2008-03-05 10:53   ` Joel Becker
  0 siblings, 0 replies; 24+ messages in thread
From: Joel Becker @ 2008-03-05 10:53 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Mar 04, 2008 at 04:49:50PM -0800, Sunil Mushran wrote:
> This patch makes the o2dlm allocate memory for lockres, lockname and lock
> structures from slabcaches rather than kmalloc. This allows us to not only
> make these allocs more efficient but also allows us to track the memory being
> consumed by these structures.
> 
> Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>

> ---
>  fs/ocfs2/dlm/dlmcommon.h |    7 +++++
>  fs/ocfs2/dlm/dlmdomain.c |   26 +++++++++++++++++--
>  fs/ocfs2/dlm/dlmlock.c   |   22 +++++++++++++++-
>  fs/ocfs2/dlm/dlmmaster.c |   61 +++++++++++++++++++++++++++++++++++++---------
>  4 files changed, 99 insertions(+), 17 deletions(-)
> 
> diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
> index 5b3607c..c281618 100644
> --- a/fs/ocfs2/dlm/dlmcommon.h
> +++ b/fs/ocfs2/dlm/dlmcommon.h
> @@ -961,9 +961,16 @@ static inline void __dlm_wait_on_lockres(struct dlm_lock_resource *res)
>  					  DLM_LOCK_RES_MIGRATING));
>  }
>  
> +/* create/destroy slab caches */
> +int dlm_init_master_caches(void);
> +void dlm_destroy_master_caches(void);
> +
> +int dlm_init_lock_cache(void);
> +void dlm_destroy_lock_cache(void);
>  
>  int dlm_init_mle_cache(void);
>  void dlm_destroy_mle_cache(void);
> +
>  void dlm_hb_event_notify_attached(struct dlm_ctxt *dlm, int idx, int node_up);
>  int dlm_drop_lockres_ref(struct dlm_ctxt *dlm,
>  			 struct dlm_lock_resource *res);
> diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
> index 2f15944..c8a4e08 100644
> --- a/fs/ocfs2/dlm/dlmdomain.c
> +++ b/fs/ocfs2/dlm/dlmdomain.c
> @@ -1789,21 +1789,41 @@ static int __init dlm_init(void)
>  	status = dlm_init_mle_cache();
>  	if (status) {
>  		mlog(ML_ERROR, "Could not create o2dlm_mle slabcache\n");
> -		return -1;
> +		goto error;
> +	}
> +
> +	status = dlm_init_master_caches();
> +	if (status) {
> +		mlog(ML_ERROR, "Could not create o2dlm_lockres and "
> +		     "o2dlm_lockname slabcaches\n");
> +		goto error;
> +	}
> +
> +	status = dlm_init_lock_cache();
> +	if (status) {
> +		mlog(ML_ERROR, "Count not create o2dlm_lock slabcache\n");
> +		goto error;
>  	}
>  
>  	status = dlm_register_net_handlers();
>  	if (status) {
> -		dlm_destroy_mle_cache();
> -		return -1;
> +		mlog(ML_ERROR, "Unable to register network handlers\n");
> +		goto error;
>  	}
>  
>  	return 0;
> +error:
> +	dlm_destroy_lock_cache();
> +	dlm_destroy_master_caches();
> +	dlm_destroy_mle_cache();
> +	return -1;
>  }
>  
>  static void __exit dlm_exit (void)
>  {
>  	dlm_unregister_net_handlers();
> +	dlm_destroy_lock_cache();
> +	dlm_destroy_master_caches();
>  	dlm_destroy_mle_cache();
>  }
>  
> diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c
> index 52578d9..e8e19eb 100644
> --- a/fs/ocfs2/dlm/dlmlock.c
> +++ b/fs/ocfs2/dlm/dlmlock.c
> @@ -53,6 +53,8 @@
>  #define MLOG_MASK_PREFIX ML_DLM
>  #include "cluster/masklog.h"
>  
> +static struct kmem_cache *dlm_lock_cache = NULL;
> +
>  static DEFINE_SPINLOCK(dlm_cookie_lock);
>  static u64 dlm_next_cookie = 1;
>  
> @@ -64,6 +66,22 @@ static void dlm_init_lock(struct dlm_lock *newlock, int type,
>  static void dlm_lock_release(struct kref *kref);
>  static void dlm_lock_detach_lockres(struct dlm_lock *lock);
>  
> +int dlm_init_lock_cache(void)
> +{
> +	dlm_lock_cache = kmem_cache_create("o2dlm_lock",
> +					   sizeof(struct dlm_lock), 0,
> +					   SLAB_HWCACHE_ALIGN, NULL);
> +	if (dlm_lock_cache == NULL)
> +		return -ENOMEM;
> +	return 0;
> +}
> +
> +void dlm_destroy_lock_cache(void)
> +{
> +	if (dlm_lock_cache)
> +		kmem_cache_destroy(dlm_lock_cache);
> +}
> +
>  /* Tell us whether we can grant a new lock request.
>   * locking:
>   *   caller needs:  res->spinlock
> @@ -353,7 +371,7 @@ static void dlm_lock_release(struct kref *kref)
>  		mlog(0, "freeing kernel-allocated lksb\n");
>  		kfree(lock->lksb);
>  	}
> -	kfree(lock);
> +	kmem_cache_free(dlm_lock_cache, lock);
>  }
>  
>  /* associate a lock with it's lockres, getting a ref on the lockres */
> @@ -412,7 +430,7 @@ struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie,
>  	struct dlm_lock *lock;
>  	int kernel_allocated = 0;
>  
> -	lock = kzalloc(sizeof(*lock), GFP_NOFS);
> +	lock = (struct dlm_lock *) kmem_cache_zalloc(dlm_lock_cache, GFP_NOFS);
>  	if (!lock)
>  		return NULL;
>  
> diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
> index 90797c5..ac9ed31 100644
> --- a/fs/ocfs2/dlm/dlmmaster.c
> +++ b/fs/ocfs2/dlm/dlmmaster.c
> @@ -216,10 +216,10 @@ EXPORT_SYMBOL_GPL(dlm_dump_all_mles);
>  
>  #endif  /*  0  */
>  
> -
> +static struct kmem_cache *dlm_lockres_cache = NULL;
> +static struct kmem_cache *dlm_lockname_cache = NULL;
>  static struct kmem_cache *dlm_mle_cache = NULL;
>  
> -
>  static void dlm_mle_release(struct kref *kref);
>  static void dlm_init_mle(struct dlm_master_list_entry *mle,
>  			enum dlm_mle_type type,
> @@ -560,6 +560,35 @@ static void dlm_mle_release(struct kref *kref)
>   * LOCK RESOURCE FUNCTIONS
>   */
>  
> +int dlm_init_master_caches(void)
> +{
> +	dlm_lockres_cache = kmem_cache_create("o2dlm_lockres",
> +					      sizeof(struct dlm_lock_resource),
> +					      0, SLAB_HWCACHE_ALIGN, NULL);
> +	if (!dlm_lockres_cache)
> +		goto bail;
> +
> +	dlm_lockname_cache = kmem_cache_create("o2dlm_lockname",
> +					       DLM_LOCKID_NAME_MAX, 0,
> +					       SLAB_HWCACHE_ALIGN, NULL);
> +	if (!dlm_lockname_cache)
> +		goto bail;
> +
> +	return 0;
> +bail:
> +	dlm_destroy_master_caches();
> +	return -ENOMEM;
> +}
> +
> +void dlm_destroy_master_caches(void)
> +{
> +	if (dlm_lockname_cache)
> +		kmem_cache_destroy(dlm_lockname_cache);
> +
> +	if (dlm_lockres_cache)
> +		kmem_cache_destroy(dlm_lockres_cache);
> +}
> +
>  static void dlm_set_lockres_owner(struct dlm_ctxt *dlm,
>  				  struct dlm_lock_resource *res,
>  				  u8 owner)
> @@ -642,9 +671,9 @@ static void dlm_lockres_release(struct kref *kref)
>  	BUG_ON(!list_empty(&res->recovering));
>  	BUG_ON(!list_empty(&res->purge));
>  
> -	kfree(res->lockname.name);
> +	kmem_cache_free(dlm_lockname_cache, (void *)res->lockname.name);
>  
> -	kfree(res);
> +	kmem_cache_free(dlm_lockres_cache, res);
>  }
>  
>  void dlm_lockres_put(struct dlm_lock_resource *res)
> @@ -700,20 +729,28 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
>  				   const char *name,
>  				   unsigned int namelen)
>  {
> -	struct dlm_lock_resource *res;
> +	struct dlm_lock_resource *res = NULL;
>  
> -	res = kmalloc(sizeof(struct dlm_lock_resource), GFP_NOFS);
> +	res = (struct dlm_lock_resource *)
> +				kmem_cache_zalloc(dlm_lockres_cache, GFP_NOFS);
>  	if (!res)
> -		return NULL;
> +		goto error;
>  
> -	res->lockname.name = kmalloc(namelen, GFP_NOFS);
> -	if (!res->lockname.name) {
> -		kfree(res);
> -		return NULL;
> -	}
> +	res->lockname.name = (char *)
> +				kmem_cache_zalloc(dlm_lockname_cache, GFP_NOFS);
> +	if (!res->lockname.name)
> +		goto error;
>  
>  	dlm_init_lockres(dlm, res, name, namelen);
>  	return res;
> +
> +error:
> +	if (res && res->lockname.name)
> +		kmem_cache_free(dlm_lockname_cache, (void *)res->lockname.name);
> +
> +	if (res)
> +		kmem_cache_free(dlm_lockres_cache, res);
> +	return NULL;
>  }
>  
>  void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
> -- 
> 1.5.3.6
> 
> 
> _______________________________________________
> Ocfs2-devel mailing list
> Ocfs2-devel@oss.oracle.com
> http://oss.oracle.com/mailman/listinfo/ocfs2-devel

-- 

"I don't know anything about music. In my line you don't have
 to."
        - Elvis Presley

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 04/12] ocfs2/dlm: Create debugfs dirs
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 04/12] ocfs2/dlm: Create debugfs dirs Sunil Mushran
@ 2008-03-05 10:55   ` Joel Becker
  2008-03-05 11:05     ` Joel Becker
  0 siblings, 1 reply; 24+ messages in thread
From: Joel Becker @ 2008-03-05 10:55 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Mar 04, 2008 at 04:49:52PM -0800, Sunil Mushran wrote:
> This patch creates the debugfs directories that will hold the
> files to be used to dump the dlm state.
> 
> Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>

> ---
>  fs/ocfs2/dlm/dlmcommon.h |    2 +
>  fs/ocfs2/dlm/dlmdebug.c  |   57 +++++++++++++++++++++++++++++++++++++++++++++-
>  fs/ocfs2/dlm/dlmdebug.h  |   34 +++++++++++++++++++++++++++
>  fs/ocfs2/dlm/dlmdomain.c |   20 ++++++++++++++++
>  4 files changed, 112 insertions(+), 1 deletions(-)
>  create mode 100644 fs/ocfs2/dlm/dlmdebug.h
> 
> diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
> index e2a2b7a..a20d093 100644
> --- a/fs/ocfs2/dlm/dlmcommon.h
> +++ b/fs/ocfs2/dlm/dlmcommon.h
> @@ -123,6 +123,8 @@ struct dlm_ctxt
>  	atomic_t remote_resources;
>  	atomic_t unknown_resources;
>  
> +	struct dentry *dlm_debugfs_subroot;
> +
>  	/* NOTE: Next three are protected by dlm_domain_lock */
>  	struct kref dlm_refs;
>  	enum dlm_ctxt_state dlm_state;
> diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
> index 64239b3..be63024 100644
> --- a/fs/ocfs2/dlm/dlmdebug.c
> +++ b/fs/ocfs2/dlm/dlmdebug.c
> @@ -30,6 +30,7 @@
>  #include <linux/utsname.h>
>  #include <linux/sysctl.h>
>  #include <linux/spinlock.h>
> +#include <linux/debugfs.h>
>  
>  #include "cluster/heartbeat.h"
>  #include "cluster/nodemanager.h"
> @@ -37,12 +38,16 @@
>  
>  #include "dlmapi.h"
>  #include "dlmcommon.h"
> -
>  #include "dlmdomain.h"
> +#include "dlmdebug.h"
>  
>  #define MLOG_MASK_PREFIX ML_DLM
>  #include "cluster/masklog.h"
>  
> +#ifdef CONFIG_DEBUG_FS
> +static struct dentry *dlm_debugfs_root = NULL;
> +#endif
> +
>  void dlm_print_one_lock_resource(struct dlm_lock_resource *res)
>  {
>  	mlog(ML_NOTICE, "lockres: %.*s, owner=%u, state=%u\n",
> @@ -266,3 +271,53 @@ const char *dlm_errname(enum dlm_status err)
>  	return dlm_errnames[err];
>  }
>  EXPORT_SYMBOL_GPL(dlm_errname);
> +
> +#define DLM_DEBUGFS_DIR				"o2dlm"
> +
> +/* subroot - domain dir */
> +int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm)
> +{
> +#ifdef CONFIG_DEBUG_FS
> +	dlm->dlm_debugfs_subroot = debugfs_create_dir(dlm->name,
> +						      dlm_debugfs_root);
> +	if (!dlm->dlm_debugfs_subroot) {
> +		mlog_errno(-ENOMEM);
> +		goto bail;
> +	}
> +
> +	return 0;
> +bail:
> +	dlm_destroy_debugfs_subroot(dlm);
> +	return -ENOMEM;
> +#endif
> +	return 0;
> +}
> +
> +void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm)
> +{
> +#ifdef CONFIG_DEBUG_FS
> +	if (dlm->dlm_debugfs_subroot)
> +		debugfs_remove(dlm->dlm_debugfs_subroot);
> +#endif
> +}
> +
> +/* debugfs root */
> +int dlm_create_debugfs_root(void)
> +{
> +#ifdef CONFIG_DEBUG_FS
> +	dlm_debugfs_root = debugfs_create_dir(DLM_DEBUGFS_DIR, NULL);
> +	if (!dlm_debugfs_root) {
> +		mlog_errno(-ENOMEM);
> +		return -ENOMEM;
> +	}
> +#endif
> +	return 0;
> +}
> +
> +void dlm_destroy_debugfs_root(void)
> +{
> +#ifdef CONFIG_DEBUG_FS
> +	if (dlm_debugfs_root)
> +		debugfs_remove(dlm_debugfs_root);
> +#endif
> +}
> diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
> new file mode 100644
> index 0000000..eb397d5
> --- /dev/null
> +++ b/fs/ocfs2/dlm/dlmdebug.h
> @@ -0,0 +1,34 @@
> +/* -*- mode: c; c-basic-offset: 8; -*-
> + * vim: noexpandtab sw=8 ts=8 sts=0:
> + *
> + * dlmdebug.h
> + *
> + * Copyright (C) 2008 Oracle.  All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This program 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 this program; if not, write to the
> + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> + * Boston, MA 021110-1307, USA.
> + *
> + */
> +
> +#ifndef DLMDEBUG_H
> +#define DLMDEBUG_H
> +
> +int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm);
> +void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm);
> +
> +int dlm_create_debugfs_root(void);
> +void dlm_destroy_debugfs_root(void);
> +
> +#endif
> diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
> index 6b62211..2fd17a4 100644
> --- a/fs/ocfs2/dlm/dlmdomain.c
> +++ b/fs/ocfs2/dlm/dlmdomain.c
> @@ -33,6 +33,7 @@
>  #include <linux/spinlock.h>
>  #include <linux/delay.h>
>  #include <linux/err.h>
> +#include <linux/debugfs.h>
>  
>  #include "cluster/heartbeat.h"
>  #include "cluster/nodemanager.h"
> @@ -42,6 +43,7 @@
>  #include "dlmcommon.h"
>  
>  #include "dlmdomain.h"
> +#include "dlmdebug.h"
>  
>  #include "dlmver.h"
>  
> @@ -298,6 +300,8 @@ static int dlm_wait_on_domain_helper(const char *domain)
>  
>  static void dlm_free_ctxt_mem(struct dlm_ctxt *dlm)
>  {
> +	dlm_destroy_debugfs_subroot(dlm);
> +
>  	if (dlm->lockres_hash)
>  		dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
>  
> @@ -1465,6 +1469,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
>  				u32 key)
>  {
>  	int i;
> +	int ret;
>  	struct dlm_ctxt *dlm = NULL;
>  
>  	dlm = kzalloc(sizeof(*dlm), GFP_KERNEL);
> @@ -1497,6 +1502,15 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
>  	dlm->key = key;
>  	dlm->node_num = o2nm_this_node();
>  
> +	ret = dlm_create_debugfs_subroot(dlm);
> +	if (ret < 0) {
> +		dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
> +		kfree(dlm->name);
> +		kfree(dlm);
> +		dlm = NULL;
> +		goto leave;
> +	}
> +
>  	spin_lock_init(&dlm->spinlock);
>  	spin_lock_init(&dlm->master_lock);
>  	spin_lock_init(&dlm->ast_lock);
> @@ -1822,8 +1836,13 @@ static int __init dlm_init(void)
>  		goto error;
>  	}
>  
> +	status = dlm_create_debugfs_root();
> +	if (status)
> +		goto error;
> +
>  	return 0;
>  error:
> +	dlm_unregister_net_handlers();
>  	dlm_destroy_lock_cache();
>  	dlm_destroy_master_caches();
>  	dlm_destroy_mle_cache();
> @@ -1832,6 +1851,7 @@ error:
>  
>  static void __exit dlm_exit (void)
>  {
> +	dlm_destroy_debugfs_root();
>  	dlm_unregister_net_handlers();
>  	dlm_destroy_lock_cache();
>  	dlm_destroy_master_caches();
> -- 
> 1.5.3.6
> 
> 
> _______________________________________________
> Ocfs2-devel mailing list
> Ocfs2-devel@oss.oracle.com
> http://oss.oracle.com/mailman/listinfo/ocfs2-devel

-- 

Life's Little Instruction Book #226

	"When someone hugs you, let them be the first to let go."

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 05/12] ocfs2/dlm: Dump the dlm state in a debugfs file
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 05/12] ocfs2/dlm: Dump the dlm state in " Sunil Mushran
@ 2008-03-05 11:05   ` Joel Becker
  0 siblings, 0 replies; 24+ messages in thread
From: Joel Becker @ 2008-03-05 11:05 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Mar 04, 2008 at 04:49:53PM -0800, Sunil Mushran wrote:
> This patch dumps the dlm state (dlm_ctxt) into a debugfs file.

> Useful for debugging.
> +/* files in subroot */
> +int dlm_debug_init(struct dlm_ctxt *dlm)
> +{
> +#ifdef CONFIG_DEBUG_FS
> +	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
> +
> +	/* for dumping dlm_ctxt */
> +	dc->debug_state_dentry = debugfs_create_file(DLM_DEBUGFS_DLM_STATE,
> +						     S_IFREG|S_IRUSR,
> +						     dlm->dlm_debugfs_subroot,
> +						     dlm, &debug_state_fops);
> +	if (!dc->debug_state_dentry) {
> +		mlog_errno(-ENOMEM);
> +		goto bail;
> +	}
> +
> +	dlm_debug_get(dc);
> +	return 0;
> +
> +bail:
> +	dlm_debug_shutdown(dlm);
> +	return -ENOMEM;
> +#endif
> +	return 0;
> +}

	Here again you could move the no-debugfs case to an inline in
dlmdebug.h.

Joel

-- 

"Time is an illusion, lunchtime doubly so."
        -Douglas Adams

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 04/12] ocfs2/dlm: Create debugfs dirs
  2008-03-05 10:55   ` Joel Becker
@ 2008-03-05 11:05     ` Joel Becker
  0 siblings, 0 replies; 24+ messages in thread
From: Joel Becker @ 2008-03-05 11:05 UTC (permalink / raw)
  To: ocfs2-devel

On Wed, Mar 05, 2008 at 10:54:59AM -0800, Joel Becker wrote:
> On Tue, Mar 04, 2008 at 04:49:52PM -0800, Sunil Mushran wrote:
> > This patch creates the debugfs directories that will hold the
> > files to be used to dump the dlm state.
> > 
> > Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
> Signed-off-by: Joel Becker <joel.becker@oracle.com>

	I take this back.  Can't you do the #ifdef in dlmdebug.h
instead?  eg:


+#ifndef DLMDEBUG_H
+#define DLMDEBUG_H
+
+#ifdef CONFIG_DEBUG_FS
+int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm);
+void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm);
+
+int dlm_create_debugfs_root(void);
+void dlm_destroy_debugfs_root(void);
+#else
+static inline int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm)
+{
+	return 0;
+}
+static void int dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm)
+{
+	return;
+}
+static inline int dlm_create_debugfs_root(void);
+{
+	return 0;
+}
+static inline int dlm_destroy_debugfs_root(void);
+{
+	return;
+}
+#endif  /* CONFIG_DEBUG_FS */
+
+#endif  /* DLMDEBUG_H */

	This allows us to leave a million #ifdefs out of dlmdebug.c -
you just wrap the *entire* debugfs bit in a giant #ifdef.  That's much
nicer to read than functions that are ifdef'd out one-by-one.
	Also, in general, can you comment your #endif lines if they are
not on the same 80x24 terminal screen as the opening #ifdef?

Joel

-- 

"I don't want to achieve immortality through my work; I want to
 achieve immortality through not dying."
        - Woody Allen

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 06/12] ocfs2/dlm: Dumps the lockres' into a debugfs file
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 06/12] ocfs2/dlm: Dumps the lockres' into a debugfs file Sunil Mushran
@ 2008-03-05 11:07   ` Joel Becker
  0 siblings, 0 replies; 24+ messages in thread
From: Joel Becker @ 2008-03-05 11:07 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Mar 04, 2008 at 04:49:54PM -0800, Sunil Mushran wrote:
> This patch dumps all the lockres' alongwith all the locks into
> a debugfs file. Useful for debugging.
> 
> Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>

> ---
>  fs/ocfs2/dlm/dlmdebug.c |  247 +++++++++++++++++++++++++++++++++++++++++++++++
>  fs/ocfs2/dlm/dlmdebug.h |    8 ++
>  2 files changed, 255 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
> index 540c4f8..5afc723 100644
> --- a/fs/ocfs2/dlm/dlmdebug.c
> +++ b/fs/ocfs2/dlm/dlmdebug.c
> @@ -272,8 +272,35 @@ const char *dlm_errname(enum dlm_status err)
>  }
>  EXPORT_SYMBOL_GPL(dlm_errname);
>  
> +/* NOTE: This function converts a lockname into a string. It uses knowledge
> + * of the format of the lockname that should be outside the purview of the dlm.
> + * We are adding only to make dlm debugging slightly easier.
> + *
> + * For more on lockname formats, please refer to dlmglue.c and ocfs2_lockid.h.
> + */
> +static int stringify_lockname(const char *lockname, int locklen,
> +			      char *buf, int len)
> +{
> +	int out = 0;
> +	__be64 inode_blkno_be;
> +
> +#define OCFS2_DENTRY_LOCK_INO_START	18
> +	if (*lockname == 'N') {
> +		memcpy((__be64 *)&inode_blkno_be,
> +		       (char *)&lockname[OCFS2_DENTRY_LOCK_INO_START],
> +		       sizeof(__be64));
> +		out += snprintf(buf + out, len - out, "%.*s%08x",
> +				OCFS2_DENTRY_LOCK_INO_START - 1, lockname,
> +				(unsigned int)be64_to_cpu(inode_blkno_be));
> +	} else
> +		out += snprintf(buf + out, len - out, "%.*s",
> +				locklen, lockname);
> +	return out;
> +}
> +
>  #define DLM_DEBUGFS_DIR				"o2dlm"
>  #define DLM_DEBUGFS_DLM_STATE			"dlm_state"
> +#define DLM_DEBUGFS_LOCKING_STATE		"locking_state"
>  
>  #ifdef CONFIG_DEBUG_FS
>  /* begin - utils funcs */
> @@ -368,6 +395,213 @@ static int debug_buffer_release(struct inode *inode, struct file *file)
>  }
>  /* end - util funcs */
>  
> +/* begin - debug lockres funcs */
> +static int dump_lock(struct dlm_lock *lock, int list_type, char *buf, int len)
> +{
> +	int out;
> +
> +#define DEBUG_LOCK_VERSION	1
> +	spin_lock(&lock->spinlock);
> +	out = snprintf(buf, len, "LOCK:%d,%d,%d,%d,%d,%d:%lld,%d,%d,%d,%d,%d,"
> +		       "%d,%d,%d,%d\n",
> +		       DEBUG_LOCK_VERSION,
> +		       list_type, lock->ml.type, lock->ml.convert_type,
> +		       lock->ml.node,
> +		       dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
> +		       dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
> +		       !list_empty(&lock->ast_list),
> +		       !list_empty(&lock->bast_list),
> +		       lock->ast_pending, lock->bast_pending,
> +		       lock->convert_pending, lock->lock_pending,
> +		       lock->cancel_pending, lock->unlock_pending,
> +		       atomic_read(&lock->lock_refs.refcount));
> +	spin_unlock(&lock->spinlock);
> +
> +	return out;
> +}
> +
> +static int dump_lockres(struct dlm_lock_resource *res, char *buf, int len)
> +{
> +	struct dlm_lock *lock;
> +	int i;
> +	int out = 0;
> +
> +	out += snprintf(buf + out, len - out, "NAME:");
> +	out += stringify_lockname(res->lockname.name, res->lockname.len,
> +				  buf + out, len - out);
> +	out += snprintf(buf + out, len - out, "\n");
> +
> +#define DEBUG_LRES_VERSION	1
> +	out += snprintf(buf + out, len - out,
> +			"LRES:%d,%d,%d,%ld,%d,%d,%d,%d,%d,%d,%d\n",
> +			DEBUG_LRES_VERSION,
> +			res->owner, res->state, res->last_used,
> +			!list_empty(&res->purge),
> +			!list_empty(&res->dirty),
> +			!list_empty(&res->recovering),
> +			res->inflight_locks, res->migration_pending,
> +			atomic_read(&res->asts_reserved),
> +			atomic_read(&res->refs.refcount));
> +
> +	/* refmap */
> +	out += snprintf(buf + out, len - out, "RMAP:");
> +	out += stringify_nodemap(res->refmap, O2NM_MAX_NODES,
> +				 buf + out, len - out);
> +	out += snprintf(buf + out, len - out, "\n");
> +
> +	/* lvb */
> +	out += snprintf(buf + out, len - out, "LVBX:");
> +	for (i = 0; i < DLM_LVB_LEN; i++)
> +		out += snprintf(buf + out, len - out,
> +					"%02x", (unsigned char)res->lvb[i]);
> +	out += snprintf(buf + out, len - out, "\n");
> +
> +	/* granted */
> +	list_for_each_entry(lock, &res->granted, list)
> +		out += dump_lock(lock, 0, buf + out, len - out);
> +
> +	/* converting */
> +	list_for_each_entry(lock, &res->converting, list)
> +		out += dump_lock(lock, 1, buf + out, len - out);
> +
> +	/* blocked */
> +	list_for_each_entry(lock, &res->blocked, list)
> +		out += dump_lock(lock, 2, buf + out, len - out);
> +
> +	out += snprintf(buf + out, len - out, "\n");
> +
> +	return out;
> +}
> +
> +static void *lockres_seq_start(struct seq_file *m, loff_t *pos)
> +{
> +	struct debug_lockres *dl = m->private;
> +	struct dlm_ctxt *dlm = dl->dl_ctxt;
> +	struct dlm_lock_resource *res = NULL;
> +
> +	spin_lock(&dlm->spinlock);
> +
> +	if (dl->dl_res) {
> +		list_for_each_entry(res, &dl->dl_res->tracking, tracking) {
> +			if (dl->dl_res) {
> +				dlm_lockres_put(dl->dl_res);
> +				dl->dl_res = NULL;
> +			}
> +			if (&res->tracking == &dlm->tracking_list) {
> +				mlog(0, "End of list found, %p\n", res);
> +				dl = NULL;
> +				break;
> +			}
> +			dlm_lockres_get(res);
> +			dl->dl_res = res;
> +			break;
> +		}
> +	} else {
> +		if (!list_empty(&dlm->tracking_list)) {
> +			list_for_each_entry(res, &dlm->tracking_list, tracking)
> +				break;
> +			dlm_lockres_get(res);
> +			dl->dl_res = res;
> +		} else
> +			dl = NULL;
> +	}
> +
> +	if (dl) {
> +		spin_lock(&dl->dl_res->spinlock);
> +		dump_lockres(dl->dl_res, dl->dl_buf, dl->dl_len - 1);
> +		spin_unlock(&dl->dl_res->spinlock);
> +	}
> +
> +	spin_unlock(&dlm->spinlock);
> +
> +	return dl;
> +}
> +
> +static void lockres_seq_stop(struct seq_file *m, void *v)
> +{
> +}
> +
> +static void *lockres_seq_next(struct seq_file *m, void *v, loff_t *pos)
> +{
> +	return NULL;
> +}
> +
> +static int lockres_seq_show(struct seq_file *s, void *v)
> +{
> +	struct debug_lockres *dl = (struct debug_lockres *)v;
> +
> +	seq_printf(s, "%s", dl->dl_buf);
> +
> +	return 0;
> +}
> +
> +static struct seq_operations debug_lockres_ops = {
> +	.start =	lockres_seq_start,
> +	.stop =		lockres_seq_stop,
> +	.next =		lockres_seq_next,
> +	.show =		lockres_seq_show,
> +};
> +
> +static int debug_lockres_open(struct inode *inode, struct file *file)
> +{
> +	struct dlm_ctxt *dlm = inode->i_private;
> +	int ret = -ENOMEM;
> +	struct seq_file *seq;
> +	struct debug_lockres *dl = NULL;
> +
> +	dl = kzalloc(sizeof(struct debug_lockres), GFP_KERNEL);
> +	if (!dl) {
> +		mlog_errno(ret);
> +		goto bail;
> +	}
> +
> +	dl->dl_len = PAGE_SIZE;
> +	dl->dl_buf = kmalloc(dl->dl_len, GFP_KERNEL);
> +	if (!dl->dl_buf) {
> +		mlog_errno(ret);
> +		goto bail;
> +	}
> +
> +	ret = seq_open(file, &debug_lockres_ops);
> +	if (ret) {
> +		mlog_errno(ret);
> +		goto bail;
> +	}
> +
> +	seq = (struct seq_file *) file->private_data;
> +	seq->private = dl;
> +
> +	dlm_grab(dlm);
> +	dl->dl_ctxt = dlm;
> +
> +	return 0;
> +bail:
> +	if (dl)
> +		kfree(dl->dl_buf);
> +	kfree(dl);
> +	return ret;
> +}
> +
> +static int debug_lockres_release(struct inode *inode, struct file *file)
> +{
> +	struct seq_file *seq = (struct seq_file *)file->private_data;
> +	struct debug_lockres *dl = (struct debug_lockres *)seq->private;
> +
> +	if (dl->dl_res)
> +		dlm_lockres_put(dl->dl_res);
> +	dlm_put(dl->dl_ctxt);
> +	kfree(dl->dl_buf);
> +	return seq_release_private(inode, file);
> +}
> +
> +static struct file_operations debug_lockres_fops = {
> +	.open =		debug_lockres_open,
> +	.release =	debug_lockres_release,
> +	.read =		seq_read,
> +	.llseek =	seq_lseek,
> +};
> +/* end - debug lockres funcs */
> +
>  /* begin - debug state funcs */
>  static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
>  {
> @@ -547,6 +781,17 @@ int dlm_debug_init(struct dlm_ctxt *dlm)
>  		goto bail;
>  	}
>  
> +	/* for dumping lockres */
> +	dc->debug_lockres_dentry =
> +			debugfs_create_file(DLM_DEBUGFS_LOCKING_STATE,
> +					    S_IFREG|S_IRUSR,
> +					    dlm->dlm_debugfs_subroot,
> +					    dlm, &debug_lockres_fops);
> +	if (!dc->debug_lockres_dentry) {
> +		mlog_errno(-ENOMEM);
> +		goto bail;
> +	}
> +
>  	dlm_debug_get(dc);
>  	return 0;
>  
> @@ -563,6 +808,8 @@ void dlm_debug_shutdown(struct dlm_ctxt *dlm)
>  	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
>  
>  	if (dc) {
> +		if (dc->debug_lockres_dentry)
> +			debugfs_remove(dc->debug_lockres_dentry);
>  		if (dc->debug_state_dentry)
>  			debugfs_remove(dc->debug_state_dentry);
>  		dlm_debug_put(dc);
> diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
> index e6e3cd0..6676a50 100644
> --- a/fs/ocfs2/dlm/dlmdebug.h
> +++ b/fs/ocfs2/dlm/dlmdebug.h
> @@ -28,6 +28,7 @@
>  struct dlm_debug_ctxt {
>  	struct kref debug_refcnt;
>  	struct dentry *debug_state_dentry;
> +	struct dentry *debug_lockres_dentry;
>  };
>  
>  struct debug_buffer {
> @@ -35,6 +36,13 @@ struct debug_buffer {
>  	char *buf;
>  };
>  
> +struct debug_lockres {
> +	int dl_len;
> +	char *dl_buf;
> +	struct dlm_ctxt *dl_ctxt;
> +	struct dlm_lock_resource *dl_res;
> +};
> +
>  int dlm_debug_init(struct dlm_ctxt *dlm);
>  void dlm_debug_shutdown(struct dlm_ctxt *dlm);
>  
> -- 
> 1.5.3.6
> 
> 
> _______________________________________________
> Ocfs2-devel mailing list
> Ocfs2-devel@oss.oracle.com
> http://oss.oracle.com/mailman/listinfo/ocfs2-devel

-- 

 The zen have a saying:
 "When you learn how to listen, ANYONE can be your teacher."

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 07/12] ocfs2/dlm: Move struct dlm_master_list_entry to dlmcommon.h
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 07/12] ocfs2/dlm: Move struct dlm_master_list_entry to dlmcommon.h Sunil Mushran
@ 2008-03-05 11:08   ` Joel Becker
  0 siblings, 0 replies; 24+ messages in thread
From: Joel Becker @ 2008-03-05 11:08 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Mar 04, 2008 at 04:49:55PM -0800, Sunil Mushran wrote:
> This patch moves some mle related definitions from dlmmaster.c
> to dlmcommon.h.
> 
> Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>

Can we add a reason the patch header?

   This patch moves some mle related definitions from dlmmaster.c to
   dlmcommon.h.  Future patches need these definitions to dump mle
   debugging information.

Something like that.

Signed-off-by: Joel Becker <joel.becker@oracle.com>

> ---
>  fs/ocfs2/dlm/dlmcommon.h |   35 +++++++++++++++++++++++++++++++++++
>  fs/ocfs2/dlm/dlmmaster.c |   37 -------------------------------------
>  2 files changed, 35 insertions(+), 37 deletions(-)
> 
> diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
> index c772a7f..3a59fdc 100644
> --- a/fs/ocfs2/dlm/dlmcommon.h
> +++ b/fs/ocfs2/dlm/dlmcommon.h
> @@ -49,6 +49,41 @@
>  /* Intended to make it easier for us to switch out hash functions */
>  #define dlm_lockid_hash(_n, _l) full_name_hash(_n, _l)
>  
> +enum dlm_mle_type {
> +	DLM_MLE_BLOCK,
> +	DLM_MLE_MASTER,
> +	DLM_MLE_MIGRATION
> +};
> +
> +struct dlm_lock_name {
> +	u8 len;
> +	u8 name[DLM_LOCKID_NAME_MAX];
> +};
> +
> +struct dlm_master_list_entry {
> +	struct list_head list;
> +	struct list_head hb_events;
> +	struct dlm_ctxt *dlm;
> +	spinlock_t spinlock;
> +	wait_queue_head_t wq;
> +	atomic_t woken;
> +	struct kref mle_refs;
> +	int inuse;
> +	unsigned long maybe_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
> +	unsigned long vote_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
> +	unsigned long response_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
> +	unsigned long node_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
> +	u8 master;
> +	u8 new_master;
> +	enum dlm_mle_type type;
> +	struct o2hb_callback_func mle_hb_up;
> +	struct o2hb_callback_func mle_hb_down;
> +	union {
> +		struct dlm_lock_resource *res;
> +		struct dlm_lock_name name;
> +	} u;
> +};
> +
>  enum dlm_ast_type {
>  	DLM_AST = 0,
>  	DLM_BAST,
> diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
> index 9713346..94cadcb 100644
> --- a/fs/ocfs2/dlm/dlmmaster.c
> +++ b/fs/ocfs2/dlm/dlmmaster.c
> @@ -52,43 +52,6 @@
>  #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_MASTER)
>  #include "cluster/masklog.h"
>  
> -enum dlm_mle_type {
> -	DLM_MLE_BLOCK,
> -	DLM_MLE_MASTER,
> -	DLM_MLE_MIGRATION
> -};
> -
> -struct dlm_lock_name
> -{
> -	u8 len;
> -	u8 name[DLM_LOCKID_NAME_MAX];
> -};
> -
> -struct dlm_master_list_entry
> -{
> -	struct list_head list;
> -	struct list_head hb_events;
> -	struct dlm_ctxt *dlm;
> -	spinlock_t spinlock;
> -	wait_queue_head_t wq;
> -	atomic_t woken;
> -	struct kref mle_refs;
> -	int inuse;
> -	unsigned long maybe_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
> -	unsigned long vote_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
> -	unsigned long response_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
> -	unsigned long node_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
> -	u8 master;
> -	u8 new_master;
> -	enum dlm_mle_type type;
> -	struct o2hb_callback_func mle_hb_up;
> -	struct o2hb_callback_func mle_hb_down;
> -	union {
> -		struct dlm_lock_resource *res;
> -		struct dlm_lock_name name;
> -	} u;
> -};
> -
>  static void dlm_mle_node_down(struct dlm_ctxt *dlm,
>  			      struct dlm_master_list_entry *mle,
>  			      struct o2nm_node *node,
> -- 
> 1.5.3.6
> 
> 
> _______________________________________________
> Ocfs2-devel mailing list
> Ocfs2-devel@oss.oracle.com
> http://oss.oracle.com/mailman/listinfo/ocfs2-devel

-- 

"Too much walking shoes worn thin.
 Too much trippin' and my soul's worn thin.
 Time to catch a ride it leaves today
 Her name is what it means.
 Too much walking shoes worn thin."

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 08/12] ocfs2/dlm: Dumps the mles into a debugfs file
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 08/12] ocfs2/dlm: Dumps the mles into a debugfs file Sunil Mushran
@ 2008-03-05 11:09   ` Joel Becker
  0 siblings, 0 replies; 24+ messages in thread
From: Joel Becker @ 2008-03-05 11:09 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Mar 04, 2008 at 04:49:56PM -0800, Sunil Mushran wrote:
> This patch dumps all mles it can fit in one page into a debugfs file.
> Useful for debugging.
> 
> Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>

> ---
>  fs/ocfs2/dlm/dlmdebug.c |  119 +++++++++++++++++++++++++++++++++++++++++++++++
>  fs/ocfs2/dlm/dlmdebug.h |    1 +
>  2 files changed, 120 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
> index 5afc723..f792af5 100644
> --- a/fs/ocfs2/dlm/dlmdebug.c
> +++ b/fs/ocfs2/dlm/dlmdebug.c
> @@ -301,6 +301,7 @@ static int stringify_lockname(const char *lockname, int locklen,
>  #define DLM_DEBUGFS_DIR				"o2dlm"
>  #define DLM_DEBUGFS_DLM_STATE			"dlm_state"
>  #define DLM_DEBUGFS_LOCKING_STATE		"locking_state"
> +#define DLM_DEBUGFS_MLE_STATE			"mle_state"
>  
>  #ifdef CONFIG_DEBUG_FS
>  /* begin - utils funcs */
> @@ -395,6 +396,112 @@ static int debug_buffer_release(struct inode *inode, struct file *file)
>  }
>  /* end - util funcs */
>  
> +/* begin - debug mle funcs */
> +static int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len)
> +{
> +	int out = 0;
> +	unsigned int namelen;
> +	const char *name;
> +	char *mle_type;
> +
> +	if (mle->type != DLM_MLE_MASTER) {
> +		namelen = mle->u.name.len;
> +		name = mle->u.name.name;
> +	} else {
> +		namelen = mle->u.res->lockname.len;
> +		name = mle->u.res->lockname.name;
> +	}
> +
> +	if (mle->type == DLM_MLE_BLOCK)
> +		mle_type = "BLK";
> +	else if (mle->type == DLM_MLE_MASTER)
> +		mle_type = "MAS";
> +	else
> +		mle_type = "MIG";
> +
> +	out += stringify_lockname(name, namelen, buf + out, len - out);
> +	out += snprintf(buf + out, len - out,
> +			"\t%3s\tmas=%3u\tnew=%3u\tevt=%1d\tuse=%1d\tref=%3d\n",
> +			mle_type, mle->master, mle->new_master,
> +			!list_empty(&mle->hb_events),
> +			!!mle->inuse,
> +			atomic_read(&mle->mle_refs.refcount));
> +
> +	out += snprintf(buf + out, len - out, "Maybe=");
> +	out += stringify_nodemap(mle->maybe_map, O2NM_MAX_NODES,
> +				 buf + out, len - out);
> +	out += snprintf(buf + out, len - out, "\n");
> +
> +	out += snprintf(buf + out, len - out, "Vote=");
> +	out += stringify_nodemap(mle->vote_map, O2NM_MAX_NODES,
> +				 buf + out, len - out);
> +	out += snprintf(buf + out, len - out, "\n");
> +
> +	out += snprintf(buf + out, len - out, "Response=");
> +	out += stringify_nodemap(mle->response_map, O2NM_MAX_NODES,
> +				 buf + out, len - out);
> +	out += snprintf(buf + out, len - out, "\n");
> +
> +	out += snprintf(buf + out, len - out, "Node=");
> +	out += stringify_nodemap(mle->node_map, O2NM_MAX_NODES,
> +				 buf + out, len - out);
> +	out += snprintf(buf + out, len - out, "\n");
> +
> +	out += snprintf(buf + out, len - out, "\n");
> +
> +	return out;
> +}
> +
> +static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
> +{
> +	struct dlm_master_list_entry *mle;
> +	int out = 0;
> +	unsigned long total = 0;
> +
> +	out += snprintf(db->buf + out, db->len - out,
> +			"Dumping MLEs for Domain: %s\n", dlm->name);
> +
> +	spin_lock(&dlm->master_lock);
> +	list_for_each_entry(mle, &dlm->master_list, list) {
> +		++total;
> +		if (db->len - out < 200)
> +			continue;
> +		out += dump_mle(mle, db->buf + out, db->len - out);
> +	}
> +	spin_unlock(&dlm->master_lock);
> +
> +	out += snprintf(db->buf + out, db->len - out,
> +			"Total on list: %ld\n", total);
> +	return out;
> +}
> +
> +static int debug_mle_open(struct inode *inode, struct file *file)
> +{
> +	struct dlm_ctxt *dlm = inode->i_private;
> +	struct debug_buffer *db;
> +
> +	db = debug_buffer_allocate();
> +	if (!db)
> +		goto bail;
> +
> +	db->len = debug_mle_print(dlm, db);
> +
> +	file->private_data = db;
> +
> +	return 0;
> +bail:
> +	return -ENOMEM;
> +}
> +
> +static struct file_operations debug_mle_fops = {
> +	.open =		debug_mle_open,
> +	.release =	debug_buffer_release,
> +	.read =		debug_buffer_read,
> +	.llseek =	debug_buffer_llseek,
> +};
> +
> +/* end - debug mle funcs */
> +
>  /* begin - debug lockres funcs */
>  static int dump_lock(struct dlm_lock *lock, int list_type, char *buf, int len)
>  {
> @@ -792,6 +899,16 @@ int dlm_debug_init(struct dlm_ctxt *dlm)
>  		goto bail;
>  	}
>  
> +	/* for dumping mles */
> +	dc->debug_mle_dentry = debugfs_create_file(DLM_DEBUGFS_MLE_STATE,
> +						   S_IFREG|S_IRUSR,
> +						   dlm->dlm_debugfs_subroot,
> +						   dlm, &debug_mle_fops);
> +	if (!dc->debug_mle_dentry) {
> +		mlog_errno(-ENOMEM);
> +		goto bail;
> +	}
> +
>  	dlm_debug_get(dc);
>  	return 0;
>  
> @@ -808,6 +925,8 @@ void dlm_debug_shutdown(struct dlm_ctxt *dlm)
>  	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
>  
>  	if (dc) {
> +		if (dc->debug_mle_dentry)
> +			debugfs_remove(dc->debug_mle_dentry);
>  		if (dc->debug_lockres_dentry)
>  			debugfs_remove(dc->debug_lockres_dentry);
>  		if (dc->debug_state_dentry)
> diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
> index 6676a50..313af2a 100644
> --- a/fs/ocfs2/dlm/dlmdebug.h
> +++ b/fs/ocfs2/dlm/dlmdebug.h
> @@ -29,6 +29,7 @@ struct dlm_debug_ctxt {
>  	struct kref debug_refcnt;
>  	struct dentry *debug_state_dentry;
>  	struct dentry *debug_lockres_dentry;
> +	struct dentry *debug_mle_dentry;
>  };
>  
>  struct debug_buffer {
> -- 
> 1.5.3.6
> 
> 
> _______________________________________________
> Ocfs2-devel mailing list
> Ocfs2-devel@oss.oracle.com
> http://oss.oracle.com/mailman/listinfo/ocfs2-devel

-- 

"The nice thing about egotists is that they don't talk about other
 people."
         - Lucille S. Harper

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 09/12] ocfs2/dlm: Dumps the purgelist into a debugfs file
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 09/12] ocfs2/dlm: Dumps the purgelist into a debugfs file Sunil Mushran
@ 2008-03-05 11:09   ` Joel Becker
  0 siblings, 0 replies; 24+ messages in thread
From: Joel Becker @ 2008-03-05 11:09 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Mar 04, 2008 at 04:49:57PM -0800, Sunil Mushran wrote:
> This patch dumps all the lockres' on the purgelist it can fit in one page
> into a debugfs file. Useful for debugging.
> 
> Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>

> ---
>  fs/ocfs2/dlm/dlmdebug.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++
>  fs/ocfs2/dlm/dlmdebug.h |    1 +
>  2 files changed, 72 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
> index f792af5..0842e1b 100644
> --- a/fs/ocfs2/dlm/dlmdebug.c
> +++ b/fs/ocfs2/dlm/dlmdebug.c
> @@ -302,6 +302,7 @@ static int stringify_lockname(const char *lockname, int locklen,
>  #define DLM_DEBUGFS_DLM_STATE			"dlm_state"
>  #define DLM_DEBUGFS_LOCKING_STATE		"locking_state"
>  #define DLM_DEBUGFS_MLE_STATE			"mle_state"
> +#define DLM_DEBUGFS_PURGE_LIST			"purge_list"
>  
>  #ifdef CONFIG_DEBUG_FS
>  /* begin - utils funcs */
> @@ -396,6 +397,63 @@ static int debug_buffer_release(struct inode *inode, struct file *file)
>  }
>  /* end - util funcs */
>  
> +/* begin - purge list funcs */
> +static int debug_purgelist_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
> +{
> +	struct dlm_lock_resource *res;
> +	int out = 0;
> +	unsigned long total = 0;
> +
> +	out += snprintf(db->buf + out, db->len - out,
> +			"Dumping Purgelist for Domain: %s\n", dlm->name);
> +
> +	spin_lock(&dlm->spinlock);
> +	list_for_each_entry(res, &dlm->purge_list, purge) {
> +		++total;
> +		if (db->len - out < 100)
> +			continue;
> +		spin_lock(&res->spinlock);
> +		out += stringify_lockname(res->lockname.name,
> +					  res->lockname.len,
> +					  db->buf + out, db->len - out);
> +		out += snprintf(db->buf + out, db->len - out, "\t%ld\n",
> +				(jiffies - res->last_used)/HZ);
> +		spin_unlock(&res->spinlock);
> +	}
> +	spin_unlock(&dlm->spinlock);
> +
> +	out += snprintf(db->buf + out, db->len - out,
> +			"Total on list: %ld\n", total);
> +
> +	return out;
> +}
> +
> +static int debug_purgelist_open(struct inode *inode, struct file *file)
> +{
> +	struct dlm_ctxt *dlm = inode->i_private;
> +	struct debug_buffer *db;
> +
> +	db = debug_buffer_allocate();
> +	if (!db)
> +		goto bail;
> +
> +	db->len = debug_purgelist_print(dlm, db);
> +
> +	file->private_data = db;
> +
> +	return 0;
> +bail:
> +	return -ENOMEM;
> +}
> +
> +static struct file_operations debug_purgelist_fops = {
> +	.open =		debug_purgelist_open,
> +	.release =	debug_buffer_release,
> +	.read =		debug_buffer_read,
> +	.llseek =	debug_buffer_llseek,
> +};
> +/* end - purge list funcs */
> +
>  /* begin - debug mle funcs */
>  static int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len)
>  {
> @@ -909,6 +967,17 @@ int dlm_debug_init(struct dlm_ctxt *dlm)
>  		goto bail;
>  	}
>  
> +	/* for dumping lockres on the purge list */
> +	dc->debug_purgelist_dentry =
> +			debugfs_create_file(DLM_DEBUGFS_PURGE_LIST,
> +					    S_IFREG|S_IRUSR,
> +					    dlm->dlm_debugfs_subroot,
> +					    dlm, &debug_purgelist_fops);
> +	if (!dc->debug_purgelist_dentry) {
> +		mlog_errno(-ENOMEM);
> +		goto bail;
> +	}
> +
>  	dlm_debug_get(dc);
>  	return 0;
>  
> @@ -925,6 +994,8 @@ void dlm_debug_shutdown(struct dlm_ctxt *dlm)
>  	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;
>  
>  	if (dc) {
> +		if (dc->debug_purgelist_dentry)
> +			debugfs_remove(dc->debug_purgelist_dentry);
>  		if (dc->debug_mle_dentry)
>  			debugfs_remove(dc->debug_mle_dentry);
>  		if (dc->debug_lockres_dentry)
> diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
> index 313af2a..974a6be 100644
> --- a/fs/ocfs2/dlm/dlmdebug.h
> +++ b/fs/ocfs2/dlm/dlmdebug.h
> @@ -30,6 +30,7 @@ struct dlm_debug_ctxt {
>  	struct dentry *debug_state_dentry;
>  	struct dentry *debug_lockres_dentry;
>  	struct dentry *debug_mle_dentry;
> +	struct dentry *debug_purgelist_dentry;
>  };
>  
>  struct debug_buffer {
> -- 
> 1.5.3.6
> 
> 
> _______________________________________________
> Ocfs2-devel mailing list
> Ocfs2-devel@oss.oracle.com
> http://oss.oracle.com/mailman/listinfo/ocfs2-devel

-- 

"In the beginning, the universe was created. This has made a lot 
 of people very angry, and is generally considered to have been a 
 bad move."
        - Douglas Adams

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 10/12] ocfs2/dlm: Dumps the workqueue into a debugfs file
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 10/12] ocfs2/dlm: Dumps the workqueue into a debugfs file Sunil Mushran
@ 2008-03-05 11:12   ` Joel Becker
  2008-03-05 11:22     ` Sunil Mushran
  0 siblings, 1 reply; 24+ messages in thread
From: Joel Becker @ 2008-03-05 11:12 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Mar 04, 2008 at 04:49:58PM -0800, Sunil Mushran wrote:
> This patch dumps all the tasks on the workqueue it can fit in one page
> into a debugfs file. Useful for debugging.
 
> +void dlm_request_all_locks_worker(struct dlm_work_item *item, void *data);
> +void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data);
> +void dlm_assert_master_worker(struct dlm_work_item *item, void *data);
<snip>
> +		if (wi->func == dlm_request_all_locks_worker) {
> +			out += snprintf(db->buf + out, db->len - out,
> +					"RequestAllLocks, "
> +					"recomaster=%d, deadnode=%d\n",
> +					wi->u.ral.reco_master,
> +					wi->u.ral.dead_node);
> +		} else if (wi->func == dlm_mig_lockres_worker) {

	There *has* to be a better way to determine what kind of worker
we have.  De-staticing functions just to compare them is pretty heavy
handed.

Joel

-- 

"Every new beginning comes from some other beginning's end."

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 12/12] ocfs2/dlm: Fix lockname in lockres print function
  2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 12/12] ocfs2/dlm: Fix lockname in lockres print function Sunil Mushran
@ 2008-03-05 11:13   ` Joel Becker
  0 siblings, 0 replies; 24+ messages in thread
From: Joel Becker @ 2008-03-05 11:13 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Mar 04, 2008 at 04:50:00PM -0800, Sunil Mushran wrote:
> __dlm_print_one_lock_resource was printing lockname incorrectly.
> Also, we now use printk directly instead of mlog as the latter prints
> the line context which is not useful for this print.
> 
> Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>

> ---
>  fs/ocfs2/dlm/dlmdebug.c |  111 +++++++++++++++++++----------------------------
>  1 files changed, 45 insertions(+), 66 deletions(-)
> 
> diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
> index ef91a10..baf2374 100644
> --- a/fs/ocfs2/dlm/dlmdebug.c
> +++ b/fs/ocfs2/dlm/dlmdebug.c
> @@ -50,22 +50,20 @@ static struct dentry *dlm_debugfs_root = NULL;
>  
>  void dlm_print_one_lock_resource(struct dlm_lock_resource *res)
>  {
> -	mlog(ML_NOTICE, "lockres: %.*s, owner=%u, state=%u\n",
> -	       res->lockname.len, res->lockname.name,
> -	       res->owner, res->state);
>  	spin_lock(&res->spinlock);
>  	__dlm_print_one_lock_resource(res);
>  	spin_unlock(&res->spinlock);
>  }
>  
>  int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len);
> +int stringify_lockname(const char *lockname, int locklen, char *buf, int len);
>  
>  static void dlm_print_lockres_refmap(struct dlm_lock_resource *res)
>  {
>  	int bit;
>  	assert_spin_locked(&res->spinlock);
>  
> -	mlog(ML_NOTICE, "  refmap nodes: [ ");
> +	printk(KERN_NOTICE "  refmap nodes: [ ");
>  	bit = 0;
>  	while (1) {
>  		bit = find_next_bit(res->refmap, O2NM_MAX_NODES, bit);
> @@ -77,62 +75,69 @@ static void dlm_print_lockres_refmap(struct dlm_lock_resource *res)
>  	printk("], inflight=%u\n", res->inflight_locks);
>  }
>  
> +static void __dlm_print_lock(struct dlm_lock *lock)
> +{
> +	assert_spin_locked(&lock->spinlock);
> +
> +	printk(KERN_NOTICE "    type=%d, conv=%d, node=%u, cookie=%u:%llu, "
> +	       "ref=%u, ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c), "
> +	       "pending=(conv=%c,lock=%c,cancel=%c,unlock=%c)\n",
> +	       lock->ml.type, lock->ml.convert_type, lock->ml.node,
> +	       dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
> +	       dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
> +	       atomic_read(&lock->lock_refs.refcount),
> +	       (list_empty(&lock->ast_list) ? 'y' : 'n'),
> +	       (lock->ast_pending ? 'y' : 'n'),
> +	       (list_empty(&lock->bast_list) ? 'y' : 'n'),
> +	       (lock->bast_pending ? 'y' : 'n'),
> +	       (lock->convert_pending ? 'y' : 'n'),
> +	       (lock->lock_pending ? 'y' : 'n'),
> +	       (lock->cancel_pending ? 'y' : 'n'),
> +	       (lock->unlock_pending ? 'y' : 'n'));
> +}
> +
>  void __dlm_print_one_lock_resource(struct dlm_lock_resource *res)
>  {
>  	struct list_head *iter2;
>  	struct dlm_lock *lock;
> +	char buf[DLM_LOCKID_NAME_MAX];
>  
>  	assert_spin_locked(&res->spinlock);
>  
> -	mlog(ML_NOTICE, "lockres: %.*s, owner=%u, state=%u\n",
> -	       res->lockname.len, res->lockname.name,
> -	       res->owner, res->state);
> -	mlog(ML_NOTICE, "  last used: %lu, on purge list: %s\n",
> -	     res->last_used, list_empty(&res->purge) ? "no" : "yes");
> +	stringify_lockname(res->lockname.name, res->lockname.len,
> +			   buf, sizeof(buf) - 1);
> +	printk(KERN_NOTICE "lockres: %s, owner=%u, state=%u\n",
> +	       buf, res->owner, res->state);
> +	printk(KERN_NOTICE "  last used: %lu, refcnt: %u, on purge list: %s\n",
> +	       res->last_used, atomic_read(&res->refs.refcount),
> +	       list_empty(&res->purge) ? "no" : "yes");
> +	printk(KERN_NOTICE "  on dirty list: %s, on reco list: %s, "
> +	       "migrating pending: %s\n",
> +	       list_empty(&res->dirty) ? "no" : "yes",
> +	       list_empty(&res->recovering) ? "no" : "yes",
> +	       res->migration_pending ? "yes" : "no");
> +	printk(KERN_NOTICE "  inflight locks: %d, asts reserved: %d\n",
> +	       res->inflight_locks, atomic_read(&res->asts_reserved));
>  	dlm_print_lockres_refmap(res);
> -	mlog(ML_NOTICE, "  granted queue: \n");
> +	printk(KERN_NOTICE "  granted queue:\n");
>  	list_for_each(iter2, &res->granted) {
>  		lock = list_entry(iter2, struct dlm_lock, list);
>  		spin_lock(&lock->spinlock);
> -		mlog(ML_NOTICE, "    type=%d, conv=%d, node=%u, "
> -		       "cookie=%u:%llu, ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c)\n", 
> -		       lock->ml.type, lock->ml.convert_type, lock->ml.node, 
> -		     dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
> -		     dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
> -		       list_empty(&lock->ast_list) ? 'y' : 'n',
> -		       lock->ast_pending ? 'y' : 'n',
> -		       list_empty(&lock->bast_list) ? 'y' : 'n',
> -		       lock->bast_pending ? 'y' : 'n');
> +		__dlm_print_lock(lock);
>  		spin_unlock(&lock->spinlock);
>  	}
> -	mlog(ML_NOTICE, "  converting queue: \n");
> +	printk(KERN_NOTICE "  converting queue:\n");
>  	list_for_each(iter2, &res->converting) {
>  		lock = list_entry(iter2, struct dlm_lock, list);
>  		spin_lock(&lock->spinlock);
> -		mlog(ML_NOTICE, "    type=%d, conv=%d, node=%u, "
> -		       "cookie=%u:%llu, ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c)\n", 
> -		       lock->ml.type, lock->ml.convert_type, lock->ml.node, 
> -		     dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
> -		     dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
> -		       list_empty(&lock->ast_list) ? 'y' : 'n',
> -		       lock->ast_pending ? 'y' : 'n',
> -		       list_empty(&lock->bast_list) ? 'y' : 'n',
> -		       lock->bast_pending ? 'y' : 'n');
> +		__dlm_print_lock(lock);
>  		spin_unlock(&lock->spinlock);
>  	}
> -	mlog(ML_NOTICE, "  blocked queue: \n");
> +	printk(KERN_NOTICE "  blocked queue:\n");
>  	list_for_each(iter2, &res->blocked) {
>  		lock = list_entry(iter2, struct dlm_lock, list);
>  		spin_lock(&lock->spinlock);
> -		mlog(ML_NOTICE, "    type=%d, conv=%d, node=%u, "
> -		       "cookie=%u:%llu, ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c)\n", 
> -		       lock->ml.type, lock->ml.convert_type, lock->ml.node, 
> -		     dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
> -		     dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
> -		       list_empty(&lock->ast_list) ? 'y' : 'n',
> -		       lock->ast_pending ? 'y' : 'n',
> -		       list_empty(&lock->bast_list) ? 'y' : 'n',
> -		       lock->bast_pending ? 'y' : 'n');
> +		__dlm_print_lock(lock);
>  		spin_unlock(&lock->spinlock);
>  	}
>  }
> @@ -143,31 +148,6 @@ void dlm_print_one_lock(struct dlm_lock *lockid)
>  }
>  EXPORT_SYMBOL_GPL(dlm_print_one_lock);
>  
> -#if 0
> -void dlm_dump_lock_resources(struct dlm_ctxt *dlm)
> -{
> -	struct dlm_lock_resource *res;
> -	struct hlist_node *iter;
> -	struct hlist_head *bucket;
> -	int i;
> -
> -	mlog(ML_NOTICE, "struct dlm_ctxt: %s, node=%u, key=%u\n",
> -		  dlm->name, dlm->node_num, dlm->key);
> -	if (!dlm || !dlm->name) {
> -		mlog(ML_ERROR, "dlm=%p\n", dlm);
> -		return;
> -	}
> -
> -	spin_lock(&dlm->spinlock);
> -	for (i=0; i<DLM_HASH_BUCKETS; i++) {
> -		bucket = dlm_lockres_hash(dlm, i);
> -		hlist_for_each_entry(res, iter, bucket, hash_node)
> -			dlm_print_one_lock_resource(res);
> -	}
> -	spin_unlock(&dlm->spinlock);
> -}
> -#endif  /*  0  */
> -
>  void dlm_print_one_mle(struct dlm_master_list_entry *mle)
>  {
>  	char *buf;
> @@ -291,8 +271,7 @@ EXPORT_SYMBOL_GPL(dlm_errname);
>   *
>   * For more on lockname formats, please refer to dlmglue.c and ocfs2_lockid.h.
>   */
> -static int stringify_lockname(const char *lockname, int locklen,
> -			      char *buf, int len)
> +int stringify_lockname(const char *lockname, int locklen, char *buf, int len)
>  {
>  	int out = 0;
>  	__be64 inode_blkno_be;
> -- 
> 1.5.3.6
> 
> 
> _______________________________________________
> Ocfs2-devel mailing list
> Ocfs2-devel@oss.oracle.com
> http://oss.oracle.com/mailman/listinfo/ocfs2-devel

-- 

"It is not the function of our government to keep the citizen from
 falling into error; it is the function of the citizen to keep the
 government from falling into error."
	- Robert H. Jackson

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Ocfs2-devel] [PATCH 10/12] ocfs2/dlm: Dumps the workqueue into a debugfs file
  2008-03-05 11:12   ` Joel Becker
@ 2008-03-05 11:22     ` Sunil Mushran
  0 siblings, 0 replies; 24+ messages in thread
From: Sunil Mushran @ 2008-03-05 11:22 UTC (permalink / raw)
  To: ocfs2-devel

Yeah... I'll remove this patch. Not that we've ever used this
except that one time.

Joel Becker wrote:
> On Tue, Mar 04, 2008 at 04:49:58PM -0800, Sunil Mushran wrote:
>   
>> This patch dumps all the tasks on the workqueue it can fit in one page
>> into a debugfs file. Useful for debugging.
>>     
>  
>   
>> +void dlm_request_all_locks_worker(struct dlm_work_item *item, void *data);
>> +void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data);
>> +void dlm_assert_master_worker(struct dlm_work_item *item, void *data);
>>     
> <snip>
>   
>> +		if (wi->func == dlm_request_all_locks_worker) {
>> +			out += snprintf(db->buf + out, db->len - out,
>> +					"RequestAllLocks, "
>> +					"recomaster=%d, deadnode=%d\n",
>> +					wi->u.ral.reco_master,
>> +					wi->u.ral.dead_node);
>> +		} else if (wi->func == dlm_mig_lockres_worker) {
>>     
>
> 	There *has* to be a better way to determine what kind of worker
> we have.  De-staticing functions just to compare them is pretty heavy
> handed.
>
> Joel
>
>   

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2008-03-05 11:22 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-04 16:50 [Ocfs2-devel] New dlm debug infrastructure - 2nd attempt Sunil Mushran
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 09/12] ocfs2/dlm: Dumps the purgelist into a debugfs file Sunil Mushran
2008-03-05 11:09   ` Joel Becker
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 11/12] ocfs2/dlm: Move dlm_print_one_mle() from dlmmaster.c to dlmdebug.c Sunil Mushran
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 02/12] ocfs2/dlm: Creates slabcaches for lock and lockres Sunil Mushran
2008-03-05 10:53   ` Joel Becker
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 08/12] ocfs2/dlm: Dumps the mles into a debugfs file Sunil Mushran
2008-03-05 11:09   ` Joel Becker
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 05/12] ocfs2/dlm: Dump the dlm state in " Sunil Mushran
2008-03-05 11:05   ` Joel Becker
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 04/12] ocfs2/dlm: Create debugfs dirs Sunil Mushran
2008-03-05 10:55   ` Joel Becker
2008-03-05 11:05     ` Joel Becker
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 10/12] ocfs2/dlm: Dumps the workqueue into a debugfs file Sunil Mushran
2008-03-05 11:12   ` Joel Becker
2008-03-05 11:22     ` Sunil Mushran
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 07/12] ocfs2/dlm: Move struct dlm_master_list_entry to dlmcommon.h Sunil Mushran
2008-03-05 11:08   ` Joel Becker
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 01/12] ocfs2/dlm: Rename slabcache dlm_mle_cache to o2dlm_mle Sunil Mushran
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 03/12] ocfs2/dlm: Link all lockres' to a tracking list Sunil Mushran
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 06/12] ocfs2/dlm: Dumps the lockres' into a debugfs file Sunil Mushran
2008-03-05 11:07   ` Joel Becker
2008-03-04 16:50 ` [Ocfs2-devel] [PATCH 12/12] ocfs2/dlm: Fix lockname in lockres print function Sunil Mushran
2008-03-05 11:13   ` Joel Becker

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.