Commit eaf5bd3c authored by Steven Whitehouse's avatar Steven Whitehouse

[GFS2] Simplify multiple glock aquisition

There is a bug in the code which acquires multiple glocks where if the
initial out-of-order attempt fails part way though we can land up trying
to acquire the wrong number of glocks. This is part of the fix for red
hat bz #239737. The other part of the bz doesn't apply to upstream
kernels since it was fixed by:

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=d3717bdf8f08a0e1039158c8bab2c24d20f492b6

Since the out-of-order code doesn't appear to add anything to the
performance of GFS2, this patch just removed it rather than trying to
fix it. It should be much easier to see whats going on here now. In
addition, we don't allocate any memory unless we are using a lot of
glocks (which is a relatively uncommon case).
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent 2332c443
...@@ -1327,10 +1327,6 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs, ...@@ -1327,10 +1327,6 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs,
* @num_gh: the number of structures * @num_gh: the number of structures
* @ghs: an array of struct gfs2_holder structures * @ghs: an array of struct gfs2_holder structures
* *
* Figure out how big an impact this function has. Either:
* 1) Replace this code with code that calls gfs2_glock_prefetch()
* 2) Forget async stuff and just call nq_m_sync()
* 3) Leave it like it is
* *
* Returns: 0 on success (all glocks acquired), * Returns: 0 on success (all glocks acquired),
* errno on failure (no glocks acquired) * errno on failure (no glocks acquired)
...@@ -1338,62 +1334,28 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs, ...@@ -1338,62 +1334,28 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs,
int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs) int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs)
{ {
int *e; struct gfs2_holder *tmp[4];
unsigned int x; struct gfs2_holder **pph = tmp;
int borked = 0, serious = 0;
int error = 0; int error = 0;
if (!num_gh) switch(num_gh) {
case 0:
return 0; return 0;
case 1:
if (num_gh == 1) {
ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
return gfs2_glock_nq(ghs); return gfs2_glock_nq(ghs);
} default:
if (num_gh <= 4)
e = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL);
if (!e)
return -ENOMEM;
for (x = 0; x < num_gh; x++) {
ghs[x].gh_flags |= LM_FLAG_TRY | GL_ASYNC;
error = gfs2_glock_nq(&ghs[x]);
if (error) {
borked = 1;
serious = error;
num_gh = x;
break; break;
pph = kmalloc(num_gh * sizeof(struct gfs2_holder *), GFP_NOFS);
if (!pph)
return -ENOMEM;
} }
}
for (x = 0; x < num_gh; x++) {
error = e[x] = glock_wait_internal(&ghs[x]);
if (error) {
borked = 1;
if (error != GLR_TRYFAILED && error != GLR_CANCELED)
serious = error;
}
}
if (!borked) {
kfree(e);
return 0;
}
for (x = 0; x < num_gh; x++)
if (!e[x])
gfs2_glock_dq(&ghs[x]);
if (serious) error = nq_m_sync(num_gh, ghs, pph);
error = serious;
else {
for (x = 0; x < num_gh; x++)
gfs2_holder_reinit(ghs[x].gh_state, ghs[x].gh_flags,
&ghs[x]);
error = nq_m_sync(num_gh, ghs, (struct gfs2_holder **)e);
}
kfree(e); if (pph != tmp)
kfree(pph);
return error; return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment