Re: [Cluster-devel] [GFS2 PATCH 2/2] GFS2: Use resizable hash table for glocks

2015-07-13 Thread Steven Whitehouse

Hi,

Looks good. Acked-by: Steven Whitehouse swhit...@redhat.com

Steve.

On 09/07/15 19:25, Bob Peterson wrote:

This patch changes the glock hash table from a normal hash table to
a resizable hash table, which scales better. This also simplifies
a lot of code.
---
  fs/gfs2/glock.c  | 282 +--
  fs/gfs2/incore.h |   4 +-
  2 files changed, 111 insertions(+), 175 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 25e0389..813de00 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -34,6 +34,7 @@
  #include linux/percpu.h
  #include linux/list_sort.h
  #include linux/lockref.h
+#include linux/rhashtable.h
  
  #include gfs2.h

  #include incore.h
@@ -51,8 +52,12 @@
  
  struct gfs2_glock_iter {

int hash;   /* hash bucket index   */
-   unsigned nhash; /* Index within current bucket */
struct gfs2_sbd *sdp;   /* incore superblock   */
+};
+
+struct gfs2_glock_rht_iter {
+   struct gfs2_sbd *sdp;   /* incore superblock   */
+   struct rhashtable_iter hti; /* rhashtable iterator */
struct gfs2_glock *gl;  /* current glock struct*/
loff_t last_pos;/* last position   */
  };
@@ -70,44 +75,20 @@ static DEFINE_SPINLOCK(lru_lock);
  
  #define GFS2_GL_HASH_SHIFT  15

  #define GFS2_GL_HASH_SIZE   (1  GFS2_GL_HASH_SHIFT)
-#define GFS2_GL_HASH_MASK   (GFS2_GL_HASH_SIZE - 1)
-
-static struct hlist_bl_head gl_hash_table[GFS2_GL_HASH_SIZE];
-static struct dentry *gfs2_root;
-
-/**
- * gl_hash() - Turn glock number into hash bucket number
- * @lock: The glock number
- *
- * Returns: The number of the corresponding hash bucket
- */
-
-static unsigned int gl_hash(const struct gfs2_sbd *sdp,
-   const struct lm_lockname *name)
-{
-   unsigned int h;
-
-   h = jhash(name-ln_number, sizeof(u64), 0);
-   h = jhash(name-ln_type, sizeof(unsigned int), h);
-   h = jhash(sdp, sizeof(struct gfs2_sbd *), h);
-   h = GFS2_GL_HASH_MASK;
-
-   return h;
-}
  
-static inline void spin_lock_bucket(unsigned int hash)

-{
-   hlist_bl_lock(gl_hash_table[hash]);
-}
+struct rhashtable_params ht_parms = {
+   .nelem_hint = GFS2_GL_HASH_SIZE * 3 / 4,
+   .key_len = sizeof(struct lm_lockname),
+   .key_offset = offsetof(struct gfs2_glock, gl_name),
+   .head_offset = offsetof(struct gfs2_glock, gl_node),
+   .hashfn = jhash,
+};
  
-static inline void spin_unlock_bucket(unsigned int hash)

-{
-   hlist_bl_unlock(gl_hash_table[hash]);
-}
+static struct rhashtable gl_hash_table;
  
-static void gfs2_glock_dealloc(struct rcu_head *rcu)

+void gfs2_glock_free(struct gfs2_glock *gl)
  {
-   struct gfs2_glock *gl = container_of(rcu, struct gfs2_glock, gl_rcu);
+   struct gfs2_sbd *sdp = gl-gl_name.ln_sbd;
  
  	if (gl-gl_ops-go_flags  GLOF_ASPACE) {

kmem_cache_free(gfs2_glock_aspace_cachep, gl);
@@ -115,13 +96,6 @@ static void gfs2_glock_dealloc(struct rcu_head *rcu)
kfree(gl-gl_lksb.sb_lvbptr);
kmem_cache_free(gfs2_glock_cachep, gl);
}
-}
-
-void gfs2_glock_free(struct gfs2_glock *gl)
-{
-   struct gfs2_sbd *sdp = gl-gl_name.ln_sbd;
-
-   call_rcu(gl-gl_rcu, gfs2_glock_dealloc);
if (atomic_dec_and_test(sdp-sd_glock_disposal))
wake_up(sdp-sd_glock_wait);
  }
