Skip to content

Commit adbc76a

Browse files
Christoph HellwigDarrick J. Wong
authored andcommitted
xfs: convert busy extent tracking to the generic group structure
Split busy extent tracking from struct xfs_perag into its own private structure, which can be pointed to by the generic group structure. Note that this structure is now dynamically allocated instead of embedded as the upcoming zone XFS code doesn't need it and will also have an unusually high number of groups due to hardware constraints. Dynamically allocating the structure this is a big memory saver for this case. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent 0e10cb9 commit adbc76a

File tree

12 files changed

+193
-151
lines changed

12 files changed

+193
-151
lines changed

fs/xfs/libxfs/xfs_ag.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,8 @@ xfs_perag_alloc(
230230
#ifdef __KERNEL__
231231
/* Place kernel structure only init below this point. */
232232
spin_lock_init(&pag->pag_ici_lock);
233-
spin_lock_init(&pag->pagb_lock);
234233
INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
235234
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
236-
init_waitqueue_head(&pag->pagb_wait);
237-
pag->pagb_tree = RB_ROOT;
238235
#endif /* __KERNEL__ */
239236

240237
error = xfs_buf_cache_init(&pag->pag_bcache);

fs/xfs/libxfs/xfs_ag.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,6 @@ struct xfs_perag {
8080
uint8_t pagf_repair_rmap_level;
8181
#endif
8282

83-
spinlock_t pagb_lock; /* lock for pagb_tree */
84-
struct rb_root pagb_tree; /* ordered tree of busy extents */
85-
unsigned int pagb_gen; /* generation count for pagb_tree */
86-
wait_queue_head_t pagb_wait; /* woken when pagb_gen changes */
87-
8883
atomic_t pagf_fstrms; /* # of filestreams active in this AG */
8984

9085
spinlock_t pag_ici_lock; /* incore inode cache lock */

fs/xfs/libxfs/xfs_alloc.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,8 @@ xfs_alloc_compute_aligned(
331331
bool busy;
332332

333333
/* Trim busy sections out of found extent */
334-
busy = xfs_extent_busy_trim(args, &bno, &len, busy_gen);
334+
busy = xfs_extent_busy_trim(pag_group(args->pag), args->minlen,
335+
args->maxlen, &bno, &len, busy_gen);
335336

336337
/*
337338
* If we have a largish extent that happens to start before min_agbno,
@@ -1251,7 +1252,7 @@ xfs_alloc_ag_vextent_small(
12511252
if (fbno == NULLAGBLOCK)
12521253
goto out;
12531254

1254-
xfs_extent_busy_reuse(args->pag, fbno, 1,
1255+
xfs_extent_busy_reuse(pag_group(args->pag), fbno, 1,
12551256
(args->datatype & XFS_ALLOC_NOBUSY));
12561257

12571258
if (args->datatype & XFS_ALLOC_USERDATA) {
@@ -1364,7 +1365,8 @@ xfs_alloc_ag_vextent_exact(
13641365
*/
13651366
tbno = fbno;
13661367
tlen = flen;
1367-
xfs_extent_busy_trim(args, &tbno, &tlen, &busy_gen);
1368+
xfs_extent_busy_trim(pag_group(args->pag), args->minlen, args->maxlen,
1369+
&tbno, &tlen, &busy_gen);
13681370

13691371
/*
13701372
* Give up if the start of the extent is busy, or the freespace isn't
@@ -1757,8 +1759,9 @@ xfs_alloc_ag_vextent_near(
17571759
* the allocation can be retried.
17581760
*/
17591761
trace_xfs_alloc_near_busy(args);
1760-
error = xfs_extent_busy_flush(args->tp, args->pag,
1761-
acur.busy_gen, alloc_flags);
1762+
error = xfs_extent_busy_flush(args->tp,
1763+
pag_group(args->pag), acur.busy_gen,
1764+
alloc_flags);
17621765
if (error)
17631766
goto out;
17641767

@@ -1873,8 +1876,9 @@ xfs_alloc_ag_vextent_size(
18731876
* the allocation can be retried.
18741877
*/
18751878
trace_xfs_alloc_size_busy(args);
1876-
error = xfs_extent_busy_flush(args->tp, args->pag,
1877-
busy_gen, alloc_flags);
1879+
error = xfs_extent_busy_flush(args->tp,
1880+
pag_group(args->pag), busy_gen,
1881+
alloc_flags);
18781882
if (error)
18791883
goto error0;
18801884

@@ -1972,8 +1976,9 @@ xfs_alloc_ag_vextent_size(
19721976
* the allocation can be retried.
19731977
*/
19741978
trace_xfs_alloc_size_busy(args);
1975-
error = xfs_extent_busy_flush(args->tp, args->pag,
1976-
busy_gen, alloc_flags);
1979+
error = xfs_extent_busy_flush(args->tp,
1980+
pag_group(args->pag), busy_gen,
1981+
alloc_flags);
19771982
if (error)
19781983
goto error0;
19791984

@@ -3615,8 +3620,8 @@ xfs_alloc_vextent_finish(
36153620
if (error)
36163621
goto out_drop_perag;
36173622

3618-
ASSERT(!xfs_extent_busy_search(args->pag, args->agbno,
3619-
args->len));
3623+
ASSERT(!xfs_extent_busy_search(pag_group(args->pag),
3624+
args->agbno, args->len));
36203625
}
36213626

36223627
xfs_ag_resv_alloc_extent(args->pag, args->resv, args);
@@ -4014,7 +4019,7 @@ __xfs_free_extent(
40144019

40154020
if (skip_discard)
40164021
busy_flags |= XFS_EXTENT_BUSY_SKIP_DISCARD;
4017-
xfs_extent_busy_insert(tp, pag, agbno, len, busy_flags);
4022+
xfs_extent_busy_insert(tp, pag_group(pag), agbno, len, busy_flags);
40184023
return 0;
40194024

40204025
err_release:

fs/xfs/libxfs/xfs_alloc_btree.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ xfs_allocbt_alloc_block(
8686
}
8787

8888
atomic64_inc(&cur->bc_mp->m_allocbt_blks);
89-
xfs_extent_busy_reuse(cur->bc_ag.pag, bno, 1, false);
89+
xfs_extent_busy_reuse(pag_group(cur->bc_ag.pag), bno, 1, false);
9090

9191
new->s = cpu_to_be32(bno);
9292

@@ -110,7 +110,7 @@ xfs_allocbt_free_block(
110110
return error;
111111

112112
atomic64_dec(&cur->bc_mp->m_allocbt_blks);
113-
xfs_extent_busy_insert(cur->bc_tp, agbp->b_pag, bno, 1,
113+
xfs_extent_busy_insert(cur->bc_tp, pag_group(agbp->b_pag), bno, 1,
114114
XFS_EXTENT_BUSY_SKIP_DISCARD);
115115
return 0;
116116
}

fs/xfs/libxfs/xfs_group.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "xfs_mount.h"
1111
#include "xfs_error.h"
1212
#include "xfs_trace.h"
13+
#include "xfs_extent_busy.h"
1314
#include "xfs_group.h"
1415

1516
/*
@@ -161,6 +162,9 @@ xfs_group_free(
161162
XFS_IS_CORRUPT(mp, atomic_read(&xg->xg_ref) != 0);
162163

163164
xfs_defer_drain_free(&xg->xg_intents_drain);
165+
#ifdef __KERNEL__
166+
kfree(xg->xg_busy_extents);
167+
#endif
164168

165169
if (uninit)
166170
uninit(xg);
@@ -185,6 +189,9 @@ xfs_group_insert(
185189
xg->xg_type = type;
186190

187191
#ifdef __KERNEL__
192+
xg->xg_busy_extents = xfs_extent_busy_alloc();
193+
if (!xg->xg_busy_extents)
194+
return -ENOMEM;
188195
spin_lock_init(&xg->xg_state_lock);
189196
xfs_hooks_init(&xg->xg_rmap_update_hooks);
190197
#endif
@@ -196,9 +203,14 @@ xfs_group_insert(
196203
error = xa_insert(&mp->m_groups[type].xa, index, xg, GFP_KERNEL);
197204
if (error) {
198205
WARN_ON_ONCE(error == -EBUSY);
199-
xfs_defer_drain_free(&xg->xg_intents_drain);
200-
return error;
206+
goto out_drain;
201207
}
202208

203209
return 0;
210+
out_drain:
211+
xfs_defer_drain_free(&xg->xg_intents_drain);
212+
#ifdef __KERNEL__
213+
kfree(xg->xg_busy_extents);
214+
#endif
215+
return error;
204216
}

fs/xfs/libxfs/xfs_group.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ struct xfs_group {
1515
#ifdef __KERNEL__
1616
/* -- kernel only structures below this line -- */
1717

18+
/*
19+
* Track freed but not yet committed extents.
20+
*/
21+
struct xfs_extent_busy_tree *xg_busy_extents;
22+
1823
/*
1924
* Bitsets of per-ag metadata that have been checked and/or are sick.
2025
* Callers should hold xg_state_lock before accessing this field.

fs/xfs/libxfs/xfs_rmap_btree.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ xfs_rmapbt_alloc_block(
102102
return 0;
103103
}
104104

105-
xfs_extent_busy_reuse(pag, bno, 1, false);
105+
xfs_extent_busy_reuse(pag_group(pag), bno, 1, false);
106106

107107
new->s = cpu_to_be32(bno);
108108
be32_add_cpu(&agf->agf_rmap_blocks, 1);
@@ -136,7 +136,7 @@ xfs_rmapbt_free_block(
136136
if (error)
137137
return error;
138138

139-
xfs_extent_busy_insert(cur->bc_tp, pag, bno, 1,
139+
xfs_extent_busy_insert(cur->bc_tp, pag_group(pag), bno, 1,
140140
XFS_EXTENT_BUSY_SKIP_DISCARD);
141141

142142
xfs_ag_resv_free_extent(pag, XFS_AG_RESV_RMAPBT, NULL, 1);

fs/xfs/scrub/alloc_repair.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,16 @@ int
132132
xrep_setup_ag_allocbt(
133133
struct xfs_scrub *sc)
134134
{
135+
struct xfs_group *xg = pag_group(sc->sa.pag);
136+
unsigned int busy_gen;
137+
135138
/*
136139
* Make sure the busy extent list is clear because we can't put extents
137140
* on there twice.
138141
*/
139-
if (xfs_extent_busy_list_empty(sc->sa.pag, &busy_gen))
142+
if (xfs_extent_busy_list_empty(xg, &busy_gen))
140143
return 0;
141-
return xfs_extent_busy_flush(sc->tp, sc->sa.pag, busy_gen, 0);
144+
return xfs_extent_busy_flush(sc->tp, xg, busy_gen, 0);
142145
}
143146

144147
/* Check for any obvious conflicts in the free extent. */
@@ -866,7 +869,7 @@ xrep_allocbt(
866869
* on there twice. In theory we cleared this before we started, but
867870
* let's not risk the filesystem.
868871
*/
869-
if (!xfs_extent_busy_list_empty(sc->sa.pag, &busy_gen)) {
872+
if (!xfs_extent_busy_list_empty(pag_group(sc->sa.pag), &busy_gen)) {
870873
error = -EDEADLOCK;
871874
goto out_ra;
872875
}

fs/xfs/scrub/reap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ xreap_put_freelist(
137137
agfl_bp, agbno, 0);
138138
if (error)
139139
return error;
140-
xfs_extent_busy_insert(sc->tp, sc->sa.pag, agbno, 1,
140+
xfs_extent_busy_insert(sc->tp, pag_group(sc->sa.pag), agbno, 1,
141141
XFS_EXTENT_BUSY_SKIP_DISCARD);
142142

143143
return 0;

fs/xfs/xfs_discard.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,12 @@ xfs_discard_extents(
117117

118118
blk_start_plug(&plug);
119119
list_for_each_entry(busyp, &extents->extent_list, list) {
120-
trace_xfs_discard_extent(busyp->pag, busyp->bno, busyp->length);
120+
struct xfs_perag *pag = to_perag(busyp->group);
121+
122+
trace_xfs_discard_extent(pag, busyp->bno, busyp->length);
121123

122124
error = __blkdev_issue_discard(mp->m_ddev_targp->bt_bdev,
123-
xfs_agbno_to_daddr(busyp->pag, busyp->bno),
125+
xfs_agbno_to_daddr(pag, busyp->bno),
124126
XFS_FSB_TO_BB(mp, busyp->length),
125127
GFP_KERNEL, &bio);
126128
if (error && error != -EOPNOTSUPP) {
@@ -271,12 +273,12 @@ xfs_trim_gather_extents(
271273
* If any blocks in the range are still busy, skip the
272274
* discard and try again the next time.
273275
*/
274-
if (xfs_extent_busy_search(pag, fbno, flen)) {
276+
if (xfs_extent_busy_search(pag_group(pag), fbno, flen)) {
275277
trace_xfs_discard_busy(pag, fbno, flen);
276278
goto next_extent;
277279
}
278280

279-
xfs_extent_busy_insert_discard(pag, fbno, flen,
281+
xfs_extent_busy_insert_discard(pag_group(pag), fbno, flen,
280282
&extents->extent_list);
281283
next_extent:
282284
if (tcur->by_bno)

0 commit comments

Comments
 (0)