* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2014, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Now we support both locked iteration & lockless iteration of hash
* table. Also, user can break the iteration by return 1 in callback.
*/
+#include <linux/seq_file.h>
#include <libcfs/libcfs.h>
static inline void
cfs_hash_spin_lock(cfs_hash_lock_t *lock, int exclusive)
+__acquires(&lock->spin)
{
spin_lock(&lock->spin);
}
static inline void
cfs_hash_spin_unlock(cfs_hash_lock_t *lock, int exclusive)
+__releases(&lock->spin)
{
spin_unlock(&lock->spin);
}
static inline void
cfs_hash_rw_lock(cfs_hash_lock_t *lock, int exclusive)
+__acquires(&lock->rw)
{
if (!exclusive)
read_lock(&lock->rw);
static inline void
cfs_hash_rw_unlock(cfs_hash_lock_t *lock, int exclusive)
+__releases(&lock->rw)
{
if (!exclusive)
read_unlock(&lock->rw);
if (hs == NULL)
RETURN(NULL);
- strncpy(hs->hs_name, name, len);
- hs->hs_name[len - 1] = '\0';
+ strlcpy(hs->hs_name, name, len);
hs->hs_flags = flags;
atomic_set(&hs->hs_refcount, 1);
}
EXPORT_SYMBOL(cfs_hash_rehash_key);
-#ifndef HAVE_ONLY_PROCFS_SEQ
-int cfs_hash_debug_header(char *str, int size)
-{
- return snprintf(str, size, "%-*s%6s%6s%6s%6s%6s%6s%6s%7s%8s%8s%8s%s\n",
- CFS_HASH_BIGNAME_LEN,
- "name", "cur", "min", "max", "theta", "t-min", "t-max",
- "flags", "rehash", "count", "maxdep", "maxdepb",
- " distribution");
-}
-EXPORT_SYMBOL(cfs_hash_debug_header);
-#endif
-
-int cfs_hash_debug_header_seq(struct seq_file *m)
+int cfs_hash_debug_header(struct seq_file *m)
{
return seq_printf(m, "%-*s%6s%6s%6s%6s%6s%6s%6s%7s%8s%8s%8s%s\n",
CFS_HASH_BIGNAME_LEN,
"flags", "rehash", "count", "maxdep", "maxdepb",
" distribution");
}
-EXPORT_SYMBOL(cfs_hash_debug_header_seq);
+EXPORT_SYMBOL(cfs_hash_debug_header);
static cfs_hash_bucket_t **
cfs_hash_full_bkts(cfs_hash_t *hs)
CFS_HASH_RH_NBKT(hs) : CFS_HASH_NBKT(hs);
}
-#ifndef HAVE_ONLY_PROCFS_SEQ
-int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size)
-{
- int dist[8] = { 0, };
- int maxdep = -1;
- int maxdepb = -1;
- int total = 0;
- int c = 0;
- int theta;
- int i;
-
- if (str == NULL || size == 0)
- return 0;
-
- cfs_hash_lock(hs, 0);
- theta = __cfs_hash_theta(hs);
-
- c += snprintf(str + c, size - c, "%-*s ",
- CFS_HASH_BIGNAME_LEN, hs->hs_name);
- c += snprintf(str + c, size - c, "%5d ", 1 << hs->hs_cur_bits);
- c += snprintf(str + c, size - c, "%5d ", 1 << hs->hs_min_bits);
- c += snprintf(str + c, size - c, "%5d ", 1 << hs->hs_max_bits);
- c += snprintf(str + c, size - c, "%d.%03d ",
- __cfs_hash_theta_int(theta),
- __cfs_hash_theta_frac(theta));
- c += snprintf(str + c, size - c, "%d.%03d ",
- __cfs_hash_theta_int(hs->hs_min_theta),
- __cfs_hash_theta_frac(hs->hs_min_theta));
- c += snprintf(str + c, size - c, "%d.%03d ",
- __cfs_hash_theta_int(hs->hs_max_theta),
- __cfs_hash_theta_frac(hs->hs_max_theta));
- c += snprintf(str + c, size - c, " 0x%02x ", hs->hs_flags);
- c += snprintf(str + c, size - c, "%6d ", hs->hs_rehash_count);
-
- /*
- * The distribution is a summary of the chained hash depth in
- * each of the libcfs hash buckets. Each buckets hsb_count is
- * divided by the hash theta value and used to generate a
- * histogram of the hash distribution. A uniform hash will
- * result in all hash buckets being close to the average thus
- * only the first few entries in the histogram will be non-zero.
- * If you hash function results in a non-uniform hash the will
- * be observable by outlier bucks in the distribution histogram.
- *
- * Uniform hash distribution: 128/128/0/0/0/0/0/0
- * Non-Uniform hash distribution: 128/125/0/0/0/0/2/1
- */
- for (i = 0; i < cfs_hash_full_nbkt(hs); i++) {
- cfs_hash_bd_t bd;
-
- bd.bd_bucket = cfs_hash_full_bkts(hs)[i];
- cfs_hash_bd_lock(hs, &bd, 0);
- if (maxdep < bd.bd_bucket->hsb_depmax) {
- maxdep = bd.bd_bucket->hsb_depmax;
-#ifdef __KERNEL__
- maxdepb = ffz(~maxdep);
-#endif
- }
- total += bd.bd_bucket->hsb_count;
- dist[min(fls(bd.bd_bucket->hsb_count/max(theta,1)),7)]++;
- cfs_hash_bd_unlock(hs, &bd, 0);
- }
-
- c += snprintf(str + c, size - c, "%7d ", total);
- c += snprintf(str + c, size - c, "%7d ", maxdep);
- c += snprintf(str + c, size - c, "%7d ", maxdepb);
- for (i = 0; i < 8; i++)
- c += snprintf(str + c, size - c, "%d%c", dist[i],
- (i == 7) ? '\n' : '/');
-
- cfs_hash_unlock(hs, 0);
-
- return c;
-}
-EXPORT_SYMBOL(cfs_hash_debug_str);
-#endif
-
-int cfs_hash_debug_str_seq(cfs_hash_t *hs, struct seq_file *m)
+int cfs_hash_debug_str(cfs_hash_t *hs, struct seq_file *m)
{
int dist[8] = { 0, };
int maxdep = -1;
cfs_hash_unlock(hs, 0);
return c;
}
-EXPORT_SYMBOL(cfs_hash_debug_str_seq);
+EXPORT_SYMBOL(cfs_hash_debug_str);