Skip to content

Commit f3c799c

Browse files
author
Darrick J. Wong
committed
xfs: create slab caches for frequently-used deferred items
Create slab caches for the high-level structures that coordinate deferred intent items, since they're used fairly heavily. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Chandan Babu R <[email protected]>
1 parent 9e25395 commit f3c799c

File tree

12 files changed

+154
-16
lines changed

12 files changed

+154
-16
lines changed

fs/xfs/libxfs/xfs_bmap.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#include "xfs_icache.h"
3838
#include "xfs_iomap.h"
3939

40-
40+
struct kmem_cache *xfs_bmap_intent_cache;
4141
struct kmem_cache *xfs_bmap_free_item_cache;
4242

4343
/*
@@ -6190,7 +6190,7 @@ __xfs_bmap_add(
61906190
bmap->br_blockcount,
61916191
bmap->br_state);
61926192

6193-
bi = kmem_alloc(sizeof(struct xfs_bmap_intent), KM_NOFS);
6193+
bi = kmem_cache_alloc(xfs_bmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
61946194
INIT_LIST_HEAD(&bi->bi_list);
61956195
bi->bi_type = type;
61966196
bi->bi_owner = ip;
@@ -6301,3 +6301,20 @@ xfs_bmap_validate_extent(
63016301
return __this_address;
63026302
return NULL;
63036303
}
6304+
6305+
int __init
6306+
xfs_bmap_intent_init_cache(void)
6307+
{
6308+
xfs_bmap_intent_cache = kmem_cache_create("xfs_bmap_intent",
6309+
sizeof(struct xfs_bmap_intent),
6310+
0, 0, NULL);
6311+
6312+
return xfs_bmap_intent_cache != NULL ? 0 : -ENOMEM;
6313+
}
6314+
6315+
void
6316+
xfs_bmap_intent_destroy_cache(void)
6317+
{
6318+
kmem_cache_destroy(xfs_bmap_intent_cache);
6319+
xfs_bmap_intent_cache = NULL;
6320+
}

fs/xfs/libxfs/xfs_bmap.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,4 +290,9 @@ int xfs_bmapi_remap(struct xfs_trans *tp, struct xfs_inode *ip,
290290
xfs_fileoff_t bno, xfs_filblks_t len, xfs_fsblock_t startblock,
291291
int flags);
292292

293+
extern struct kmem_cache *xfs_bmap_intent_cache;
294+
295+
int __init xfs_bmap_intent_init_cache(void);
296+
void xfs_bmap_intent_destroy_cache(void);
297+
293298
#endif /* __XFS_BMAP_H__ */

fs/xfs/libxfs/xfs_defer.c

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
#include "xfs_trace.h"
1919
#include "xfs_icache.h"
2020
#include "xfs_log.h"
21+
#include "xfs_rmap.h"
22+
#include "xfs_refcount.h"
23+
#include "xfs_bmap.h"
24+
25+
static struct kmem_cache *xfs_defer_pending_cache;
2126

