X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fobdclass%2Flprocfs_status.c;h=97d4107bfae74a43726ac7d8aa4e43bf5be82fb5;hp=0b4941fd8677d82479a73c531431dfd6d21cc41a;hb=6fe7c32906f67f43d815c884ed8a902bb2333992;hpb=6af4ec4c33cc2ea97094c5fab69d9d637d2d82d3 diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 0b4941f..97d4107 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, Whamcloud, Inc. + * Copyright (c) 2011, 2013, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -46,10 +46,7 @@ #include #include -#include -#include #include -#include #if defined(LPROCFS) @@ -60,9 +57,16 @@ CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644, #define MAX_STRING_SIZE 128 /* for bug 10866, global variable */ -CFS_DECLARE_RWSEM(_lprocfs_lock); +DECLARE_RWSEM(_lprocfs_lock); EXPORT_SYMBOL(_lprocfs_lock); +int lprocfs_single_release(struct inode *inode, struct file *file) +{ + LPROCFS_EXIT(); + return single_release(inode, file); +} +EXPORT_SYMBOL(lprocfs_single_release); + int lprocfs_seq_release(struct inode *inode, struct file *file) { LPROCFS_EXIT(); @@ -379,7 +383,7 @@ out: } EXPORT_SYMBOL(lprocfs_add_vars); -void lprocfs_remove(struct proc_dir_entry **rooth) +void lprocfs_remove_nolock(struct proc_dir_entry **rooth) { struct proc_dir_entry *root = *rooth; struct proc_dir_entry *temp = root; @@ -392,7 +396,6 @@ void lprocfs_remove(struct proc_dir_entry **rooth) parent = root->parent; LASSERT(parent != NULL); - LPROCFS_WRITE_ENTRY(); /* search vs remove race */ while (1) { while (temp->subdir != NULL) @@ -407,28 +410,17 @@ void lprocfs_remove(struct proc_dir_entry **rooth) "0x%p %s/%s len %d\n", rm_entry, temp->name, rm_entry->name, (int)strlen(rm_entry->name)); -#ifdef HAVE_PROCFS_USERS - /* if procfs uses user count to synchronize deletion of - * proc entry, there is no protection for rm_entry->data, - * then lprocfs_fops_read and lprocfs_fops_write maybe - * call proc_dir_entry->read_proc (or write_proc) with - * proc_dir_entry->data == NULL, then cause kernel Oops. - * see bug19706 for detailed information */ - - /* procfs won't free rm_entry->data if it isn't a LINK, - * and Lustre won't use rm_entry->data if it is a LINK */ - if (S_ISLNK(rm_entry->mode)) - rm_entry->data = NULL; -#else - /* Now, the rm_entry->deleted flags is protected - * by _lprocfs_lock. */ - rm_entry->data = NULL; -#endif remove_proc_entry(rm_entry->name, temp); if (temp == parent) break; } - LPROCFS_WRITE_EXIT(); +} + +void lprocfs_remove(struct proc_dir_entry **rooth) +{ + LPROCFS_WRITE_ENTRY(); /* search vs remove race */ + lprocfs_remove_nolock(rooth); + LPROCFS_WRITE_EXIT(); } EXPORT_SYMBOL(lprocfs_remove); @@ -439,6 +431,52 @@ void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent) } EXPORT_SYMBOL(lprocfs_remove_proc_entry); +void lprocfs_try_remove_proc_entry(const char *name, + struct proc_dir_entry *parent) +{ + struct proc_dir_entry *t = NULL; + struct proc_dir_entry **p; + int len, busy = 0; + + LASSERT(parent != NULL); + len = strlen(name); + + LPROCFS_WRITE_ENTRY(); + + /* lookup target name */ + for (p = &parent->subdir; *p; p = &(*p)->next) { + if ((*p)->namelen != len) + continue; + if (memcmp(name, (*p)->name, len)) + continue; + t = *p; + break; + } + + if (t) { + /* verify it's empty: do not count "num_refs" */ + for (p = &t->subdir; *p; p = &(*p)->next) { + if ((*p)->namelen != strlen("num_refs")) { + busy = 1; + break; + } + if (memcmp("num_refs", (*p)->name, + strlen("num_refs"))) { + busy = 1; + break; + } + } + } + + if (busy == 0) + lprocfs_remove_nolock(&t); + + LPROCFS_WRITE_EXIT(); + + return; +} +EXPORT_SYMBOL(lprocfs_try_remove_proc_entry); + struct proc_dir_entry *lprocfs_register(const char *name, struct proc_dir_entry *parent, struct lprocfs_vars *list, void *data) @@ -548,24 +586,11 @@ int lprocfs_rd_name(char *page, char **start, off_t off, int count, struct obd_device *dev = data; LASSERT(dev != NULL); - LASSERT(dev->obd_name != NULL); *eof = 1; return snprintf(page, count, "%s\n", dev->obd_name); } EXPORT_SYMBOL(lprocfs_rd_name); -int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - struct obd_device *obd = data; - - LASSERT(obd != NULL); - LASSERT(obd->obd_fsops != NULL); - LASSERT(obd->obd_fsops->fs_type != NULL); - return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type); -} -EXPORT_SYMBOL(lprocfs_rd_fstype); - int lprocfs_rd_blksize(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -582,21 +607,6 @@ int lprocfs_rd_blksize(char *page, char **start, off_t off, int count, } EXPORT_SYMBOL(lprocfs_rd_blksize); -int lprocfs_osd_rd_blksize(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct dt_device *dt = data; - struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); - if (!rc) { - *eof = 1; - rc = snprintf(page, count, "%d\n", - (unsigned) osfs.os_bsize); - } - return rc; -} -EXPORT_SYMBOL(lprocfs_osd_rd_blksize); - int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -619,26 +629,6 @@ int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count, } EXPORT_SYMBOL(lprocfs_rd_kbytestotal); -int lprocfs_osd_rd_kbytestotal(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct dt_device *dt = data; - struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); - if (!rc) { - __u32 blk_size = osfs.os_bsize >> 10; - __u64 result = osfs.os_blocks; - - while (blk_size >>= 1) - result <<= 1; - - *eof = 1; - rc = snprintf(page, count, LPU64"\n", result); - } - return rc; -} -EXPORT_SYMBOL(lprocfs_osd_rd_kbytestotal); - int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -661,26 +651,6 @@ int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count, } EXPORT_SYMBOL(lprocfs_rd_kbytesfree); -int lprocfs_osd_rd_kbytesfree(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct dt_device *dt = data; - struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); - if (!rc) { - __u32 blk_size = osfs.os_bsize >> 10; - __u64 result = osfs.os_bfree; - - while (blk_size >>= 1) - result <<= 1; - - *eof = 1; - rc = snprintf(page, count, LPU64"\n", result); - } - return rc; -} -EXPORT_SYMBOL(lprocfs_osd_rd_kbytesfree); - int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -703,26 +673,6 @@ int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count, } EXPORT_SYMBOL(lprocfs_rd_kbytesavail); -int lprocfs_osd_rd_kbytesavail(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct dt_device *dt = data; - struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); - if (!rc) { - __u32 blk_size = osfs.os_bsize >> 10; - __u64 result = osfs.os_bavail; - - while (blk_size >>= 1) - result <<= 1; - - *eof = 1; - rc = snprintf(page, count, LPU64"\n", result); - } - return rc; -} -EXPORT_SYMBOL(lprocfs_osd_rd_kbytesavail); - int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -740,21 +690,6 @@ int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count, } EXPORT_SYMBOL(lprocfs_rd_filestotal); -int lprocfs_osd_rd_filestotal(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct dt_device *dt = data; - struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); - if (!rc) { - *eof = 1; - rc = snprintf(page, count, LPU64"\n", osfs.os_files); - } - - return rc; -} -EXPORT_SYMBOL(lprocfs_osd_rd_filestotal); - int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -771,20 +706,6 @@ int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count, } EXPORT_SYMBOL(lprocfs_rd_filesfree); -int lprocfs_osd_rd_filesfree(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct dt_device *dt = data; - struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); - if (!rc) { - *eof = 1; - rc = snprintf(page, count, LPU64"\n", osfs.os_ffree); - } - return rc; -} -EXPORT_SYMBOL(lprocfs_osd_rd_filesfree); - int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -833,54 +754,41 @@ EXPORT_SYMBOL(lprocfs_rd_conn_uuid); /** add up per-cpu counters */ void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, - struct lprocfs_counter *cnt) + struct lprocfs_counter *cnt) { - unsigned int num_entry; - struct lprocfs_counter t; - struct lprocfs_counter *percpu_cntr; - int centry; - int i; - unsigned long flags = 0; + unsigned int num_entry; + struct lprocfs_counter *percpu_cntr; + struct lprocfs_counter_header *cntr_header; + int i; + unsigned long flags = 0; - memset(cnt, 0, sizeof(*cnt)); + memset(cnt, 0, sizeof(*cnt)); - if (stats == NULL) { - /* set count to 1 to avoid divide-by-zero errs in callers */ - cnt->lc_count = 1; - return; - } + if (stats == NULL) { + /* set count to 1 to avoid divide-by-zero errs in callers */ + cnt->lc_count = 1; + return; + } - cnt->lc_min = LC_MIN_INIT; + cnt->lc_min = LC_MIN_INIT; num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags); for (i = 0; i < num_entry; i++) { if (stats->ls_percpu[i] == NULL) continue; - percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx]; - - do { - centry = cfs_atomic_read(&percpu_cntr-> \ - lc_cntl.la_entry); - t.lc_count = percpu_cntr->lc_count; - t.lc_sum = percpu_cntr->lc_sum; - t.lc_min = percpu_cntr->lc_min; - t.lc_max = percpu_cntr->lc_max; - t.lc_sumsquare = percpu_cntr->lc_sumsquare; - } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \ - la_entry) && - centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \ - la_exit)); - cnt->lc_count += t.lc_count; - cnt->lc_sum += t.lc_sum; - if (t.lc_min < cnt->lc_min) - cnt->lc_min = t.lc_min; - if (t.lc_max > cnt->lc_max) - cnt->lc_max = t.lc_max; - cnt->lc_sumsquare += t.lc_sumsquare; - } + cntr_header = &stats->ls_cnt_header[idx]; + percpu_cntr = lprocfs_stats_counter_get(stats, i, idx); + + cnt->lc_count += percpu_cntr->lc_count; + cnt->lc_sum += percpu_cntr->lc_sum; + if (percpu_cntr->lc_min < cnt->lc_min) + cnt->lc_min = percpu_cntr->lc_min; + if (percpu_cntr->lc_max > cnt->lc_max) + cnt->lc_max = percpu_cntr->lc_max; + cnt->lc_sumsquare += percpu_cntr->lc_sumsquare; + } - cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units; lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags); } EXPORT_SYMBOL(lprocfs_stats_collect); @@ -952,6 +860,13 @@ static const char *obd_connect_names[] = { "umask", "einprogress", "grant_param", + "flock_owner", + "lvb_type", + "nanoseconds_times", + "lightweight_conn", + "short_io", + "pingless", + "unknown", NULL }; @@ -976,11 +891,15 @@ EXPORT_SYMBOL(obd_connect_flags2str); int lprocfs_rd_import(char *page, char **start, off_t off, int count, int *eof, void *data) { - struct lprocfs_counter ret; - struct obd_device *obd = (struct obd_device *)data; - struct obd_import *imp; - struct obd_import_conn *conn; - int i, j, k, rw = 0; + struct lprocfs_counter ret; + struct lprocfs_counter_header *header; + struct obd_device *obd = (struct obd_device *)data; + struct obd_import *imp; + struct obd_import_conn *conn; + int i; + int j; + int k; + int rw = 0; LASSERT(obd != NULL); LPROCFS_CLIMP_CHECK(obd); @@ -1010,7 +929,7 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count, "]\n" " connection:\n" " failover_nids: ["); - cfs_spin_lock(&imp->imp_lock); + spin_lock(&imp->imp_lock); j = 0; cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) { i += snprintf(page + i, count - i, "%s%s", j ? ", " : "", @@ -1028,8 +947,12 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count, imp->imp_conn_cnt, imp->imp_generation, cfs_atomic_read(&imp->imp_inval_count)); - cfs_spin_unlock(&imp->imp_lock); + spin_unlock(&imp->imp_lock); + if (obd->obd_svc_stats == NULL) + goto out_climp; + + header = &obd->obd_svc_stats->ls_cnt_header[PTLRPC_REQWAIT_CNTR]; lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret); if (ret.lc_count != 0) { /* first argument to do_div MUST be __u64 */ @@ -1047,7 +970,7 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count, cfs_atomic_read(&imp->imp_inflight), cfs_atomic_read(&imp->imp_unregistering), cfs_atomic_read(&imp->imp_timeouts), - ret.lc_sum, ret.lc_units); + ret.lc_sum, header->lc_units); k = 0; for(j = 0; j < IMP_AT_MAX_PORTALS; j++) { @@ -1090,6 +1013,7 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count, } k = (int)ret.lc_sum; j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES; + header = &obd->obd_svc_stats->ls_cnt_header[j]; lprocfs_stats_collect(obd->obd_svc_stats, j, &ret); if (ret.lc_sum > 0 && ret.lc_count != 0) { /* first argument to do_div MUST be __u64 */ @@ -1098,7 +1022,7 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count, ret.lc_sum = sum; i += snprintf(page + i, count - i, " %s_per_rpc: "LPU64"\n", - ret.lc_units, ret.lc_sum); + header->lc_units, ret.lc_sum); j = (int)ret.lc_sum; if (j > 0) i += snprintf(page + i, count - i, @@ -1107,6 +1031,7 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count, } } +out_climp: LPROCFS_CLIMP_EXIT(obd); return i; } @@ -1288,9 +1213,8 @@ EXPORT_SYMBOL(lprocfs_obd_cleanup); static void lprocfs_free_client_stats(struct nid_stat *client_stat) { - CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat, - client_stat->nid_proc, client_stat->nid_stats, - client_stat->nid_brw_stats); + CDEBUG(D_CONFIG, "stat %p - data %p/%p\n", client_stat, + client_stat->nid_proc, client_stat->nid_stats); LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0, "nid %s:count %d\n", libcfs_nid2str(client_stat->nid), @@ -1302,9 +1226,6 @@ static void lprocfs_free_client_stats(struct nid_stat *client_stat) if (client_stat->nid_stats) lprocfs_free_stats(&client_stat->nid_stats); - if (client_stat->nid_brw_stats) - OBD_FREE_PTR(client_stat->nid_brw_stats); - if (client_stat->nid_ldlm_stats) lprocfs_free_stats(&client_stat->nid_ldlm_stats); @@ -1335,9 +1256,10 @@ EXPORT_SYMBOL(lprocfs_free_per_client_stats); struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num, enum lprocfs_stats_flags flags) { - struct lprocfs_stats *stats; - unsigned int percpusize; - unsigned int num_entry; + struct lprocfs_stats *stats; + unsigned int num_entry; + unsigned int percpusize = 0; + int i; if (num == 0) return NULL; @@ -1348,31 +1270,42 @@ struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num, if (flags & LPROCFS_STATS_FLAG_NOPERCPU) num_entry = 1; else - num_entry = cfs_num_possible_cpus() + 1; + num_entry = cfs_num_possible_cpus(); /* alloc percpu pointers for all possible cpu slots */ - OBD_ALLOC(stats, offsetof(struct lprocfs_stats, ls_percpu[num_entry])); + LIBCFS_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_entry])); if (stats == NULL) return NULL; stats->ls_num = num; - stats->ls_biggest_alloc_num = 1; stats->ls_flags = flags; - cfs_spin_lock_init(&stats->ls_lock); - - percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]); - if (num_entry > 1) - percpusize = CFS_L1_CACHE_ALIGN(percpusize); - - /* for no percpu area, the 0th entry is for real use, - * for percpu area, the 0th entry is for intialized entry template */ - OBD_ALLOC(stats->ls_percpu[0], percpusize); - if (stats->ls_percpu[0] == NULL) { - OBD_FREE(stats, - offsetof(struct lprocfs_stats, ls_percpu[num_entry])); - stats = NULL; + spin_lock_init(&stats->ls_lock); + + /* alloc num of counter headers */ + LIBCFS_ALLOC(stats->ls_cnt_header, + stats->ls_num * sizeof(struct lprocfs_counter_header)); + if (stats->ls_cnt_header == NULL) + goto fail; + + if ((flags & LPROCFS_STATS_FLAG_NOPERCPU) != 0) { + /* contains only one set counters */ + percpusize = lprocfs_stats_counter_size(stats); + LIBCFS_ALLOC_ATOMIC(stats->ls_percpu[0], percpusize); + if (stats->ls_percpu[0] == NULL) + goto fail; + stats->ls_biggest_alloc_num = 1; + } else if ((flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) { + /* alloc all percpu data, currently only obd_memory use this */ + for (i = 0; i < num_entry; ++i) + if (lprocfs_stats_alloc_one(stats, i) < 0) + goto fail; } + return stats; + +fail: + lprocfs_free_stats(&stats); + return NULL; } EXPORT_SYMBOL(lprocfs_alloc_stats); @@ -1390,25 +1323,27 @@ void lprocfs_free_stats(struct lprocfs_stats **statsh) if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) num_entry = 1; else - num_entry = cfs_num_possible_cpus() + 1; + num_entry = cfs_num_possible_cpus(); - percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]); - if (num_entry > 1) - percpusize = CFS_L1_CACHE_ALIGN(percpusize); + percpusize = lprocfs_stats_counter_size(stats); for (i = 0; i < num_entry; i++) if (stats->ls_percpu[i] != NULL) - OBD_FREE(stats->ls_percpu[i], percpusize); - OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_entry])); + LIBCFS_FREE(stats->ls_percpu[i], percpusize); + if (stats->ls_cnt_header != NULL) + LIBCFS_FREE(stats->ls_cnt_header, stats->ls_num * + sizeof(struct lprocfs_counter_header)); + LIBCFS_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_entry])); } EXPORT_SYMBOL(lprocfs_free_stats); void lprocfs_clear_stats(struct lprocfs_stats *stats) { - struct lprocfs_counter *percpu_cntr; - int i; - int j; - unsigned int num_entry; - unsigned long flags = 0; + struct lprocfs_counter *percpu_cntr; + struct lprocfs_counter_header *header; + int i; + int j; + unsigned int num_entry; + unsigned long flags = 0; num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags); @@ -1416,14 +1351,15 @@ void lprocfs_clear_stats(struct lprocfs_stats *stats) if (stats->ls_percpu[i] == NULL) continue; for (j = 0; j < stats->ls_num; j++) { - percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j]; - cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry); - percpu_cntr->lc_count = 0; - percpu_cntr->lc_sum = 0; - percpu_cntr->lc_min = LC_MIN_INIT; - percpu_cntr->lc_max = 0; - percpu_cntr->lc_sumsquare = 0; - cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit); + header = &stats->ls_cnt_header[j]; + percpu_cntr = lprocfs_stats_counter_get(stats, i, j); + percpu_cntr->lc_count = 0; + percpu_cntr->lc_min = LC_MIN_INIT; + percpu_cntr->lc_max = 0; + percpu_cntr->lc_sumsquare = 0; + percpu_cntr->lc_sum = 0; + if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) + percpu_cntr->lc_sum_irq = 0; } } @@ -1444,10 +1380,9 @@ static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf, static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos) { - struct lprocfs_stats *stats = p->private; - /* return 1st cpu location */ - return (*pos >= stats->ls_num) ? NULL : - &(stats->ls_percpu[0]->lp_cntr[*pos]); + struct lprocfs_stats *stats = p->private; + + return (*pos < stats->ls_num) ? pos : NULL; } static void lprocfs_stats_seq_stop(struct seq_file *p, void *v) @@ -1456,61 +1391,61 @@ static void lprocfs_stats_seq_stop(struct seq_file *p, void *v) static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos) { - struct lprocfs_stats *stats = p->private; - ++*pos; - return (*pos >= stats->ls_num) ? NULL : - &(stats->ls_percpu[0]->lp_cntr[*pos]); + (*pos)++; + + return lprocfs_stats_seq_start(p, pos); } /* seq file export of one lprocfs counter */ static int lprocfs_stats_seq_show(struct seq_file *p, void *v) { - struct lprocfs_stats *stats = p->private; - struct lprocfs_counter *cntr = v; - struct lprocfs_counter ret; - int idx, rc = 0; - - if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) { - struct timeval now; - cfs_gettimeofday(&now); - rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n", - "snapshot_time", now.tv_sec, now.tv_usec); - if (rc < 0) - return rc; - } - idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0]; - - lprocfs_stats_collect(stats, idx, &ret); - - if (ret.lc_count == 0) - goto out; - - rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name, - ret.lc_count, cntr->lc_units); - - if (rc < 0) - goto out; - - if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) { - rc = seq_printf(p, " "LPD64" "LPD64" "LPD64, - ret.lc_min, ret.lc_max, ret.lc_sum); - if (rc < 0) - goto out; - if (cntr->lc_config & LPROCFS_CNTR_STDDEV) - rc = seq_printf(p, " "LPD64, ret.lc_sumsquare); - if (rc < 0) - goto out; - } - rc = seq_printf(p, "\n"); - out: - return (rc < 0) ? rc : 0; + struct lprocfs_stats *stats = p->private; + struct lprocfs_counter_header *hdr; + struct lprocfs_counter ctr; + int idx = *(loff_t *)v; + int rc = 0; + + if (idx == 0) { + struct timeval now; + + cfs_gettimeofday(&now); + rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n", + "snapshot_time", now.tv_sec, now.tv_usec); + if (rc < 0) + return rc; + } + + hdr = &stats->ls_cnt_header[idx]; + lprocfs_stats_collect(stats, idx, &ctr); + + if (ctr.lc_count == 0) + goto out; + + rc = seq_printf(p, "%-25s "LPD64" samples [%s]", hdr->lc_name, + ctr.lc_count, hdr->lc_units); + if (rc < 0) + goto out; + + if ((hdr->lc_config & LPROCFS_CNTR_AVGMINMAX) && ctr.lc_count > 0) { + rc = seq_printf(p, " "LPD64" "LPD64" "LPD64, + ctr.lc_min, ctr.lc_max, ctr.lc_sum); + if (rc < 0) + goto out; + if (hdr->lc_config & LPROCFS_CNTR_STDDEV) + rc = seq_printf(p, " "LPD64, ctr.lc_sumsquare); + if (rc < 0) + goto out; + } + rc = seq_printf(p, "\n"); +out: + return (rc < 0) ? rc : 0; } struct seq_operations lprocfs_stats_seq_sops = { - start: lprocfs_stats_seq_start, - stop: lprocfs_stats_seq_stop, - next: lprocfs_stats_seq_next, - show: lprocfs_stats_seq_show, + .start = lprocfs_stats_seq_start, + .stop = lprocfs_stats_seq_stop, + .next = lprocfs_stats_seq_next, + .show = lprocfs_stats_seq_show, }; static int lprocfs_stats_seq_open(struct inode *inode, struct file *file) @@ -1566,20 +1501,35 @@ EXPORT_SYMBOL(lprocfs_register_stats); void lprocfs_counter_init(struct lprocfs_stats *stats, int index, unsigned conf, const char *name, const char *units) { - struct lprocfs_counter *c = &(stats->ls_percpu[0]->lp_cntr[index]); - unsigned long flags = 0; + struct lprocfs_counter_header *header; + struct lprocfs_counter *percpu_cntr; + unsigned long flags = 0; + unsigned int i; + unsigned int num_cpu; LASSERT(stats != NULL); - LASSERT(stats->ls_percpu[0] != NULL); - - lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags); - c->lc_config = conf; - c->lc_count = 0; - c->lc_sum = 0; - c->lc_min = LC_MIN_INIT; - c->lc_max = 0; - c->lc_name = name; - c->lc_units = units; + + header = &stats->ls_cnt_header[index]; + LASSERTF(header != NULL, "Failed to allocate stats header:[%d]%s/%s\n", + index, name, units); + + header->lc_config = conf; + header->lc_name = name; + header->lc_units = units; + + num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags); + for (i = 0; i < num_cpu; ++i) { + if (stats->ls_percpu[i] == NULL) + continue; + percpu_cntr = lprocfs_stats_counter_get(stats, i, index); + percpu_cntr->lc_count = 0; + percpu_cntr->lc_min = LC_MIN_INIT; + percpu_cntr->lc_max = 0; + percpu_cntr->lc_sumsquare = 0; + percpu_cntr->lc_sum = 0; + if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) + percpu_cntr->lc_sum_irq = 0; + } lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags); } EXPORT_SYMBOL(lprocfs_counter_init); @@ -1611,7 +1561,6 @@ void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats) LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init); LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini); LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc); - LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete); LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs); LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async); LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd); @@ -1654,7 +1603,6 @@ void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats) LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid); LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck); LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl); - LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit); LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping); LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new); LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem); @@ -1689,7 +1637,7 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats) * , and that the corresponding line item * LPROCFS_OBD_OP_INIT(.., .., opname) * is missing from the list above. */ - LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL, + LASSERTF(stats->ls_cnt_header[i].lc_name != NULL, "Missing obd_stat initializer obd_op " "operation at offset %d.\n", i - num_private_stats); } @@ -1721,7 +1669,7 @@ do { \ void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats) { LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus); - LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata); + LPROCFS_MD_OP_INIT(num_private_stats, stats, null_inode); LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata); LPROCFS_MD_OP_INIT(num_private_stats, stats, close); LPROCFS_MD_OP_INIT(num_private_stats, stats, create); @@ -1775,7 +1723,7 @@ int lprocfs_alloc_md_stats(struct obd_device *obd, lprocfs_init_mps_stats(num_private_stats, stats); for (i = num_private_stats; i < num_stats; i++) { - if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) { + if (stats->ls_cnt_header[i].lc_name == NULL) { CERROR("Missing md_stat initializer md_op " "operation at offset %d. Aborting.\n", i - num_private_stats); @@ -1933,25 +1881,20 @@ EXPORT_SYMBOL(lprocfs_nid_stats_clear_read); static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data) { struct nid_stat *stat = obj; - int i; ENTRY; CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count)); if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) { /* object has only hash references. */ - cfs_spin_lock(&stat->nid_obd->obd_nid_lock); - cfs_list_move(&stat->nid_list, data); - cfs_spin_unlock(&stat->nid_obd->obd_nid_lock); + spin_lock(&stat->nid_obd->obd_nid_lock); + cfs_list_move(&stat->nid_list, data); + spin_unlock(&stat->nid_obd->obd_nid_lock); RETURN(1); } /* we has reference to object - only clear data*/ if (stat->nid_stats) lprocfs_clear_stats(stat->nid_stats); - if (stat->nid_brw_stats) { - for (i = 0; i < BRW_LAST; i++) - lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]); - } RETURN(0); } @@ -2065,9 +2008,9 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) exp->exp_nid_stats = new_stat; *newnid = 1; /* protect competitive add to list, not need locking on destroy */ - cfs_spin_lock(&obd->obd_nid_lock); - cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats); - cfs_spin_unlock(&obd->obd_nid_lock); + spin_lock(&obd->obd_nid_lock); + cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats); + spin_unlock(&obd->obd_nid_lock); RETURN(rc); @@ -2270,12 +2213,64 @@ int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count, } EXPORT_SYMBOL(lprocfs_write_frac_u64_helper); -int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode, - struct file_operations *seq_fops, void *data) +static char *lprocfs_strnstr(const char *s1, const char *s2, size_t len) +{ + size_t l2; + + l2 = strlen(s2); + if (!l2) + return (char *)s1; + while (len >= l2) { + len--; + if (!memcmp(s1, s2, l2)) + return (char *)s1; + s1++; + } + return NULL; +} + +/** + * Find the string \a name in the input \a buffer, and return a pointer to the + * value immediately following \a name, reducing \a count appropriately. + * If \a name is not found the original \a buffer is returned. + */ +char *lprocfs_find_named_value(const char *buffer, const char *name, + unsigned long *count) +{ + char *val; + size_t buflen = *count; + + /* there is no strnstr() in rhel5 and ubuntu kernels */ + val = lprocfs_strnstr(buffer, name, buflen); + if (val == NULL) + return (char *)buffer; + + val += strlen(name); /* skip prefix */ + while (val < buffer + buflen && isspace(*val)) /* skip separator */ + val++; + + *count = 0; + while (val < buffer + buflen && isalnum(*val)) { + ++*count; + ++val; + } + + return val - *count; +} +EXPORT_SYMBOL(lprocfs_find_named_value); + +int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, + const char *name, + mode_t mode, + const struct file_operations *seq_fops, + void *data) { struct proc_dir_entry *entry; ENTRY; + /* Disallow secretly (un)writable entries. */ + LASSERT((seq_fops->write == NULL) == ((mode & 0222) == 0)); + LPROCFS_WRITE_ENTRY(); entry = create_proc_entry(name, mode, parent); if (entry) { @@ -2291,10 +2286,11 @@ int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode, } EXPORT_SYMBOL(lprocfs_seq_create); -__inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name, - mode_t mode, - struct file_operations *seq_fops, - void *data) +int lprocfs_obd_seq_create(struct obd_device *dev, + const char *name, + mode_t mode, + const struct file_operations *seq_fops, + void *data) { return (lprocfs_seq_create(dev->obd_proc_entry, name, mode, seq_fops, data)); @@ -2303,12 +2299,12 @@ EXPORT_SYMBOL(lprocfs_obd_seq_create); void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value) { - if (value >= OBD_HIST_MAX) - value = OBD_HIST_MAX - 1; + if (value >= OBD_HIST_MAX) + value = OBD_HIST_MAX - 1; - cfs_spin_lock(&oh->oh_lock); - oh->oh_buckets[value]++; - cfs_spin_unlock(&oh->oh_lock); + spin_lock(&oh->oh_lock); + oh->oh_buckets[value]++; + spin_unlock(&oh->oh_lock); } EXPORT_SYMBOL(lprocfs_oh_tally); @@ -2336,9 +2332,9 @@ EXPORT_SYMBOL(lprocfs_oh_sum); void lprocfs_oh_clear(struct obd_histogram *oh) { - cfs_spin_lock(&oh->oh_lock); - memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets)); - cfs_spin_unlock(&oh->oh_lock); + spin_lock(&oh->oh_lock); + memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets)); + spin_unlock(&oh->oh_lock); } EXPORT_SYMBOL(lprocfs_oh_clear); @@ -2355,11 +2351,6 @@ int lprocfs_obd_rd_hash(char *page, char **start, off_t off, c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c); c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c); c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c); -#ifdef HAVE_QUOTA_SUPPORT - if (obd->u.obt.obt_qctxt.lqc_lqs_hash) - c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash, - page + c, count - c); -#endif return c; } @@ -2572,19 +2563,6 @@ int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer, } EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard); -int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - - LASSERT(obd != NULL); - LASSERT(mnt_get_devname(obd->u.obt.obt_vfsmnt)); - *eof = 1; - return snprintf(page, count, "%s\n", - mnt_get_devname(obd->u.obt.obt_vfsmnt)); -} -EXPORT_SYMBOL(lprocfs_obd_rd_mntdev); - int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off, int count, int *eof, void *data) {