* [Cluster-devel] [GFS2 PATCH 1/3] GFS2: Eliminate a goto from function gfs2_inplace_reserve @ 2013-09-16 20:10 Bob Peterson 2013-09-16 20:10 ` [Cluster-devel] [GFS2 PATCH 2/3] GFS2: Drop initial reservation if too small Bob Peterson 2013-09-16 20:10 ` [Cluster-devel] [GFS2 PATCH 3/3] GFS2: Don't insert into reservations tree unless rgrp has enough blocks Bob Peterson 0 siblings, 2 replies; 5+ messages in thread From: Bob Peterson @ 2013-09-16 20:10 UTC (permalink / raw) To: cluster-devel.redhat.com This patch just refactors function gfs2_inplace_reserve in order to eliminate a goto. This is mainly just preparation for a future patch that will simplify the logic and improve performance. --- fs/gfs2/rgrp.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index e4f3362..8d5d583 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1899,19 +1899,17 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags) rg_mblk_search(rs->rs_rbm.rgd, ip, requested); /* Skip rgrps when we can't get a reservation on first pass */ - if (!gfs2_rs_active(rs) && (loops < 1)) - goto check_rgrp; + if (gfs2_rs_active(rs) || (loops >= 1)) { + /* If rgrp has enough free space, use it */ + if (rs->rs_rbm.rgd->rd_free_clone >= requested) { + ip->i_rgd = rs->rs_rbm.rgd; + return 0; + } - /* If rgrp has enough free space, use it */ - if (rs->rs_rbm.rgd->rd_free_clone >= requested) { - ip->i_rgd = rs->rs_rbm.rgd; - return 0; + /* Drop reservation if we couldn't use reserved rgrp */ + if (gfs2_rs_active(rs)) + gfs2_rs_deltree(rs); } - - /* Drop reservation, if we couldn't use reserved rgrp */ - if (gfs2_rs_active(rs)) - gfs2_rs_deltree(rs); -check_rgrp: /* Check for unlinked inodes which can be reclaimed */ if (rs->rs_rbm.rgd->rd_flags & GFS2_RDF_CHECK) try_rgrp_unlink(rs->rs_rbm.rgd, &last_unlinked, -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Cluster-devel] [GFS2 PATCH 2/3] GFS2: Drop initial reservation if too small 2013-09-16 20:10 [Cluster-devel] [GFS2 PATCH 1/3] GFS2: Eliminate a goto from function gfs2_inplace_reserve Bob Peterson @ 2013-09-16 20:10 ` Bob Peterson 2013-09-17 9:24 ` Steven Whitehouse 2013-09-16 20:10 ` [Cluster-devel] [GFS2 PATCH 3/3] GFS2: Don't insert into reservations tree unless rgrp has enough blocks Bob Peterson 1 sibling, 1 reply; 5+ messages in thread From: Bob Peterson @ 2013-09-16 20:10 UTC (permalink / raw) To: cluster-devel.redhat.com Before this patch, function gfs2_inplace_reserve would grab a blocking lock on the rgrp glock. This is not necessary if we already know that rgrp doesn't have enough blocks to satisfy the request. This patch makes the function drop the inadequate reservation so that a more suitable rgrp may be found (with a try lock). This is not a very important thing to do, and it still requires a blocking lock to remove the reservation. However, it allows us to further simplify the code with a future patch because after this patch, we will know for sure that the reservation will not be in the rgrp's reservations tree unless it has enough blocks. --- fs/gfs2/rgrp.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 8d5d583..ed57fdf 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1826,6 +1826,37 @@ static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *b } /** + * drop_if_too_small - Drop a reservation if it's too small. + * @rs: reservation to check + * @requested: number of blocks requested + * + * Returns: 0 if good + */ +static int drop_if_too_small(struct gfs2_blkreserv *rs, u32 requested) +{ + int rg_locked, error; + + if (rs->rs_rbm.rgd->rd_free_clone >= requested) + return 0; + + rg_locked = 0; + if (gfs2_glock_is_locked_by_me(rs->rs_rbm.rgd->rd_gl)) + rg_locked = 1; + + if (!rg_locked) { + error = gfs2_glock_nq_init(rs->rs_rbm.rgd->rd_gl, + LM_ST_EXCLUSIVE, 0, &rs->rs_rgd_gh); + if (unlikely(error)) + return error; + } + gfs2_rs_deltree(rs); + if (!rg_locked) + gfs2_glock_dq_uninit(&rs->rs_rgd_gh); + + return 0; +} + +/** * gfs2_inplace_reserve - Reserve space in the filesystem * @ip: the inode to reserve space for * @requested: the number of blocks to be reserved @@ -1849,10 +1880,16 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags) return -EINVAL; if (gfs2_rs_active(rs)) { begin = rs->rs_rbm.rgd; - } else if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) { - rs->rs_rbm.rgd = begin = ip->i_rgd; - } else { - rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1); + error = drop_if_too_small(rs, requested); + if (unlikely(error)) + return error; + } + if (!gfs2_rs_active(rs)) { + if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) { + rs->rs_rbm.rgd = begin = ip->i_rgd; + } else { + rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1); + } } if (S_ISDIR(ip->i_inode.i_mode) && (aflags & GFS2_AF_ORLOV)) skip = gfs2_orlov_skip(ip); -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Cluster-devel] [GFS2 PATCH 2/3] GFS2: Drop initial reservation if too small 2013-09-16 20:10 ` [Cluster-devel] [GFS2 PATCH 2/3] GFS2: Drop initial reservation if too small Bob Peterson @ 2013-09-17 9:24 ` Steven Whitehouse 2013-09-17 17:33 ` Bob Peterson 0 siblings, 1 reply; 5+ messages in thread From: Steven Whitehouse @ 2013-09-17 9:24 UTC (permalink / raw) To: cluster-devel.redhat.com Hi, On Mon, 2013-09-16 at 15:10 -0500, Bob Peterson wrote: > Before this patch, function gfs2_inplace_reserve would grab a blocking > lock on the rgrp glock. This is not necessary if we already know that > rgrp doesn't have enough blocks to satisfy the request. This patch > makes the function drop the inadequate reservation so that a more > suitable rgrp may be found (with a try lock). This is not a very > important thing to do, and it still requires a blocking lock to remove > the reservation. However, it allows us to further simplify the code > with a future patch because after this patch, we will know for sure > that the reservation will not be in the rgrp's reservations tree > unless it has enough blocks. > --- > fs/gfs2/rgrp.c | 45 +++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 41 insertions(+), 4 deletions(-) > This looks like the wrong thing to do. If we have a reservation, then we should always use it until it is used up, otherwise we are adding more fragmentation when we do not need to. The requested amount is supposed to be the number of blocks that we'd like to have in an ideal world, but provided we can supply the minimum number of blocks (currently 1) then there is no need to drop the reservation. Also, I don't want to reintroduce the try locks now that we've eliminated them from this part of the code, since that brings back another set of problems. Maybe I'm not understanding what the intent is here though as despite the comment above, the patches don't appear to actually bring the try lock back. postmark only tends to write very small files, depending on what settings it is being run with, so will likely not gain from the reservations work at all. The main reason for using it is to ensure that we don't get a regression rather than expecting it to show any improvements. Steve. > diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c > index 8d5d583..ed57fdf 100644 > --- a/fs/gfs2/rgrp.c > +++ b/fs/gfs2/rgrp.c > @@ -1826,6 +1826,37 @@ static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *b > } > > /** > + * drop_if_too_small - Drop a reservation if it's too small. > + * @rs: reservation to check > + * @requested: number of blocks requested > + * > + * Returns: 0 if good > + */ > +static int drop_if_too_small(struct gfs2_blkreserv *rs, u32 requested) > +{ > + int rg_locked, error; > + > + if (rs->rs_rbm.rgd->rd_free_clone >= requested) > + return 0; > + > + rg_locked = 0; > + if (gfs2_glock_is_locked_by_me(rs->rs_rbm.rgd->rd_gl)) > + rg_locked = 1; > + > + if (!rg_locked) { > + error = gfs2_glock_nq_init(rs->rs_rbm.rgd->rd_gl, > + LM_ST_EXCLUSIVE, 0, &rs->rs_rgd_gh); > + if (unlikely(error)) > + return error; > + } > + gfs2_rs_deltree(rs); > + if (!rg_locked) > + gfs2_glock_dq_uninit(&rs->rs_rgd_gh); > + > + return 0; > +} > + > +/** > * gfs2_inplace_reserve - Reserve space in the filesystem > * @ip: the inode to reserve space for > * @requested: the number of blocks to be reserved > @@ -1849,10 +1880,16 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags) > return -EINVAL; > if (gfs2_rs_active(rs)) { > begin = rs->rs_rbm.rgd; > - } else if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) { > - rs->rs_rbm.rgd = begin = ip->i_rgd; > - } else { > - rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1); > + error = drop_if_too_small(rs, requested); > + if (unlikely(error)) > + return error; > + } > + if (!gfs2_rs_active(rs)) { > + if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) { > + rs->rs_rbm.rgd = begin = ip->i_rgd; > + } else { > + rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1); > + } > } > if (S_ISDIR(ip->i_inode.i_mode) && (aflags & GFS2_AF_ORLOV)) > skip = gfs2_orlov_skip(ip); ^ permalink raw reply [flat|nested] 5+ messages in thread
* [Cluster-devel] [GFS2 PATCH 2/3] GFS2: Drop initial reservation if too small 2013-09-17 9:24 ` Steven Whitehouse @ 2013-09-17 17:33 ` Bob Peterson 0 siblings, 0 replies; 5+ messages in thread From: Bob Peterson @ 2013-09-17 17:33 UTC (permalink / raw) To: cluster-devel.redhat.com ----- Original Message ----- | Hi, | | On Mon, 2013-09-16 at 15:10 -0500, Bob Peterson wrote: | > Before this patch, function gfs2_inplace_reserve would grab a blocking | > lock on the rgrp glock. This is not necessary if we already know that | > rgrp doesn't have enough blocks to satisfy the request. This patch | > makes the function drop the inadequate reservation so that a more | > suitable rgrp may be found (with a try lock). This is not a very | > important thing to do, and it still requires a blocking lock to remove | > the reservation. However, it allows us to further simplify the code | > with a future patch because after this patch, we will know for sure | > that the reservation will not be in the rgrp's reservations tree | > unless it has enough blocks. | > --- | > fs/gfs2/rgrp.c | 45 +++++++++++++++++++++++++++++++++++++++++---- | > 1 file changed, 41 insertions(+), 4 deletions(-) | > | This looks like the wrong thing to do. If we have a reservation, then we | should always use it until it is used up, otherwise we are adding more | fragmentation when we do not need to. The requested amount is supposed | to be the number of blocks that we'd like to have in an ideal world, but | provided we can supply the minimum number of blocks (currently 1) then | there is no need to drop the reservation. | | Also, I don't want to reintroduce the try locks now that we've | eliminated them from this part of the code, since that brings back | another set of problems. Maybe I'm not understanding what the intent is | here though as despite the comment above, the patches don't appear to | actually bring the try lock back. | | postmark only tends to write very small files, depending on what | settings it is being run with, so will likely not gain from the | reservations work at all. The main reason for using it is to ensure that | we don't get a regression rather than expecting it to show any | improvements. | | Steve. Hi, Actually, unless I'm reading the code wrong, it already does this. If this is the wrong thing to do, we need to change the logic. In today's gfs2_inplace_reserve, there's a check: if (rs->rs_rbm.rgd->rd_free_clone >= requested) { ip->i_rgd = rs->rs_rbm.rgd; return 0; } (otherwise it gets rejected) This similarly rejects any pre-existing reservation if it doesn't satisfy the requested size. What I was trying to do here is preserve the existing logic. If it's wrong and we need to change it, that's fine, but I have doubts that it will pass all the testing; when I was working on the block reservations code, I believe I tried that and got into some nasty problems. Still, it may be worth trying again. Regards, Bob Peterson Red Hat File Systems ^ permalink raw reply [flat|nested] 5+ messages in thread
* [Cluster-devel] [GFS2 PATCH 3/3] GFS2: Don't insert into reservations tree unless rgrp has enough blocks 2013-09-16 20:10 [Cluster-devel] [GFS2 PATCH 1/3] GFS2: Eliminate a goto from function gfs2_inplace_reserve Bob Peterson 2013-09-16 20:10 ` [Cluster-devel] [GFS2 PATCH 2/3] GFS2: Drop initial reservation if too small Bob Peterson @ 2013-09-16 20:10 ` Bob Peterson 1 sibling, 0 replies; 5+ messages in thread From: Bob Peterson @ 2013-09-16 20:10 UTC (permalink / raw) To: cluster-devel.redhat.com The previous two patches simplified the logic in gfs2_inplace_reserve and ensured that inadequate reservations are dropped before we enter the main loop. This patch takes the next logical step and makes sure that new reservations don't get inserted into the rgrp reservations tree unless they are also adequate. So now we don't have to repeatly insert a reservation, determine it's inadequate, then remove it from the tree again. We can take a proactive approach that says: Only insert it if it's adequate. That's makes the code a little faster. --- fs/gfs2/rgrp.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index ed57fdf..59637ab 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1455,7 +1455,7 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip, return; ret = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, extlen, ip, true); - if (ret == 0) { + if (ret == 0 && rgd->rd_free_clone >= requested) { rs->rs_rbm = rbm; rs->rs_free = extlen; rs->rs_inum = ip->i_no_addr; @@ -1936,16 +1936,11 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags) rg_mblk_search(rs->rs_rbm.rgd, ip, requested); /* Skip rgrps when we can't get a reservation on first pass */ - if (gfs2_rs_active(rs) || (loops >= 1)) { - /* If rgrp has enough free space, use it */ - if (rs->rs_rbm.rgd->rd_free_clone >= requested) { - ip->i_rgd = rs->rs_rbm.rgd; - return 0; - } - - /* Drop reservation if we couldn't use reserved rgrp */ - if (gfs2_rs_active(rs)) - gfs2_rs_deltree(rs); + if (gfs2_rs_active(rs) || + ((loops >= 1) && + (rs->rs_rbm.rgd->rd_free_clone >= requested))) { + ip->i_rgd = rs->rs_rbm.rgd; + return 0; } /* Check for unlinked inodes which can be reclaimed */ if (rs->rs_rbm.rgd->rd_flags & GFS2_RDF_CHECK) -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-09-17 17:33 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-09-16 20:10 [Cluster-devel] [GFS2 PATCH 1/3] GFS2: Eliminate a goto from function gfs2_inplace_reserve Bob Peterson 2013-09-16 20:10 ` [Cluster-devel] [GFS2 PATCH 2/3] GFS2: Drop initial reservation if too small Bob Peterson 2013-09-17 9:24 ` Steven Whitehouse 2013-09-17 17:33 ` Bob Peterson 2013-09-16 20:10 ` [Cluster-devel] [GFS2 PATCH 3/3] GFS2: Don't insert into reservations tree unless rgrp has enough blocks Bob Peterson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).