From: Steven Whitehouse <swhiteho@redhat.com>
To: cluster-devel@redhat.com, linux-kernel@vger.kernel.org
Cc: Steven Whitehouse <swhiteho@redhat.com>
Subject: [PATCH 08/15] GFS2: Fix glock deallocation race
Date: Tue, 15 Mar 2011 09:11:38 +0000 [thread overview]
Message-ID: <1300180305-5993-9-git-send-email-swhiteho@redhat.com> (raw)
In-Reply-To: <1300180305-5993-1-git-send-email-swhiteho@redhat.com>
This patch fixes a race in deallocating glocks which was introduced
in the RCU glock patch. We need to ensure that the glock count is
kept correct even in the case that there is a race to add a new
glock into the hash table. Also, to avoid having to wait for an
RCU grace period, the glock counter can be decremented before
call_rcu() is called.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index ddc3e1e..3f45a14 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -103,16 +103,21 @@ static inline void spin_unlock_bucket(unsigned int hash)
__bit_spin_unlock(0, (unsigned long *)bl);
}
-void gfs2_glock_free(struct rcu_head *rcu)
+static void gfs2_glock_dealloc(struct rcu_head *rcu)
{
struct gfs2_glock *gl = container_of(rcu, struct gfs2_glock, gl_rcu);
- struct gfs2_sbd *sdp = gl->gl_sbd;
if (gl->gl_ops->go_flags & GLOF_ASPACE)
kmem_cache_free(gfs2_glock_aspace_cachep, gl);
else
kmem_cache_free(gfs2_glock_cachep, gl);
+}
+
+void gfs2_glock_free(struct gfs2_glock *gl)
+{
+ struct gfs2_sbd *sdp = gl->gl_sbd;
+ call_rcu(&gl->gl_rcu, gfs2_glock_dealloc);
if (atomic_dec_and_test(&sdp->sd_glock_disposal))
wake_up(&sdp->sd_glock_wait);
}
@@ -760,6 +765,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
if (tmp) {
spin_unlock_bucket(hash);
kmem_cache_free(cachep, gl);
+ atomic_dec(&sdp->sd_glock_disposal);
gl = tmp;
} else {
hlist_bl_add_head_rcu(&gl->gl_list, &gl_hash_table[hash]);
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index afa8bfe..aea1606 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -230,7 +230,7 @@ extern void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
extern void gfs2_glock_finish_truncate(struct gfs2_inode *ip);
extern void gfs2_glock_thaw(struct gfs2_sbd *sdp);
extern void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl);
-extern void gfs2_glock_free(struct rcu_head *rcu);
+extern void gfs2_glock_free(struct gfs2_glock *gl);
extern int __init gfs2_glock_init(void);
extern void gfs2_glock_exit(void);
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c
index c80485c..98c80d8 100644
--- a/fs/gfs2/lock_dlm.c
+++ b/fs/gfs2/lock_dlm.c
@@ -30,7 +30,7 @@ static void gdlm_ast(void *arg)
switch (gl->gl_lksb.sb_status) {
case -DLM_EUNLOCK: /* Unlocked, so glock can be freed */
- call_rcu(&gl->gl_rcu, gfs2_glock_free);
+ gfs2_glock_free(gl);
return;
case -DLM_ECANCEL: /* Cancel while getting lock */
ret |= LM_OUT_CANCELED;
@@ -165,7 +165,7 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
int error;
if (gl->gl_lksb.sb_lkid == 0) {
- call_rcu(&gl->gl_rcu, gfs2_glock_free);
+ gfs2_glock_free(gl);
return;
}
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index a39c103..67654d0 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -928,14 +928,9 @@ static const match_table_t nolock_tokens = {
{ Opt_err, NULL },
};
-static void nolock_put_lock(struct gfs2_glock *gl)
-{
- call_rcu(&gl->gl_rcu, gfs2_glock_free);
-}
-
static const struct lm_lockops nolock_ops = {
.lm_proto_name = "lock_nolock",
- .lm_put_lock = nolock_put_lock,
+ .lm_put_lock = gfs2_glock_free,
.lm_tokens = &nolock_tokens,
};
--
1.7.4
next prev parent reply other threads:[~2011-03-15 9:35 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-15 9:11 GFS2: Pre-pull patch posting (merge window) Steven Whitehouse
2011-03-15 9:11 ` [PATCH 01/15] GFS2: Use RCU for glock hash table Steven Whitehouse
2011-03-15 9:11 ` [PATCH 02/15] GFS2: Post-VFS scale update for RCU path walk Steven Whitehouse
2011-03-15 9:11 ` [PATCH 03/15] GFS2: Fix glock queue trace point Steven Whitehouse
2011-03-15 9:11 ` [PATCH 04/15] GFS2: Improve cluster mmap scalability Steven Whitehouse
2011-03-15 9:11 ` [PATCH 05/15] GFS2: panics on quotacheck update Steven Whitehouse
2011-03-15 9:11 ` [PATCH 06/15] GFS2: deallocation performance patch Steven Whitehouse
2011-03-15 9:11 ` [PATCH 07/15] GFS2: quota allows exceeding hard limit Steven Whitehouse
2011-03-15 9:11 ` Steven Whitehouse [this message]
2011-03-15 9:11 ` [PATCH 09/15] GFS2: Remove potential race in flock code Steven Whitehouse
2011-03-15 9:11 ` [PATCH 10/15] GFS2: Optimize glock multiple-dequeue code Steven Whitehouse
2011-03-15 9:11 ` [PATCH 11/15] GFS2: fix block allocation check for fallocate Steven Whitehouse
2011-03-15 9:11 ` [PATCH 12/15] GFS2: introduce AIL lock Steven Whitehouse
2011-03-15 9:11 ` [PATCH 13/15] GFS2: Update to AIL list locking Steven Whitehouse
2011-03-15 9:11 ` [PATCH 14/15] GFS2: Adding missing unlock_page() Steven Whitehouse
2011-03-15 9:11 ` [PATCH 15/15] GFS2: Don't use _raw version of RCU dereference Steven Whitehouse
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1300180305-5993-9-git-send-email-swhiteho@redhat.com \
--to=swhiteho@redhat.com \
--cc=cluster-devel@redhat.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®