diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2010-11-30 10:49:31 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2010-11-30 10:49:31 -0500 |
commit | 47a25380e37f44db7202093ca92e4af569c34f55 (patch) | |
tree | db3e6dba3859c5562b9a86f6d4059519fa7a1c52 | |
parent | e06dfc492870e1d380f02722cde084b724dc197b (diff) |
GFS2: Merge glock state fields into a bitfield
We can only merge the fields into a bitfield if the locking
rules for them are the same. In this case gl_spin covers all
of the fields (write side) but a couple of them are used
with GLF_LOCK as the read side lock, which should be ok
since we know that the field in question won't be changing
at the time.
The gl_req setting has to be done earlier (in glock.c) in order
to place it under gl_spin. The gl_reply setting also has to be
brought under gl_spin in order to comply with the new rules.
This saves 4*sizeof(unsigned int) per glock.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Cc: Bob Peterson <rpeterso@redhat.com>
-rw-r--r-- | fs/gfs2/glock.c | 9 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 12 | ||||
-rw-r--r-- | fs/gfs2/lock_dlm.c | 1 |
3 files changed, 14 insertions, 8 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 2dd1d7238111..08a8beb152e6 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -567,6 +567,7 @@ __acquires(&gl->gl_spin) | |||
567 | set_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags); | 567 | set_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags); |
568 | do_error(gl, 0); /* Fail queued try locks */ | 568 | do_error(gl, 0); /* Fail queued try locks */ |
569 | } | 569 | } |
570 | gl->gl_req = target; | ||
570 | spin_unlock(&gl->gl_spin); | 571 | spin_unlock(&gl->gl_spin); |
571 | if (glops->go_xmote_th) | 572 | if (glops->go_xmote_th) |
572 | glops->go_xmote_th(gl); | 573 | glops->go_xmote_th(gl); |
@@ -1353,24 +1354,28 @@ static int gfs2_should_freeze(const struct gfs2_glock *gl) | |||
1353 | * @gl: Pointer to the glock | 1354 | * @gl: Pointer to the glock |
1354 | * @ret: The return value from the dlm | 1355 | * @ret: The return value from the dlm |
1355 | * | 1356 | * |
1357 | * The gl_reply field is under the gl_spin lock so that it is ok | ||
1358 | * to use a bitfield shared with other glock state fields. | ||
1356 | */ | 1359 | */ |
1357 | 1360 | ||
1358 | void gfs2_glock_complete(struct gfs2_glock *gl, int ret) | 1361 | void gfs2_glock_complete(struct gfs2_glock *gl, int ret) |
1359 | { | 1362 | { |
1360 | struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct; | 1363 | struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct; |
1361 | 1364 | ||
1365 | spin_lock(&gl->gl_spin); | ||
1362 | gl->gl_reply = ret; | 1366 | gl->gl_reply = ret; |
1363 | 1367 | ||
1364 | if (unlikely(test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags))) { | 1368 | if (unlikely(test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags))) { |
1365 | spin_lock(&gl->gl_spin); | ||
1366 | if (gfs2_should_freeze(gl)) { | 1369 | if (gfs2_should_freeze(gl)) { |
1367 | set_bit(GLF_FROZEN, &gl->gl_flags); | 1370 | set_bit(GLF_FROZEN, &gl->gl_flags); |
1368 | spin_unlock(&gl->gl_spin); | 1371 | spin_unlock(&gl->gl_spin); |
1369 | return; | 1372 | return; |
1370 | } | 1373 | } |
1371 | spin_unlock(&gl->gl_spin); | ||
1372 | } | 1374 | } |
1375 | |||
1376 | spin_unlock(&gl->gl_spin); | ||
1373 | set_bit(GLF_REPLY_PENDING, &gl->gl_flags); | 1377 | set_bit(GLF_REPLY_PENDING, &gl->gl_flags); |
1378 | smp_wmb(); | ||
1374 | gfs2_glock_hold(gl); | 1379 | gfs2_glock_hold(gl); |
1375 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 1380 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
1376 | gfs2_glock_put(gl); | 1381 | gfs2_glock_put(gl); |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 764fbb49efc8..8d3d2b4a0a7d 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -207,12 +207,14 @@ struct gfs2_glock { | |||
207 | 207 | ||
208 | spinlock_t gl_spin; | 208 | spinlock_t gl_spin; |
209 | 209 | ||
210 | unsigned int gl_state; | 210 | /* State fields protected by gl_spin */ |
211 | unsigned int gl_target; | 211 | unsigned int gl_state:2, /* Current state */ |
212 | unsigned int gl_reply; | 212 | gl_target:2, /* Target state */ |
213 | gl_demote_state:2, /* State requested by remote node */ | ||
214 | gl_req:2, /* State in last dlm request */ | ||
215 | gl_reply:8; /* Last reply from the dlm */ | ||
216 | |||
213 | unsigned int gl_hash; | 217 | unsigned int gl_hash; |
214 | unsigned int gl_req; | ||
215 | unsigned int gl_demote_state; /* state requested by remote node */ | ||
216 | unsigned long gl_demote_time; /* time of first demote request */ | 218 | unsigned long gl_demote_time; /* time of first demote request */ |
217 | struct list_head gl_holders; | 219 | struct list_head gl_holders; |
218 | 220 | ||
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index f40ce34c803e..6e493aee28f8 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c | |||
@@ -153,7 +153,6 @@ static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state, | |||
153 | int req; | 153 | int req; |
154 | u32 lkf; | 154 | u32 lkf; |
155 | 155 | ||
156 | gl->gl_req = req_state; | ||
157 | req = make_mode(req_state); | 156 | req = make_mode(req_state); |
158 | lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req); | 157 | lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req); |
159 | 158 | ||