[PATCH 02/20] staging: lustre: convert lov_pool to use rhashtable

2018-04-11 Thread NeilBrown
The pools hashtable can be implemented using
the rhashtable implementation in lib.
This has the benefit that lookups are lock-free.

We need to use kfree_rcu() to free a pool so
that a lookup racing with a deletion will not access
freed memory.

rhashtable has no combined lookup-and-delete interface,
but as the lookup is lockless and the chains are short,
this brings little cost.  Even if a lookup finds a pool,
we must be prepared for the delete to fail to find it,
as we might race with another thread doing a delete.

We use atomic_inc_not_zero() after finding a pool in the
hash table and if that fails, we must have raced with a
deletion, so we treat the lookup as a failure.

Use hashlen_string() rather than a hand-crafted hash
function.
Note that the pool_name, and the search key, are
guaranteed to be nul terminated.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/obd.h|4 -
 .../staging/lustre/lustre/include/obd_support.h|3 
 drivers/staging/lustre/lustre/lov/lov_internal.h   |   11 +
 drivers/staging/lustre/lustre/lov/lov_obd.c|   12 +-
 drivers/staging/lustre/lustre/lov/lov_pool.c   |  159 
 5 files changed, 80 insertions(+), 109 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/obd.h 
b/drivers/staging/lustre/lustre/include/obd.h
index f1233ca7d337..ad265db48b76 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -46,6 +46,8 @@
 #include 
 #include 
 
