diff options
Diffstat (limited to 'drivers/staging/lustre/lustre/ldlm/ldlm_resource.c')
-rw-r--r-- | drivers/staging/lustre/lustre/ldlm/ldlm_resource.c | 358 |
1 files changed, 198 insertions, 160 deletions
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index f750d42a7..cdb63665a 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -61,19 +61,17 @@ LIST_HEAD(ldlm_cli_active_namespace_list); /* Client namespaces that don't have any locks in them */ LIST_HEAD(ldlm_cli_inactive_namespace_list); -struct proc_dir_entry *ldlm_type_proc_dir = NULL; -static struct proc_dir_entry *ldlm_ns_proc_dir = NULL; -struct proc_dir_entry *ldlm_svc_proc_dir = NULL; - -extern unsigned int ldlm_cancel_unused_locks_before_replay; +static struct dentry *ldlm_debugfs_dir; +static struct dentry *ldlm_ns_debugfs_dir; +struct dentry *ldlm_svc_debugfs_dir; /* during debug dump certain amount of granted locks for one resource to avoid * DDOS. */ unsigned int ldlm_dump_granted_max = 256; -#if defined(CONFIG_PROC_FS) -static ssize_t lprocfs_wr_dump_ns(struct file *file, const char __user *buffer, - size_t count, loff_t *off) +static ssize_t +lprocfs_wr_dump_ns(struct file *file, const char __user *buffer, + size_t count, loff_t *off) { ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER, D_DLMTRACE); ldlm_dump_all_namespaces(LDLM_NAMESPACE_CLIENT, D_DLMTRACE); @@ -82,81 +80,82 @@ static ssize_t lprocfs_wr_dump_ns(struct file *file, const char __user *buffer, LPROC_SEQ_FOPS_WR_ONLY(ldlm, dump_ns); LPROC_SEQ_FOPS_RW_TYPE(ldlm_rw, uint); -LPROC_SEQ_FOPS_RO_TYPE(ldlm, uint); -int ldlm_proc_setup(void) +static struct lprocfs_vars ldlm_debugfs_list[] = { + { "dump_namespaces", &ldlm_dump_ns_fops, NULL, 0222 }, + { "dump_granted_max", &ldlm_rw_uint_fops, &ldlm_dump_granted_max }, + { NULL } +}; + +int ldlm_debugfs_setup(void) { int rc; - struct lprocfs_vars list[] = { - { "dump_namespaces", &ldlm_dump_ns_fops, NULL, 0222 }, - { "dump_granted_max", &ldlm_rw_uint_fops, - &ldlm_dump_granted_max }, - { "cancel_unused_locks_before_replay", &ldlm_rw_uint_fops, - &ldlm_cancel_unused_locks_before_replay }, - { NULL } }; - LASSERT(ldlm_ns_proc_dir == NULL); - - ldlm_type_proc_dir = lprocfs_register(OBD_LDLM_DEVICENAME, - proc_lustre_root, - NULL, NULL); - if (IS_ERR(ldlm_type_proc_dir)) { + + ldlm_debugfs_dir = ldebugfs_register(OBD_LDLM_DEVICENAME, + debugfs_lustre_root, + NULL, NULL); + if (IS_ERR_OR_NULL(ldlm_debugfs_dir)) { CERROR("LProcFS failed in ldlm-init\n"); - rc = PTR_ERR(ldlm_type_proc_dir); + rc = ldlm_debugfs_dir ? PTR_ERR(ldlm_debugfs_dir) : -ENOMEM; goto err; } - ldlm_ns_proc_dir = lprocfs_register("namespaces", - ldlm_type_proc_dir, - NULL, NULL); - if (IS_ERR(ldlm_ns_proc_dir)) { + ldlm_ns_debugfs_dir = ldebugfs_register("namespaces", + ldlm_debugfs_dir, + NULL, NULL); + if (IS_ERR_OR_NULL(ldlm_ns_debugfs_dir)) { CERROR("LProcFS failed in ldlm-init\n"); - rc = PTR_ERR(ldlm_ns_proc_dir); + rc = ldlm_ns_debugfs_dir ? PTR_ERR(ldlm_ns_debugfs_dir) + : -ENOMEM; goto err_type; } - ldlm_svc_proc_dir = lprocfs_register("services", - ldlm_type_proc_dir, - NULL, NULL); - if (IS_ERR(ldlm_svc_proc_dir)) { + ldlm_svc_debugfs_dir = ldebugfs_register("services", + ldlm_debugfs_dir, + NULL, NULL); + if (IS_ERR_OR_NULL(ldlm_svc_debugfs_dir)) { CERROR("LProcFS failed in ldlm-init\n"); - rc = PTR_ERR(ldlm_svc_proc_dir); + rc = ldlm_svc_debugfs_dir ? PTR_ERR(ldlm_svc_debugfs_dir) + : -ENOMEM; goto err_ns; } - rc = lprocfs_add_vars(ldlm_type_proc_dir, list, NULL); + rc = ldebugfs_add_vars(ldlm_debugfs_dir, ldlm_debugfs_list, NULL); return 0; err_ns: - lprocfs_remove(&ldlm_ns_proc_dir); + ldebugfs_remove(&ldlm_ns_debugfs_dir); err_type: - lprocfs_remove(&ldlm_type_proc_dir); + ldebugfs_remove(&ldlm_debugfs_dir); err: - ldlm_svc_proc_dir = NULL; - ldlm_type_proc_dir = NULL; - ldlm_ns_proc_dir = NULL; + ldlm_svc_debugfs_dir = NULL; + ldlm_ns_debugfs_dir = NULL; + ldlm_debugfs_dir = NULL; return rc; } -void ldlm_proc_cleanup(void) +void ldlm_debugfs_cleanup(void) { - if (ldlm_svc_proc_dir) - lprocfs_remove(&ldlm_svc_proc_dir); + if (!IS_ERR_OR_NULL(ldlm_svc_debugfs_dir)) + ldebugfs_remove(&ldlm_svc_debugfs_dir); - if (ldlm_ns_proc_dir) - lprocfs_remove(&ldlm_ns_proc_dir); + if (!IS_ERR_OR_NULL(ldlm_ns_debugfs_dir)) + ldebugfs_remove(&ldlm_ns_debugfs_dir); - if (ldlm_type_proc_dir) - lprocfs_remove(&ldlm_type_proc_dir); + if (!IS_ERR_OR_NULL(ldlm_debugfs_dir)) + ldebugfs_remove(&ldlm_debugfs_dir); - ldlm_svc_proc_dir = NULL; - ldlm_type_proc_dir = NULL; - ldlm_ns_proc_dir = NULL; + ldlm_svc_debugfs_dir = NULL; + ldlm_ns_debugfs_dir = NULL; + ldlm_debugfs_dir = NULL; } -static int lprocfs_ns_resources_seq_show(struct seq_file *m, void *v) +static ssize_t resource_count_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ldlm_namespace *ns = m->private; + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); __u64 res = 0; struct cfs_hash_bd bd; int i; @@ -164,46 +163,56 @@ static int lprocfs_ns_resources_seq_show(struct seq_file *m, void *v) /* result is not strictly consistent */ cfs_hash_for_each_bucket(ns->ns_rs_hash, &bd, i) res += cfs_hash_bd_count_get(&bd); - return lprocfs_rd_u64(m, &res); + return sprintf(buf, "%lld\n", res); } -LPROC_SEQ_FOPS_RO(lprocfs_ns_resources); +LUSTRE_RO_ATTR(resource_count); -static int lprocfs_ns_locks_seq_show(struct seq_file *m, void *v) +static ssize_t lock_count_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ldlm_namespace *ns = m->private; + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); __u64 locks; locks = lprocfs_stats_collector(ns->ns_stats, LDLM_NSS_LOCKS, LPROCFS_FIELDS_FLAGS_SUM); - return lprocfs_rd_u64(m, &locks); + return sprintf(buf, "%lld\n", locks); +} +LUSTRE_RO_ATTR(lock_count); + +static ssize_t lock_unused_count_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); + + return sprintf(buf, "%d\n", ns->ns_nr_unused); } -LPROC_SEQ_FOPS_RO(lprocfs_ns_locks); +LUSTRE_RO_ATTR(lock_unused_count); -static int lprocfs_lru_size_seq_show(struct seq_file *m, void *v) +static ssize_t lru_size_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ldlm_namespace *ns = m->private; + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); __u32 *nr = &ns->ns_max_unused; if (ns_connect_lru_resize(ns)) nr = &ns->ns_nr_unused; - return lprocfs_rd_uint(m, nr); + return sprintf(buf, "%u", *nr); } -static ssize_t lprocfs_lru_size_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t lru_size_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) { - struct ldlm_namespace *ns = ((struct seq_file *)file->private_data)->private; - char dummy[MAX_STRING_SIZE + 1]; + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); unsigned long tmp; int lru_resize; int err; - dummy[MAX_STRING_SIZE] = '\0'; - if (copy_from_user(dummy, buffer, MAX_STRING_SIZE)) - return -EFAULT; - - if (strncmp(dummy, "clear", 5) == 0) { + if (strncmp(buffer, "clear", 5) == 0) { CDEBUG(D_DLMTRACE, "dropping all unused locks from namespace %s\n", ldlm_ns_name(ns)); @@ -229,9 +238,9 @@ static ssize_t lprocfs_lru_size_seq_write(struct file *file, return count; } - err = kstrtoul(dummy, 10, &tmp); + err = kstrtoul(buffer, 10, &tmp); if (err != 0) { - CERROR("invalid value written\n"); + CERROR("lru_size: invalid value written\n"); return -EINVAL; } lru_resize = (tmp == 0); @@ -277,25 +286,56 @@ static ssize_t lprocfs_lru_size_seq_write(struct file *file, return count; } -LPROC_SEQ_FOPS(lprocfs_lru_size); +LUSTRE_RW_ATTR(lru_size); -static int lprocfs_elc_seq_show(struct seq_file *m, void *v) +static ssize_t lru_max_age_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct ldlm_namespace *ns = m->private; - unsigned int supp = ns_connect_cancelset(ns); + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); - return lprocfs_rd_uint(m, &supp); + return sprintf(buf, "%u", ns->ns_max_age); } -static ssize_t lprocfs_elc_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) +static ssize_t lru_max_age_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) { - struct ldlm_namespace *ns = ((struct seq_file *)file->private_data)->private; - unsigned int supp = -1; + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); + unsigned long tmp; + int err; + + err = kstrtoul(buffer, 10, &tmp); + if (err != 0) + return -EINVAL; + + ns->ns_max_age = tmp; + + return count; +} +LUSTRE_RW_ATTR(lru_max_age); + +static ssize_t early_lock_cancel_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); + + return sprintf(buf, "%d\n", ns_connect_cancelset(ns)); +} + +static ssize_t early_lock_cancel_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) +{ + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); + unsigned long supp = -1; int rc; - rc = lprocfs_wr_uint(file, buffer, count, &supp); + rc = kstrtoul(buffer, 10, &supp); if (rc < 0) return rc; @@ -305,91 +345,88 @@ static ssize_t lprocfs_elc_seq_write(struct file *file, ns->ns_connect_flags |= OBD_CONNECT_CANCELSET; return count; } -LPROC_SEQ_FOPS(lprocfs_elc); +LUSTRE_RW_ATTR(early_lock_cancel); + +/* These are for namespaces in /sys/fs/lustre/ldlm/namespaces/ */ +static struct attribute *ldlm_ns_attrs[] = { + &lustre_attr_resource_count.attr, + &lustre_attr_lock_count.attr, + &lustre_attr_lock_unused_count.attr, + &lustre_attr_lru_size.attr, + &lustre_attr_lru_max_age.attr, + &lustre_attr_early_lock_cancel.attr, + NULL, +}; + +static void ldlm_ns_release(struct kobject *kobj) +{ + struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace, + ns_kobj); + complete(&ns->ns_kobj_unregister); +} -void ldlm_namespace_proc_unregister(struct ldlm_namespace *ns) +static struct kobj_type ldlm_ns_ktype = { + .default_attrs = ldlm_ns_attrs, + .sysfs_ops = &lustre_sysfs_ops, + .release = ldlm_ns_release, +}; + +static void ldlm_namespace_debugfs_unregister(struct ldlm_namespace *ns) { - if (ns->ns_proc_dir_entry == NULL) + if (IS_ERR_OR_NULL(ns->ns_debugfs_entry)) CERROR("dlm namespace %s has no procfs dir?\n", ldlm_ns_name(ns)); else - lprocfs_remove(&ns->ns_proc_dir_entry); + ldebugfs_remove(&ns->ns_debugfs_entry); if (ns->ns_stats != NULL) lprocfs_free_stats(&ns->ns_stats); } -#define LDLM_NS_ADD_VAR(name, var, ops) \ - do { \ - snprintf(lock_name, MAX_STRING_SIZE, name); \ - lock_vars[0].data = var; \ - lock_vars[0].fops = ops; \ - lprocfs_add_vars(ns_pde, lock_vars, NULL); \ - } while (0) - -int ldlm_namespace_proc_register(struct ldlm_namespace *ns) +void ldlm_namespace_sysfs_unregister(struct ldlm_namespace *ns) { - struct lprocfs_vars lock_vars[2]; - char lock_name[MAX_STRING_SIZE + 1]; - struct proc_dir_entry *ns_pde; + kobject_put(&ns->ns_kobj); + wait_for_completion(&ns->ns_kobj_unregister); +} - LASSERT(ns != NULL); - LASSERT(ns->ns_rs_hash != NULL); +int ldlm_namespace_sysfs_register(struct ldlm_namespace *ns) +{ + int err; - if (ns->ns_proc_dir_entry != NULL) { - ns_pde = ns->ns_proc_dir_entry; - } else { - ns_pde = proc_mkdir(ldlm_ns_name(ns), ldlm_ns_proc_dir); - if (ns_pde == NULL) - return -ENOMEM; - ns->ns_proc_dir_entry = ns_pde; - } + ns->ns_kobj.kset = ldlm_ns_kset; + init_completion(&ns->ns_kobj_unregister); + err = kobject_init_and_add(&ns->ns_kobj, &ldlm_ns_ktype, NULL, + "%s", ldlm_ns_name(ns)); ns->ns_stats = lprocfs_alloc_stats(LDLM_NSS_LAST, 0); - if (ns->ns_stats == NULL) + if (ns->ns_stats == NULL) { + kobject_put(&ns->ns_kobj); return -ENOMEM; + } lprocfs_counter_init(ns->ns_stats, LDLM_NSS_LOCKS, LPROCFS_CNTR_AVGMINMAX, "locks", "locks"); - lock_name[MAX_STRING_SIZE] = '\0'; - - memset(lock_vars, 0, sizeof(lock_vars)); - lock_vars[0].name = lock_name; + return err; +} - LDLM_NS_ADD_VAR("resource_count", ns, &lprocfs_ns_resources_fops); - LDLM_NS_ADD_VAR("lock_count", ns, &lprocfs_ns_locks_fops); +static int ldlm_namespace_debugfs_register(struct ldlm_namespace *ns) +{ + struct dentry *ns_entry; - if (ns_is_client(ns)) { - LDLM_NS_ADD_VAR("lock_unused_count", &ns->ns_nr_unused, - &ldlm_uint_fops); - LDLM_NS_ADD_VAR("lru_size", ns, &lprocfs_lru_size_fops); - LDLM_NS_ADD_VAR("lru_max_age", &ns->ns_max_age, - &ldlm_rw_uint_fops); - LDLM_NS_ADD_VAR("early_lock_cancel", ns, &lprocfs_elc_fops); + if (!IS_ERR_OR_NULL(ns->ns_debugfs_entry)) { + ns_entry = ns->ns_debugfs_entry; } else { - LDLM_NS_ADD_VAR("ctime_age_limit", &ns->ns_ctime_age_limit, - &ldlm_rw_uint_fops); - LDLM_NS_ADD_VAR("lock_timeouts", &ns->ns_timeouts, - &ldlm_uint_fops); - LDLM_NS_ADD_VAR("max_nolock_bytes", &ns->ns_max_nolock_size, - &ldlm_rw_uint_fops); - LDLM_NS_ADD_VAR("contention_seconds", &ns->ns_contention_time, - &ldlm_rw_uint_fops); - LDLM_NS_ADD_VAR("contended_locks", &ns->ns_contended_locks, - &ldlm_rw_uint_fops); - LDLM_NS_ADD_VAR("max_parallel_ast", &ns->ns_max_parallel_ast, - &ldlm_rw_uint_fops); + ns_entry = debugfs_create_dir(ldlm_ns_name(ns), + ldlm_ns_debugfs_dir); + if (ns_entry == NULL) + return -ENOMEM; + ns->ns_debugfs_entry = ns_entry; } + return 0; } #undef MAX_STRING_SIZE -#else /* CONFIG_PROC_FS */ - -#define ldlm_namespace_proc_unregister(ns) ({; }) -#define ldlm_namespace_proc_register(ns) ({0; }) - -#endif /* CONFIG_PROC_FS */ static unsigned ldlm_res_hop_hash(struct cfs_hash *hs, const void *key, unsigned mask) @@ -590,7 +627,7 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name, break; } - OBD_ALLOC_PTR(ns); + ns = kzalloc(sizeof(*ns), GFP_NOFS); if (!ns) goto out_ref; @@ -623,25 +660,26 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name, atomic_set(&ns->ns_bref, 0); init_waitqueue_head(&ns->ns_waitq); - ns->ns_max_nolock_size = NS_DEFAULT_MAX_NOLOCK_BYTES; - ns->ns_contention_time = NS_DEFAULT_CONTENTION_SECONDS; - ns->ns_contended_locks = NS_DEFAULT_CONTENDED_LOCKS; - ns->ns_max_parallel_ast = LDLM_DEFAULT_PARALLEL_AST_LIMIT; ns->ns_nr_unused = 0; ns->ns_max_unused = LDLM_DEFAULT_LRU_SIZE; ns->ns_max_age = LDLM_DEFAULT_MAX_ALIVE; - ns->ns_ctime_age_limit = LDLM_CTIME_AGE_LIMIT; - ns->ns_timeouts = 0; ns->ns_orig_connect_flags = 0; ns->ns_connect_flags = 0; ns->ns_stopping = 0; - rc = ldlm_namespace_proc_register(ns); + + rc = ldlm_namespace_sysfs_register(ns); if (rc != 0) { - CERROR("Can't initialize ns proc, rc %d\n", rc); + CERROR("Can't initialize ns sysfs, rc %d\n", rc); goto out_hash; } + rc = ldlm_namespace_debugfs_register(ns); + if (rc != 0) { + CERROR("Can't initialize ns proc, rc %d\n", rc); + goto out_sysfs; + } + idx = ldlm_namespace_nr_read(client); rc = ldlm_pool_init(&ns->ns_pool, ns, idx, client); if (rc) { @@ -652,12 +690,14 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name, ldlm_namespace_register(ns, client); return ns; out_proc: - ldlm_namespace_proc_unregister(ns); + ldlm_namespace_debugfs_unregister(ns); +out_sysfs: + ldlm_namespace_sysfs_unregister(ns); ldlm_namespace_cleanup(ns, 0); out_hash: cfs_hash_putref(ns->ns_rs_hash); out_ns: - OBD_FREE_PTR(ns); + kfree(ns); out_ref: ldlm_put_ref(); return NULL; @@ -898,13 +938,13 @@ void ldlm_namespace_free_post(struct ldlm_namespace *ns) * Removing it after @dir may cause oops. */ ldlm_pool_fini(&ns->ns_pool); - ldlm_namespace_proc_unregister(ns); + ldlm_namespace_debugfs_unregister(ns); cfs_hash_putref(ns->ns_rs_hash); /* Namespace \a ns should be not on list at this time, otherwise * this will cause issues related to using freed \a ns in poold * thread. */ LASSERT(list_empty(&ns->ns_list_chain)); - OBD_FREE_PTR(ns); + kfree(ns); ldlm_put_ref(); } @@ -915,7 +955,7 @@ void ldlm_namespace_free_post(struct ldlm_namespace *ns) * proc1: destroy import * class_disconnect_export(grab cl_sem) -> * -> ldlm_namespace_free -> - * -> lprocfs_remove(grab _lprocfs_lock). + * -> ldebugfs_remove(grab _lprocfs_lock). * proc2: read proc info * lprocfs_fops_read(grab _lprocfs_lock) -> * -> osc_rd_active, etc(grab cl_sem). @@ -1137,10 +1177,8 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent, CERROR("%s: lvbo_init failed for resource %#llx:%#llx: rc = %d\n", ns->ns_obd->obd_name, name->name[0], name->name[1], rc); - if (res->lr_lvb_data) { - OBD_FREE(res->lr_lvb_data, res->lr_lvb_len); - res->lr_lvb_data = NULL; - } + kfree(res->lr_lvb_data); + res->lr_lvb_data = NULL; res->lr_lvb_len = rc; mutex_unlock(&res->lr_lvb_mutex); ldlm_resource_putref(res); |