@@ -202,9 +176,8 @@ void gfs2_glock_put(struct gfs2_glock *gl)
  
  	gfs2_glock_remove_from_lru(gl);

spin_unlock(gl-gl_lockref.lock);
-   spin_lock_bucket(gl-gl_hash);
-   hlist_bl_del_rcu(gl-gl_list);
-   spin_unlock_bucket(gl-gl_hash);
+   if (gl-gl_node.next != NULL)
+   rhashtable_remove_fast(gl_hash_table, gl-gl_node, ht_parms);
GLOCK_BUG_ON(gl, !list_empty(gl-gl_holders));
GLOCK_BUG_ON(gl, mapping  mapping-nrpages);
trace_gfs2_glock_put(gl);
@@ -212,30 +185,6 @@ void gfs2_glock_put(struct gfs2_glock *gl)
  }
  
  /**

- * search_bucket() - Find struct gfs2_glock by lock number
- * @bucket: the bucket to search
- * @name: The lock name
- *
- * Returns: NULL, or the struct gfs2_glock with the requested number
- */
-
-static struct gfs2_glock *search_bucket(unsigned int hash,
-   const struct lm_lockname *name)
-{
-   struct gfs2_glock *gl;
-   struct hlist_bl_node *h;
-
-   hlist_bl_for_each_entry_rcu(gl, h, gl_hash_table[hash], gl_list) {
-   if (!lm_name_equal(gl-gl_name, name))
-   continue;
-   if (lockref_get_not_dead(gl-gl_lockref))
-   return gl;
-   }
-
-   return NULL;
-}
-
-/**
   * may_grant - check if its ok to grant a new lock
   * @gl: The glock
   * @gh: The lock request which we wish to grant
@@ -704,14 +653,14 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,

Re: [Cluster-devel] [GFS2 PATCH 1/2] GFS2: Move glock superblock pointer to field gl_name

2015-07-13 Thread Steven Whitehouse

Hi,

On 09/07/15 19:25, Bob Peterson wrote:

What uniquely identifies a glock in the glock hash table is not
gl_name, but gl_name and its superblock pointer. This patch makes
the gl_name field correspond to a unique glock identifier. That will
allow us to simplify hashing with a future patch, since the hash
algorithm can then take the gl_name and hash its components in one
operation.
---

[snip]

diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index a1ec7c2..4de7853 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -205,11 +205,13 @@ enum {
  struct lm_lockname {
u64 ln_number;
unsigned int ln_type;
+   struct gfs2_sbd *ln_sbd;
  };
  
This looks like its adding a hole on 64 bit arches... can we swap the 
order of ln_type and ln_sbd, or even make the sbd the first element of 
this? That way a memcmp of two of lm_locknames doesn't have to include 
the hole in the comparison, which I assume is what you want here?


Steve.



Re: [Cluster-devel] [GFS2 PATCH 1/2][TRY #2] GFS2: Move glock superblock pointer to field gl_name

2015-07-13 Thread Bob Peterson
Hi,

- Original Message -
 Hi,
 
 On 09/07/15 19:25, Bob Peterson wrote:
  What uniquely identifies a glock in the glock hash table is not
  gl_name, but gl_name and its superblock pointer. This patch makes
  the gl_name field correspond to a unique glock identifier. That will
  allow us to simplify hashing with a future patch, since the hash
  algorithm can then take the gl_name and hash its components in one
  operation.
  ---
 [snip]
  diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
  index a1ec7c2..4de7853 100644
  --- a/fs/gfs2/incore.h
  +++ b/fs/gfs2/incore.h
  @@ -205,11 +205,13 @@ enum {
struct lm_lockname {
  u64 ln_number;
  unsigned int ln_type;
  +   struct gfs2_sbd *ln_sbd;
};

 This looks like its adding a hole on 64 bit arches... can we swap the
 order of ln_type and ln_sbd, or even make the sbd the first element of
 this? That way a memcmp of two of lm_locknames doesn't have to include
 the hole in the comparison, which I assume is what you want here?
 
 Steve.

Good catch. This replacement for patch #1 is identical except for
the placement of ln_sbd in the lm_lockname structure.

Regards,

Bob Peterson
Red Hat File Systems
---
commit 0ed2b820a4f3d44e447b3e724f5355cd2f7ee4ee
Author: Bob Peterson rpete...@redhat.com
Date:   Mon Mar 16 11:52:05 2015 -0500

GFS2: Move glock superblock pointer to field gl_name

What uniquely identifies a glock in the glock hash table is not
gl_name, but gl_name and its superblock pointer. This patch makes
the gl_name field correspond to a unique glock identifier. That will
allow us to simplify hashing with a future patch, since the hash
algorithm can then take the gl_name and hash its components in one
operation.

Signed-off-by: Bob Peterson rpete...@redhat.com
---
 fs/gfs2/glock.c  | 32 +++-
 fs/gfs2/glops.c  | 38 --
 fs/gfs2/incore.h |  9 +
 fs/gfs2/lock_dlm.c   | 10 +-
 fs/gfs2/lops.c   |  6 +++---
 fs/gfs2/meta_io.c|  6 +++---
 fs/gfs2/meta_io.h|  2 +-
 fs/gfs2/quota.c  | 22 +++---
 fs/gfs2/rgrp.c   |  2 +-
 fs/gfs2/trace_gfs2.h | 18 +-
 fs/gfs2/trans.c  |  4 ++--
 11 files changed, 75 insertions(+), 74 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index a38e38f..25e0389 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -119,7 +119,7 @@ static void gfs2_glock_dealloc(struct rcu_head *rcu)
 
 void gfs2_glock_free(struct gfs2_glock *gl)
 {
-   struct gfs2_sbd *sdp = gl-gl_sbd;
+   struct gfs2_sbd *sdp = gl-gl_name.ln_sbd;
 
call_rcu(gl-gl_rcu, gfs2_glock_dealloc);
if (atomic_dec_and_test(sdp-sd_glock_disposal))
@@ -192,7 +192,7 @@ static void gfs2_glock_remove_from_lru(struct gfs2_glock 
*gl)
 
 void gfs2_glock_put(struct gfs2_glock *gl)
 {
-   struct gfs2_sbd *sdp = gl-gl_sbd;
+   struct gfs2_sbd *sdp = gl-gl_name.ln_sbd;
struct address_space *mapping = gfs2_glock2aspace(gl);
 
if (lockref_put_or_lock(gl-gl_lockref))
@@ -220,7 +220,6 @@ void gfs2_glock_put(struct gfs2_glock *gl)
  */
 
 static struct gfs2_glock *search_bucket(unsigned int hash,
-   const struct gfs2_sbd *sdp,
const struct lm_lockname *name)
 {
struct gfs2_glock *gl;
@@ -229,8 +228,6 @@ static struct gfs2_glock *search_bucket(unsigned int hash,
hlist_bl_for_each_entry_rcu(gl, h, gl_hash_table[hash], gl_list) {
if (!lm_name_equal(gl-gl_name, name))
continue;
-   if (gl-gl_sbd != sdp)
-   continue;
if (lockref_get_not_dead(gl-gl_lockref))
return gl;
}
@@ -506,7 +503,7 @@ __releases(gl-gl_spin)
 __acquires(gl-gl_spin)
 {
const struct gfs2_glock_operations *glops = gl-gl_ops;
-   struct gfs2_sbd *sdp = gl-gl_sbd;
+   struct gfs2_sbd *sdp = gl-gl_name.ln_sbd;
unsigned int lck_flags = gh ? gh-gh_flags : 0;
int ret;
 
@@ -628,7 +625,7 @@ out_unlock:
 static void delete_work_func(struct work_struct *work)
 {
struct gfs2_glock *gl = container_of(work, struct gfs2_glock, 
gl_delete);
-   struct gfs2_sbd *sdp = gl-gl_sbd;
+   struct gfs2_sbd *sdp = gl-gl_name.ln_sbd;
struct gfs2_inode *ip;
struct inode *inode;
u64 no_addr = gl-gl_name.ln_number;
@@ -704,14 +701,16 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
   struct gfs2_glock **glp)
 {
struct super_block *s = sdp-sd_vfs;
-   struct lm_lockname name = { .ln_number = number, .ln_type = 
glops-go_type };
+   struct lm_lockname name = { .ln_number = number,
+   .ln_type = glops-go_type,
+   .ln_sbd = sdp };
struct gfs2_glock *gl, *tmp;
unsigned int hash = gl_hash(sdp, name);
struct address_space *mapping;
 

Re: [Cluster-devel] [GFS2 PATCH 1/2][TRY #2] GFS2: Move glock superblock pointer to field gl_name

2015-07-13 Thread Steven Whitehouse

Hi,

On 13/07/15 14:39, Bob Peterson wrote:

Hi,

- Original Message -

Hi,

On 09/07/15 19:25, Bob Peterson wrote:

What uniquely identifies a glock in the glock hash table is not
gl_name, but gl_name and its superblock pointer. This patch makes
the gl_name field correspond to a unique glock identifier. That will
allow us to simplify hashing with a future patch, since the hash
algorithm can then take the gl_name and hash its components in one
operation.
---

[snip]

diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index a1ec7c2..4de7853 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -205,11 +205,13 @@ enum {
   struct lm_lockname {
u64 ln_number;
unsigned int ln_type;
+   struct gfs2_sbd *ln_sbd;
   };
   

This looks like its adding a hole on 64 bit arches... can we swap the
order of ln_type and ln_sbd, or even make the sbd the first element of
this? That way a memcmp of two of lm_locknames doesn't have to include
the hole in the comparison, which I assume is what you want here?

Steve.

Good catch. This replacement for patch #1 is identical except for
the placement of ln_sbd in the lm_lockname structure.

Regards,

Bob Peterson
Red Hat File Systems
---


That looks good now. Acked-by: Steven Whitehouse swhit...@redhat.com

Steve.


commit 0ed2b820a4f3d44e447b3e724f5355cd2f7ee4ee
Author: Bob Peterson rpete...@redhat.com
Date:   Mon Mar 16 11:52:05 2015 -0500

GFS2: Move glock superblock pointer to field gl_name

What uniquely identifies a glock in the glock hash table is not
gl_name, but gl_name and its superblock pointer. This patch makes
the gl_name field correspond to a unique glock identifier. That will
allow us to simplify hashing with a future patch, since the hash
algorithm can then take the gl_name and hash its components in one
operation.

Signed-off-by: Bob Peterson rpete...@redhat.com
---
  fs/gfs2/glock.c  | 32 +++-
  fs/gfs2/glops.c  | 38 --
  fs/gfs2/incore.h |  9 +
  fs/gfs2/lock_dlm.c   | 10 +-
  fs/gfs2/lops.c   |  6 +++---
  fs/gfs2/meta_io.c|  6 +++---
  fs/gfs2/meta_io.h|  2 +-
  fs/gfs2/quota.c  | 22 +++---
  fs/gfs2/rgrp.c   |  2 +-
  fs/gfs2/trace_gfs2.h | 18 +-
  fs/gfs2/trans.c  |  4 ++--
  11 files changed, 75 insertions(+), 74 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index a38e38f..25e0389 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -119,7 +119,7 @@ static void gfs2_glock_dealloc(struct rcu_head *rcu)
  
  void gfs2_glock_free(struct gfs2_glock *gl)

  {
-   struct gfs2_sbd *sdp = gl-gl_sbd;
+   struct gfs2_sbd *sdp = gl-gl_name.ln_sbd;
  
  	call_rcu(gl-gl_rcu, gfs2_glock_dealloc);

if (atomic_dec_and_test(sdp-sd_glock_disposal))
@@ -192,7 +192,7 @@ static void gfs2_glock_remove_from_lru(struct gfs2_glock 
*gl)
  
  void gfs2_glock_put(struct gfs2_glock *gl)

  {
-   struct gfs2_sbd *sdp = gl-gl_sbd;
+   struct gfs2_sbd *sdp = gl-gl_name.ln_sbd;
struct address_space *mapping = gfs2_glock2aspace(gl);
  
  	if (lockref_put_or_lock(gl-gl_lockref))

@@ -220,7 +220,6 @@ void gfs2_glock_put(struct gfs2_glock *gl)
   */
  
  static struct gfs2_glock *search_bucket(unsigned int hash,

-   const struct gfs2_sbd *sdp,
const struct lm_lockname *name)
  {
struct gfs2_glock *gl;
@@ -229,8 +228,6 @@ static struct gfs2_glock *search_bucket(unsigned int hash,
hlist_bl_for_each_entry_rcu(gl, h, gl_hash_table[hash], gl_list) {
if (!lm_name_equal(gl-gl_name, name))
continue;
-   if (gl-gl_sbd != sdp)
-   continue;
if (lockref_get_not_dead(gl-gl_lockref))
return gl;
}
@@ -506,7 +503,7 @@ __releases(gl-gl_spin)
  __acquires(gl-gl_spin)
  {
const struct gfs2_glock_operations *glops = gl-gl_ops;
-   struct gfs2_sbd *sdp = gl-gl_sbd;
+   struct gfs2_sbd *sdp = gl-gl_name.ln_sbd;
unsigned int lck_flags = gh ? gh-gh_flags : 0;
int ret;
  
@@ -628,7 +625,7 @@ out_unlock:

  static void delete_work_func(struct work_struct *work)
  {
struct gfs2_glock *gl = container_of(work, struct gfs2_glock, 
gl_delete);
-   struct gfs2_sbd *sdp = gl-gl_sbd;
+   struct gfs2_sbd *sdp = gl-gl_name.ln_sbd;
struct gfs2_inode *ip;
struct inode *inode;
u64 no_addr = gl-gl_name.ln_number;
@@ -704,14 +701,16 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
   struct gfs2_glock **glp)
  {
struct super_block *s = sdp-sd_vfs;
-   struct lm_lockname name = { .ln_number = number, .ln_type = 
glops-go_type };
+   struct lm_lockname name = { .ln_number = number,
+   .ln_type = glops-go_type,
+   .ln_sbd = sdp 

[Cluster-devel] [PATCH linux-gfs2] GFS2: ht_parms can be static

2015-07-13 Thread kbuild test robot

Signed-off-by: Fengguang Wu fengguang...@intel.com
---
 glock.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 813de00..1b0dff4 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -76,7 +76,7 @@ static DEFINE_SPINLOCK(lru_lock);
 #define GFS2_GL_HASH_SHIFT  15
 #define GFS2_GL_HASH_SIZE   (1  GFS2_GL_HASH_SHIFT)
 
-struct rhashtable_params ht_parms = {
+static struct rhashtable_params ht_parms = {
.nelem_hint = GFS2_GL_HASH_SIZE * 3 / 4,
.key_len = sizeof(struct lm_lockname),
.key_offset = offsetof(struct gfs2_glock, gl_name),