kmem_cache_t *ldlm_resource_slab, *ldlm_lock_slab;
-spinlock_t ldlm_namespace_lock = SPIN_LOCK_UNLOCKED;
+DECLARE_MUTEX(ldlm_namespace_lock);
struct list_head ldlm_namespace_list = LIST_HEAD_INIT(ldlm_namespace_list);
struct proc_dir_entry *ldlm_type_proc_dir = NULL;
struct proc_dir_entry *ldlm_ns_proc_dir = NULL;
static int ldlm_proc_dump_ns(struct file *file, const char *buffer,
unsigned long count, void *data)
{
- ldlm_dump_all_namespaces();
+ ldlm_dump_all_namespaces(D_DLMTRACE);
RETURN(count);
}
ns->ns_nr_unused = 0;
ns->ns_max_unused = LDLM_DEFAULT_LRU_SIZE;
- spin_lock(&ldlm_namespace_lock);
+ down(&ldlm_namespace_lock);
list_add(&ns->ns_list_chain, &ldlm_namespace_list);
- spin_unlock(&ldlm_namespace_lock);
+ up(&ldlm_namespace_lock);
#ifdef __KERNEL__
ldlm_proc_namespace(ns);
#endif
CERROR("Resource refcount nonzero (%d) after "
"lock cleanup; forcing cleanup.\n",
atomic_read(&res->lr_refcount));
- ldlm_resource_dump(res);
+ ldlm_resource_dump(D_ERROR, res);
atomic_set(&res->lr_refcount, 1);
ldlm_resource_putref(res);
}
if (!ns)
RETURN(ELDLM_OK);
- spin_lock(&ldlm_namespace_lock);
+ down(&ldlm_namespace_lock);
list_del(&ns->ns_list_chain);
-
- spin_unlock(&ldlm_namespace_lock);
+ up(&ldlm_namespace_lock);
/* At shutdown time, don't call the cancellation callback */
ldlm_namespace_cleanup(ns, 0);
struct ldlm_resource *res;
OBD_SLAB_ALLOC(res, ldlm_resource_slab, SLAB_NOFS, sizeof *res);
- if (res == NULL) {
- LBUG();
+ if (res == NULL)
return NULL;
- }
+
memset(res, 0, sizeof(*res));
INIT_LIST_HEAD(&res->lr_children);
"type: %d", type);
res = ldlm_resource_new();
- if (!res) {
- LBUG();
+ if (!res)
RETURN(NULL);
- }
spin_lock(&ns->ns_counter_lock);
ns->ns_resources++;
}
}
- if (create)
+ if (create) {
res = ldlm_resource_add(ns, parent, name, type);
- else
+ if (res == NULL)
+ GOTO(out, NULL);
+ } else {
res = NULL;
-
+ }
if (create && ns->ns_lvbo && ns->ns_lvbo->lvbo_init) {
int rc;
CERROR("lvbo_init failed for resource "LPU64": rc %d\n",
name.name[0], rc);
} else {
+out:
l_unlock(&ns->ns_lock);
}
}
if (!list_empty(&res->lr_granted)) {
- ldlm_resource_dump(res);
+ ldlm_resource_dump(D_ERROR, res);
LBUG();
}
if (!list_empty(&res->lr_converting)) {
- ldlm_resource_dump(res);
+ ldlm_resource_dump(D_ERROR, res);
LBUG();
}
if (!list_empty(&res->lr_waiting)) {
- ldlm_resource_dump(res);
+ ldlm_resource_dump(D_ERROR, res);
LBUG();
}
if (!list_empty(&res->lr_children)) {
- ldlm_resource_dump(res);
+ ldlm_resource_dump(D_ERROR, res);
LBUG();
}
{
l_lock(&res->lr_namespace->ns_lock);
- ldlm_resource_dump(res);
+ ldlm_resource_dump(D_OTHER, res);
CDEBUG(D_OTHER, "About to add this lock:\n");
ldlm_lock_dump(D_OTHER, lock, 0);
l_lock(&res->lr_namespace->ns_lock);
- ldlm_resource_dump(res);
+ ldlm_resource_dump(D_OTHER, res);
CDEBUG(D_OTHER, "About to insert this lock after %p:\n", original);
ldlm_lock_dump(D_OTHER, new, 0);
memcpy(&desc->lr_name, &res->lr_name, sizeof(desc->lr_name));
}
-void ldlm_dump_all_namespaces(void)
+void ldlm_dump_all_namespaces(int level)
{
struct list_head *tmp;
- spin_lock(&ldlm_namespace_lock);
+ down(&ldlm_namespace_lock);
list_for_each(tmp, &ldlm_namespace_list) {
struct ldlm_namespace *ns;
ns = list_entry(tmp, struct ldlm_namespace, ns_list_chain);
- ldlm_namespace_dump(ns);
+ ldlm_namespace_dump(level, ns);
}
- spin_unlock(&ldlm_namespace_lock);
+ up(&ldlm_namespace_lock);
}
-void ldlm_namespace_dump(struct ldlm_namespace *ns)
+void ldlm_namespace_dump(int level, struct ldlm_namespace *ns)
{
struct list_head *tmp;
- unsigned int debug_save = portal_debug;
- portal_debug |= D_OTHER;
- l_lock(&ns->ns_lock);
- CDEBUG(D_OTHER, "--- Namespace: %s (rc: %d, client: %d)\n", ns->ns_name,
- ns->ns_refcount, ns->ns_client);
+ CDEBUG(level, "--- Namespace: %s (rc: %d, client: %d)\n",
+ ns->ns_name, ns->ns_refcount, ns->ns_client);
- list_for_each(tmp, &ns->ns_root_list) {
- struct ldlm_resource *res;
- res = list_entry(tmp, struct ldlm_resource, lr_childof);
+ l_lock(&ns->ns_lock);
+ if (time_after(jiffies, ns->ns_next_dump)) {
+ list_for_each(tmp, &ns->ns_root_list) {
+ struct ldlm_resource *res;
+ res = list_entry(tmp, struct ldlm_resource, lr_childof);
- /* Once we have resources with children, this should really dump
- * them recursively. */
- ldlm_resource_dump(res);
+ /* Once we have resources with children, this should
+ * really dump them recursively. */
+ ldlm_resource_dump(level, res);
+ }
+ ns->ns_next_dump = jiffies + 10 * HZ;
}
l_unlock(&ns->ns_lock);
- portal_debug = debug_save;
}
-void ldlm_resource_dump(struct ldlm_resource *res)
+void ldlm_resource_dump(int level, struct ldlm_resource *res)
{
struct list_head *tmp;
int pos;
if (RES_NAME_SIZE != 4)
LBUG();
- CDEBUG(D_OTHER, "--- Resource: %p ("LPU64"/"LPU64"/"LPU64"/"LPU64
+ CDEBUG(level, "--- Resource: %p ("LPU64"/"LPU64"/"LPU64"/"LPU64
") (rc: %d)\n", res, res->lr_name.name[0], res->lr_name.name[1],
res->lr_name.name[2], res->lr_name.name[3],
atomic_read(&res->lr_refcount));
if (!list_empty(&res->lr_granted)) {
pos = 0;
- CDEBUG(D_OTHER, "Granted locks:\n");
+ CDEBUG(level, "Granted locks:\n");
list_for_each(tmp, &res->lr_granted) {
struct ldlm_lock *lock;
lock = list_entry(tmp, struct ldlm_lock, l_res_link);
- ldlm_lock_dump(D_OTHER, lock, ++pos);
+ ldlm_lock_dump(level, lock, ++pos);
}
}
if (!list_empty(&res->lr_converting)) {
pos = 0;
- CDEBUG(D_OTHER, "Converting locks:\n");
+ CDEBUG(level, "Converting locks:\n");
list_for_each(tmp, &res->lr_converting) {
struct ldlm_lock *lock;
lock = list_entry(tmp, struct ldlm_lock, l_res_link);
- ldlm_lock_dump(D_OTHER, lock, ++pos);
+ ldlm_lock_dump(level, lock, ++pos);
}
}
if (!list_empty(&res->lr_waiting)) {
pos = 0;
- CDEBUG(D_OTHER, "Waiting locks:\n");
+ CDEBUG(level, "Waiting locks:\n");
list_for_each(tmp, &res->lr_waiting) {
struct ldlm_lock *lock;
lock = list_entry(tmp, struct ldlm_lock, l_res_link);
- ldlm_lock_dump(D_OTHER, lock, ++pos);
+ ldlm_lock_dump(level, lock, ++pos);
}
}
}