+#include 
+
 #define MAX_OBD_DEVICES 8192
 
 struct osc_async_rc {
@@ -383,7 +385,7 @@ struct lov_obd {
__u32  lov_tgt_size;   /* size of tgts array */
int  lov_connects;
int  lov_pool_count;
-   struct cfs_hash  *lov_pools_hash_body; /* used for key access */
+   struct rhashtable   lov_pools_hash_body; /* used for key access */
struct list_headlov_pool_list; /* used for sequential access */
struct dentry   *lov_pool_debugfs_entry;
enum lustre_sec_partlov_sp_me;
diff --git a/drivers/staging/lustre/lustre/include/obd_support.h 
b/drivers/staging/lustre/lustre/include/obd_support.h
index aebcab191442..730a6ee71565 100644
--- a/drivers/staging/lustre/lustre/include/obd_support.h
+++ b/drivers/staging/lustre/lustre/include/obd_support.h
@@ -61,9 +61,6 @@ extern atomic_long_t obd_dirty_transit_pages;
 extern char obd_jobid_var[];
 
 /* Some hash init argument constants */
-#define HASH_POOLS_BKT_BITS 3
-#define HASH_POOLS_CUR_BITS 3
-#define HASH_POOLS_MAX_BITS 7
 #define HASH_UUID_BKT_BITS 5
 #define HASH_UUID_CUR_BITS 7
 #define HASH_UUID_MAX_BITS 12
diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h 
b/drivers/staging/lustre/lustre/lov/lov_internal.h
index 27f60dd7ab9a..47042f27ca90 100644
--- a/drivers/staging/lustre/lustre/lov/lov_internal.h
+++ b/drivers/staging/lustre/lustre/lov/lov_internal.h
@@ -149,11 +149,16 @@ struct pool_desc {
char pool_name[LOV_MAXPOOLNAME + 1];
struct ost_pool  pool_obds;
atomic_t pool_refcount;
-   struct hlist_nodepool_hash; /* access by poolname */
-   struct list_head pool_list; /* serial access */
+   struct rhash_headpool_hash; /* access by poolname */
+   union {
+   struct list_headpool_list;  /* serial access */
+   struct rcu_head rcu;/* delayed free */
+   };
struct dentry   *pool_debugfs_entry;/* file in debugfs */
struct obd_device   *pool_lobd; /* owner */
 };
+int lov_pool_hash_init(struct rhashtable *tbl);
+void lov_pool_hash_destroy(struct rhashtable *tbl);
 
 struct lov_request {
struct obd_info   rq_oi;
@@ -241,8 +246,6 @@ void lprocfs_lov_init_vars(struct lprocfs_static_vars 
*lvars);
 /* lov_cl.c */
 extern struct lu_device_type lov_device_type;
 
-/* pools */
-extern struct cfs_hash_ops pool_hash_operations;
 /* ost_pool methods */
 int lov_ost_pool_init(struct ost_pool *op, unsigned int count);
 int lov_ost_pool_extend(struct ost_pool *op, unsigned int min_count);
diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c 
b/drivers/staging/lustre/lustre/lov/lov_obd.c
index 355e87ecc62d..94da35e673f7 100644
--- a/drivers/staging/lustre/lustre/lov/lov_obd.c
+++ b/drivers/staging/lustre/lustre/lov/lov_obd.c
@@ -795,15 +795,11 @@ int lov_setup(struct obd_device *obd, struct lustre_cfg 
*lcfg)
 
init_rwsem(>lov_notify_lock);
 
-   lov->lov_pools_hash_body = cfs_hash_create("POOLS", HASH_POOLS_CUR_BITS,
-  HASH_POOLS_MAX_BITS,
-  HASH_POOLS_BKT_BITS, 0,
-  CFS_HASH_MIN_THETA,
- 

[PATCH 02/20] staging: lustre: convert lov_pool to use rhashtable

2018-04-11 Thread NeilBrown
The pools hashtable can be implemented using
the rhashtable implementation in lib.
This has the benefit that lookups are lock-free.

We need to use kfree_rcu() to free a pool so
that a lookup racing with a deletion will not access
freed memory.

rhashtable has no combined lookup-and-delete interface,
but as the lookup is lockless and the chains are short,
this brings little cost.  Even if a lookup finds a pool,
we must be prepared for the delete to fail to find it,
as we might race with another thread doing a delete.

We use atomic_inc_not_zero() after finding a pool in the
hash table and if that fails, we must have raced with a
deletion, so we treat the lookup as a failure.

Use hashlen_string() rather than a hand-crafted hash
function.
Note that the pool_name, and the search key, are
guaranteed to be nul terminated.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/obd.h|4 -
 .../staging/lustre/lustre/include/obd_support.h|3 
 drivers/staging/lustre/lustre/lov/lov_internal.h   |   11 +
 drivers/staging/lustre/lustre/lov/lov_obd.c|   12 +-
 drivers/staging/lustre/lustre/lov/lov_pool.c   |  159 
 5 files changed, 80 insertions(+), 109 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/obd.h 
b/drivers/staging/lustre/lustre/include/obd.h
index f1233ca7d337..ad265db48b76 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -46,6 +46,8 @@
 #include 
 #include 
 
+#include 
+
 #define MAX_OBD_DEVICES 8192
 
 struct osc_async_rc {
@@ -383,7 +385,7 @@ struct lov_obd {
__u32  lov_tgt_size;   /* size of tgts array */
int  lov_connects;
int  lov_pool_count;
-   struct cfs_hash  *lov_pools_hash_body; /* used for key access */
+   struct rhashtable   lov_pools_hash_body; /* used for key access */
struct list_headlov_pool_list; /* used for sequential access */
struct dentry   *lov_pool_debugfs_entry;
enum lustre_sec_partlov_sp_me;
diff --git a/drivers/staging/lustre/lustre/include/obd_support.h 
b/drivers/staging/lustre/lustre/include/obd_support.h
index aebcab191442..730a6ee71565 100644
--- a/drivers/staging/lustre/lustre/include/obd_support.h
+++ b/drivers/staging/lustre/lustre/include/obd_support.h
@@ -61,9 +61,6 @@ extern atomic_long_t obd_dirty_transit_pages;
 extern char obd_jobid_var[];
 
 /* Some hash init argument constants */
-#define HASH_POOLS_BKT_BITS 3
-#define HASH_POOLS_CUR_BITS 3
-#define HASH_POOLS_MAX_BITS 7
 #define HASH_UUID_BKT_BITS 5
 #define HASH_UUID_CUR_BITS 7
 #define HASH_UUID_MAX_BITS 12
diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h 
b/drivers/staging/lustre/lustre/lov/lov_internal.h
index 27f60dd7ab9a..47042f27ca90 100644
--- a/drivers/staging/lustre/lustre/lov/lov_internal.h
+++ b/drivers/staging/lustre/lustre/lov/lov_internal.h
@@ -149,11 +149,16 @@ struct pool_desc {
char pool_name[LOV_MAXPOOLNAME + 1];
struct ost_pool  pool_obds;
atomic_t pool_refcount;
-   struct hlist_nodepool_hash; /* access by poolname */
-   struct list_head pool_list; /* serial access */
+   struct rhash_headpool_hash; /* access by poolname */
+   union {
+   struct list_headpool_list;  /* serial access */
+   struct rcu_head rcu;/* delayed free */
+   };
struct dentry   *pool_debugfs_entry;/* file in debugfs */
struct obd_device   *pool_lobd; /* owner */
 };
+int lov_pool_hash_init(struct rhashtable *tbl);
+void lov_pool_hash_destroy(struct rhashtable *tbl);
 
 struct lov_request {
struct obd_info   rq_oi;
@@ -241,8 +246,6 @@ void lprocfs_lov_init_vars(struct lprocfs_static_vars 
*lvars);
 /* lov_cl.c */
 extern struct lu_device_type lov_device_type;
 
-/* pools */
-extern struct cfs_hash_ops pool_hash_operations;
 /* ost_pool methods */
 int lov_ost_pool_init(struct ost_pool *op, unsigned int count);
 int lov_ost_pool_extend(struct ost_pool *op, unsigned int min_count);
diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c 
b/drivers/staging/lustre/lustre/lov/lov_obd.c
index 355e87ecc62d..94da35e673f7 100644
--- a/drivers/staging/lustre/lustre/lov/lov_obd.c
+++ b/drivers/staging/lustre/lustre/lov/lov_obd.c
@@ -795,15 +795,11 @@ int lov_setup(struct obd_device *obd, struct lustre_cfg 
*lcfg)
 
init_rwsem(>lov_notify_lock);
 
-   lov->lov_pools_hash_body = cfs_hash_create("POOLS", HASH_POOLS_CUR_BITS,
-  HASH_POOLS_MAX_BITS,
-  HASH_POOLS_BKT_BITS, 0,
-  CFS_HASH_MIN_THETA,
-