2227
/*
2328
* Deferred Operations in XFS
@@ -365,7 +370,7 @@ xfs_defer_cancel_list(
365370
ops->cancel_item(pwi);
366371
}
367372
ASSERT(dfp->dfp_count == 0);
368-
kmem_free(dfp);
373+
kmem_cache_free(xfs_defer_pending_cache, dfp);
369374
}
370375
}
371376

@@ -462,7 +467,7 @@ xfs_defer_finish_one(
462467

463468
/* Done with the dfp, free it. */
464469
list_del(&dfp->dfp_list);
465-
kmem_free(dfp);
470+
kmem_cache_free(xfs_defer_pending_cache, dfp);
466471
out:
467472
if (ops->finish_cleanup)
468473
ops->finish_cleanup(tp, state, error);
@@ -596,8 +601,8 @@ xfs_defer_add(
596601
dfp = NULL;
597602
}
598603
if (!dfp) {
599-
dfp = kmem_alloc(sizeof(struct xfs_defer_pending),
600-
KM_NOFS);
604+
dfp = kmem_cache_zalloc(xfs_defer_pending_cache,
605+
GFP_NOFS | __GFP_NOFAIL);
601606
dfp->dfp_type = type;
602607
dfp->dfp_intent = NULL;
603608
dfp->dfp_done = NULL;
@@ -809,3 +814,55 @@ xfs_defer_resources_rele(
809814
dres->dr_bufs = 0;
810815
dres->dr_ordered = 0;
811816
}
817+
818+
static inline int __init
819+
xfs_defer_init_cache(void)
820+
{
821+
xfs_defer_pending_cache = kmem_cache_create("xfs_defer_pending",
822+
sizeof(struct xfs_defer_pending),
823+
0, 0, NULL);
824+
825+
return xfs_defer_pending_cache != NULL ? 0 : -ENOMEM;
826+
}
827+
828+
static inline void
829+
xfs_defer_destroy_cache(void)
830+
{
831+
kmem_cache_destroy(xfs_defer_pending_cache);
832+
xfs_defer_pending_cache = NULL;
833+
}
834+
835+
/* Set up caches for deferred work items. */
836+
int __init
837+
xfs_defer_init_item_caches(void)
838+
{
839+
int error;
840+
841+
error = xfs_defer_init_cache();
842+
if (error)
843+
return error;
844+
error = xfs_rmap_intent_init_cache();
845+
if (error)
846+
goto err;
847+
error = xfs_refcount_intent_init_cache();
848+
if (error)
849+
goto err;
850+
error = xfs_bmap_intent_init_cache();
851+
if (error)
852+
goto err;
853+
854+
return 0;
855+
err:
856+
xfs_defer_destroy_item_caches();
857+
return error;
858+
}
859+
860+
/* Destroy all the deferred work item caches, if they've been allocated. */
861+
void
862+
xfs_defer_destroy_item_caches(void)
863+
{
864+
xfs_bmap_intent_destroy_cache();
865+
xfs_refcount_intent_destroy_cache();
866+
xfs_rmap_intent_destroy_cache();
867+
xfs_defer_destroy_cache();
868+
}

fs/xfs/libxfs/xfs_defer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,7 @@ void xfs_defer_ops_capture_free(struct xfs_mount *mp,
122122
struct xfs_defer_capture *d);
123123
void xfs_defer_resources_rele(struct xfs_defer_resources *dres);
124124

125+
int __init xfs_defer_init_item_caches(void);
126+
void xfs_defer_destroy_item_caches(void);
127+
125128
#endif /* __XFS_DEFER_H__ */

fs/xfs/libxfs/xfs_refcount.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include "xfs_rmap.h"
2525
#include "xfs_ag.h"
2626

27+
struct kmem_cache *xfs_refcount_intent_cache;
28+
2729
/* Allowable refcount adjustment amounts. */
2830
enum xfs_refc_adjust_op {
2931
XFS_REFCOUNT_ADJUST_INCREASE = 1,
@@ -1235,8 +1237,8 @@ __xfs_refcount_add(
12351237
type, XFS_FSB_TO_AGBNO(tp->t_mountp, startblock),
12361238
blockcount);
12371239

1238-
ri = kmem_alloc(sizeof(struct xfs_refcount_intent),
1239-
KM_NOFS);
1240+
ri = kmem_cache_alloc(xfs_refcount_intent_cache,
1241+
GFP_NOFS | __GFP_NOFAIL);
12401242
INIT_LIST_HEAD(&ri->ri_list);
12411243
ri->ri_type = type;
12421244
ri->ri_startblock = startblock;
@@ -1782,3 +1784,20 @@ xfs_refcount_has_record(
17821784

17831785
return xfs_btree_has_record(cur, &low, &high, exists);
17841786
}
1787+
1788+
int __init
1789+
xfs_refcount_intent_init_cache(void)
1790+
{
1791+
xfs_refcount_intent_cache = kmem_cache_create("xfs_refc_intent",
1792+
sizeof(struct xfs_refcount_intent),
1793+
0, 0, NULL);
1794+
1795+
return xfs_refcount_intent_cache != NULL ? 0 : -ENOMEM;
1796+
}
1797+
1798+
void
1799+
xfs_refcount_intent_destroy_cache(void)
1800+
{
1801+
kmem_cache_destroy(xfs_refcount_intent_cache);
1802+
xfs_refcount_intent_cache = NULL;
1803+
}

fs/xfs/libxfs/xfs_refcount.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,9 @@ extern void xfs_refcount_btrec_to_irec(const union xfs_btree_rec *rec,
8383
extern int xfs_refcount_insert(struct xfs_btree_cur *cur,
8484
struct xfs_refcount_irec *irec, int *stat);
8585

86+
extern struct kmem_cache *xfs_refcount_intent_cache;
87+
88+
int __init xfs_refcount_intent_init_cache(void);
89+
void xfs_refcount_intent_destroy_cache(void);
90+
8691
#endif /* __XFS_REFCOUNT_H__ */

fs/xfs/libxfs/xfs_rmap.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include "xfs_inode.h"
2525
#include "xfs_ag.h"
2626

27+
struct kmem_cache *xfs_rmap_intent_cache;
28+
2729
/*
2830
* Lookup the first record less than or equal to [bno, len, owner, offset]
2931
* in the btree given by cur.
@@ -2485,7 +2487,7 @@ __xfs_rmap_add(
24852487
bmap->br_blockcount,
24862488
bmap->br_state);
24872489

2488-
ri = kmem_alloc(sizeof(struct xfs_rmap_intent), KM_NOFS);
2490+
ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
24892491
INIT_LIST_HEAD(&ri->ri_list);
24902492
ri->ri_type = type;
24912493
ri->ri_owner = owner;
@@ -2779,3 +2781,20 @@ const struct xfs_owner_info XFS_RMAP_OINFO_REFC = {
27792781
const struct xfs_owner_info XFS_RMAP_OINFO_COW = {
27802782
.oi_owner = XFS_RMAP_OWN_COW,
27812783
};
2784+
2785+
int __init
2786+
xfs_rmap_intent_init_cache(void)
2787+
{
2788+
xfs_rmap_intent_cache = kmem_cache_create("xfs_rmap_intent",
2789+
sizeof(struct xfs_rmap_intent),
2790+
0, 0, NULL);
2791+
2792+
return xfs_rmap_intent_cache != NULL ? 0 : -ENOMEM;
2793+
}
2794+
2795+
void
2796+
xfs_rmap_intent_destroy_cache(void)
2797+
{
2798+
kmem_cache_destroy(xfs_rmap_intent_cache);
2799+
xfs_rmap_intent_cache = NULL;
2800+
}

fs/xfs/libxfs/xfs_rmap.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,9 @@ extern const struct xfs_owner_info XFS_RMAP_OINFO_INODES;
215215
extern const struct xfs_owner_info XFS_RMAP_OINFO_REFC;
216216
extern const struct xfs_owner_info XFS_RMAP_OINFO_COW;
217217

218+
extern struct kmem_cache *xfs_rmap_intent_cache;
219+
220+
int __init xfs_rmap_intent_init_cache(void);
221+
void xfs_rmap_intent_destroy_cache(void);
222+
218223
#endif /* __XFS_RMAP_H__ */

fs/xfs/xfs_bmap_item.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ xfs_bmap_update_finish_item(
384384
bmap->bi_bmap.br_blockcount = count;
385385
return -EAGAIN;
386386
}
387-
kmem_free(bmap);
387+
kmem_cache_free(xfs_bmap_intent_cache, bmap);
388388
return error;
389389
}
390390

@@ -404,7 +404,7 @@ xfs_bmap_update_cancel_item(
404404
struct xfs_bmap_intent *bmap;
405405

406406
bmap = container_of(item, struct xfs_bmap_intent, bi_list);
407-
kmem_free(bmap);
407+
kmem_cache_free(xfs_bmap_intent_cache, bmap);
408408
}
409409

410410
const struct xfs_defer_op_type xfs_bmap_update_defer_type = {

fs/xfs/xfs_refcount_item.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ xfs_refcount_update_finish_item(
384384
refc->ri_blockcount = new_aglen;
385385
return -EAGAIN;
386386
}
387-
kmem_free(refc);
387+
kmem_cache_free(xfs_refcount_intent_cache, refc);
388388
return error;
389389
}
390390

@@ -404,7 +404,7 @@ xfs_refcount_update_cancel_item(
404404
struct xfs_refcount_intent *refc;
405405

406406
refc = container_of(item, struct xfs_refcount_intent, ri_list);
407-
kmem_free(refc);
407+
kmem_cache_free(xfs_refcount_intent_cache, refc);
408408
}
409409

410410
const struct xfs_defer_op_type xfs_refcount_update_defer_type = {

0 commit comments

Comments
 (0)