* [PATCHSET 0/5] xfs: use slab caches for deferred log items
@ 2021-10-19 18:52 Darrick J. Wong
2021-10-19 18:52 ` [PATCH 1/5] xfs: compact deferred intent item structures Darrick J. Wong
` (4 more replies)
0 siblings, 5 replies; 12+ messages in thread
From: Darrick J. Wong @ 2021-10-19 18:52 UTC (permalink / raw)
To: djwong; +Cc: linux-xfs
Hi all,
Since the adding of reflink and reverse mapping to the filesystem,
deferred log items are used quite a lot more frequently than they used
to be. This means that we're cycling a lot of small objects through the
slab caches, just like we do with btree cursors. Pack deferred item
contexts into memory pages more densely by creating separate slab caches
for each type, and shrink the intent items to use less memory.
If you're going to start using this mess, you probably ought to just
pull from my git trees, which are linked below.
This is an extraordinary way to destroy everything. Enjoy!
Comments and questions are, as always, welcome.
--D
kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=deferred-item-caches-5.16
---
fs/xfs/libxfs/xfs_ag.c | 2 -
fs/xfs/libxfs/xfs_alloc.c | 82 +++++++++++++++++++++++++++++++++++++---
fs/xfs/libxfs/xfs_alloc.h | 36 ++++++++++++++++++
fs/xfs/libxfs/xfs_bmap.c | 76 ++++++++++---------------------------
fs/xfs/libxfs/xfs_bmap.h | 35 +++--------------
fs/xfs/libxfs/xfs_bmap_btree.c | 2 -
fs/xfs/libxfs/xfs_defer.c | 67 +++++++++++++++++++++++++++++++--
fs/xfs/libxfs/xfs_defer.h | 3 +
fs/xfs/libxfs/xfs_ialloc.c | 4 +-
fs/xfs/libxfs/xfs_refcount.c | 46 +++++++++++++++-------
fs/xfs/libxfs/xfs_refcount.h | 7 +++
fs/xfs/libxfs/xfs_rmap.c | 21 ++++++++++
fs/xfs/libxfs/xfs_rmap.h | 7 +++
fs/xfs/xfs_bmap_item.c | 4 +-
fs/xfs/xfs_extfree_item.c | 19 ++++++---
fs/xfs/xfs_refcount_item.c | 4 +-
fs/xfs/xfs_reflink.c | 2 -
fs/xfs/xfs_rmap_item.c | 4 +-
fs/xfs/xfs_super.c | 21 +++++-----
19 files changed, 302 insertions(+), 140 deletions(-)
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/5] xfs: compact deferred intent item structures
2021-10-19 18:52 [PATCHSET 0/5] xfs: use slab caches for deferred log items Darrick J. Wong
@ 2021-10-19 18:52 ` Darrick J. Wong
2021-10-20 10:44 ` Chandan Babu R
2021-10-19 18:52 ` [PATCH 2/5] xfs: create slab caches for frequently-used deferred items Darrick J. Wong
` (3 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Darrick J. Wong @ 2021-10-19 18:52 UTC (permalink / raw)
To: djwong; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Rearrange these structs to reduce the amount of unused padding bytes.
This saves eight bytes for each of the three structs changed here, which
means they're now all (rmap/bmap are 64 bytes, refc is 32 bytes) even
powers of two.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/libxfs/xfs_bmap.h | 2 +-
fs/xfs/libxfs/xfs_refcount.h | 2 +-
fs/xfs/libxfs/xfs_rmap.h | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
index 2cd7717cf753..db01fe83bb8a 100644
--- a/fs/xfs/libxfs/xfs_bmap.h
+++ b/fs/xfs/libxfs/xfs_bmap.h
@@ -257,8 +257,8 @@ enum xfs_bmap_intent_type {
struct xfs_bmap_intent {
struct list_head bi_list;
enum xfs_bmap_intent_type bi_type;
- struct xfs_inode *bi_owner;
int bi_whichfork;
+ struct xfs_inode *bi_owner;
struct xfs_bmbt_irec bi_bmap;
};
diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h
index 02cb3aa405be..894045968bc6 100644
--- a/fs/xfs/libxfs/xfs_refcount.h
+++ b/fs/xfs/libxfs/xfs_refcount.h
@@ -32,8 +32,8 @@ enum xfs_refcount_intent_type {
struct xfs_refcount_intent {
struct list_head ri_list;
enum xfs_refcount_intent_type ri_type;
- xfs_fsblock_t ri_startblock;
xfs_extlen_t ri_blockcount;
+ xfs_fsblock_t ri_startblock;
};
void xfs_refcount_increase_extent(struct xfs_trans *tp,
diff --git a/fs/xfs/libxfs/xfs_rmap.h b/fs/xfs/libxfs/xfs_rmap.h
index fd67904ed446..85dd98ac3f12 100644
--- a/fs/xfs/libxfs/xfs_rmap.h
+++ b/fs/xfs/libxfs/xfs_rmap.h
@@ -159,8 +159,8 @@ enum xfs_rmap_intent_type {
struct xfs_rmap_intent {
struct list_head ri_list;
enum xfs_rmap_intent_type ri_type;
- uint64_t ri_owner;
int ri_whichfork;
+ uint64_t ri_owner;
struct xfs_bmbt_irec ri_bmap;
};
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/5] xfs: create slab caches for frequently-used deferred items
2021-10-19 18:52 [PATCHSET 0/5] xfs: use slab caches for deferred log items Darrick J. Wong
2021-10-19 18:52 ` [PATCH 1/5] xfs: compact deferred intent item structures Darrick J. Wong
@ 2021-10-19 18:52 ` Darrick J. Wong
2021-10-20 10:45 ` Chandan Babu R
2021-10-19 18:52 ` [PATCH 3/5] xfs: rename xfs_bmap_add_free to xfs_free_extent_later Darrick J. Wong
` (2 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Darrick J. Wong @ 2021-10-19 18:52 UTC (permalink / raw)
To: djwong; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
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 <djwong@kernel.org>
---
fs/xfs/libxfs/xfs_bmap.c | 21 +++++++++++++-
fs/xfs/libxfs/xfs_bmap.h | 5 +++
fs/xfs/libxfs/xfs_defer.c | 62 +++++++++++++++++++++++++++++++++++++++---
fs/xfs/libxfs/xfs_defer.h | 3 ++
fs/xfs/libxfs/xfs_refcount.c | 23 ++++++++++++++--
fs/xfs/libxfs/xfs_refcount.h | 5 +++
fs/xfs/libxfs/xfs_rmap.c | 21 ++++++++++++++
fs/xfs/libxfs/xfs_rmap.h | 5 +++
fs/xfs/xfs_bmap_item.c | 4 +--
fs/xfs/xfs_refcount_item.c | 4 +--
fs/xfs/xfs_rmap_item.c | 4 +--
fs/xfs/xfs_super.c | 10 ++++++-
12 files changed, 151 insertions(+), 16 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 8a993ef6b7f4..ef2ac0ecaed9 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -37,7 +37,7 @@
#include "xfs_icache.h"
#include "xfs_iomap.h"
-
+struct kmem_cache *xfs_bmap_intent_cache;
struct kmem_cache *xfs_bmap_free_item_cache;
/*
@@ -6190,7 +6190,7 @@ __xfs_bmap_add(
bmap->br_blockcount,
bmap->br_state);
- bi = kmem_alloc(sizeof(struct xfs_bmap_intent), KM_NOFS);
+ bi = kmem_cache_alloc(xfs_bmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
INIT_LIST_HEAD(&bi->bi_list);
bi->bi_type = type;
bi->bi_owner = ip;
@@ -6301,3 +6301,20 @@ xfs_bmap_validate_extent(
return __this_address;
return NULL;
}
+
+int __init
+xfs_bmap_intent_init_cache(void)
+{
+ xfs_bmap_intent_cache = kmem_cache_create("xfs_bmap_intent",
+ sizeof(struct xfs_bmap_intent),
+ 0, 0, NULL);
+
+ return xfs_bmap_intent_cache != NULL ? 0 : -ENOMEM;
+}
+
+void
+xfs_bmap_intent_destroy_cache(void)
+{
+ kmem_cache_destroy(xfs_bmap_intent_cache);
+ xfs_bmap_intent_cache = NULL;
+}
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
index db01fe83bb8a..fa73a56827b1 100644
--- a/fs/xfs/libxfs/xfs_bmap.h
+++ b/fs/xfs/libxfs/xfs_bmap.h
@@ -290,4 +290,9 @@ int xfs_bmapi_remap(struct xfs_trans *tp, struct xfs_inode *ip,
xfs_fileoff_t bno, xfs_filblks_t len, xfs_fsblock_t startblock,
int flags);
+extern struct kmem_cache *xfs_bmap_intent_cache;
+
+int __init xfs_bmap_intent_init_cache(void);
+void xfs_bmap_intent_destroy_cache(void);
+
#endif /* __XFS_BMAP_H__ */
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
index 136a367d7b16..641a5dee4ffc 100644
--- a/fs/xfs/libxfs/xfs_defer.c
+++ b/fs/xfs/libxfs/xfs_defer.c
@@ -18,6 +18,11 @@
#include "xfs_trace.h"
#include "xfs_icache.h"
#include "xfs_log.h"
+#include "xfs_rmap.h"
+#include "xfs_refcount.h"
+#include "xfs_bmap.h"
+
+static struct kmem_cache *xfs_defer_pending_cache;
/*
* Deferred Operations in XFS
@@ -365,7 +370,7 @@ xfs_defer_cancel_list(
ops->cancel_item(pwi);
}
ASSERT(dfp->dfp_count == 0);
- kmem_free(dfp);
+ kmem_cache_free(xfs_defer_pending_cache, dfp);
}
}
@@ -462,7 +467,7 @@ xfs_defer_finish_one(
/* Done with the dfp, free it. */
list_del(&dfp->dfp_list);
- kmem_free(dfp);
+ kmem_cache_free(xfs_defer_pending_cache, dfp);
out:
if (ops->finish_cleanup)
ops->finish_cleanup(tp, state, error);
@@ -596,8 +601,8 @@ xfs_defer_add(
dfp = NULL;
}
if (!dfp) {
- dfp = kmem_alloc(sizeof(struct xfs_defer_pending),
- KM_NOFS);
+ dfp = kmem_cache_zalloc(xfs_defer_pending_cache,
+ GFP_NOFS | __GFP_NOFAIL);
dfp->dfp_type = type;
dfp->dfp_intent = NULL;
dfp->dfp_done = NULL;
@@ -809,3 +814,52 @@ xfs_defer_resources_rele(
dres->dr_bufs = 0;
dres->dr_ordered = 0;
}
+
+static inline int __init
+xfs_defer_init_cache(void)
+{
+ xfs_defer_pending_cache = kmem_cache_create("xfs_defer_pending",
+ sizeof(struct xfs_defer_pending),
+ 0, 0, NULL);
+
+ return xfs_defer_pending_cache != NULL ? 0 : -ENOMEM;
+}
+
+static inline void
+xfs_defer_destroy_cache(void)
+{
+ kmem_cache_destroy(xfs_defer_pending_cache);
+ xfs_defer_pending_cache = NULL;
+}
+
+/* Set up caches for deferred work items. */
+int __init
+xfs_defer_init_item_caches(void)
+{
+ int error;
+
+ error = xfs_defer_init_cache();
+ if (error)
+ return error;
+ error = xfs_rmap_intent_init_cache();
+ if (error)
+ return error;
+ error = xfs_refcount_intent_init_cache();
+ if (error)
+ return error;
+ error = xfs_bmap_intent_init_cache();
+ if (error)
+ return error;
+
+ return 0;
+}
+
+/* Destroy all the deferred work item caches, if they've been allocated. */
+void
+xfs_defer_destroy_item_caches(void)
+{
+ xfs_bmap_intent_destroy_cache();
+ xfs_refcount_intent_destroy_cache();
+ xfs_rmap_intent_destroy_cache();
+ xfs_defer_destroy_cache();
+}
diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h
index 7952695c7c41..7bb8a31ad65b 100644
--- a/fs/xfs/libxfs/xfs_defer.h
+++ b/fs/xfs/libxfs/xfs_defer.h
@@ -122,4 +122,7 @@ void xfs_defer_ops_capture_free(struct xfs_mount *mp,
struct xfs_defer_capture *d);
void xfs_defer_resources_rele(struct xfs_defer_resources *dres);
+int __init xfs_defer_init_item_caches(void);
+void xfs_defer_destroy_item_caches(void);
+
#endif /* __XFS_DEFER_H__ */
diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
index e5d767a7fc5d..2c03df715d4f 100644
--- a/fs/xfs/libxfs/xfs_refcount.c
+++ b/fs/xfs/libxfs/xfs_refcount.c
@@ -24,6 +24,8 @@
#include "xfs_rmap.h"
#include "xfs_ag.h"
+struct kmem_cache *xfs_refcount_intent_cache;
+
/* Allowable refcount adjustment amounts. */
enum xfs_refc_adjust_op {
XFS_REFCOUNT_ADJUST_INCREASE = 1,
@@ -1235,8 +1237,8 @@ __xfs_refcount_add(
type, XFS_FSB_TO_AGBNO(tp->t_mountp, startblock),
blockcount);
- ri = kmem_alloc(sizeof(struct xfs_refcount_intent),
- KM_NOFS);
+ ri = kmem_cache_alloc(xfs_refcount_intent_cache,
+ GFP_NOFS | __GFP_NOFAIL);
INIT_LIST_HEAD(&ri->ri_list);
ri->ri_type = type;
ri->ri_startblock = startblock;
@@ -1782,3 +1784,20 @@ xfs_refcount_has_record(
return xfs_btree_has_record(cur, &low, &high, exists);
}
+
+int __init
+xfs_refcount_intent_init_cache(void)
+{
+ xfs_refcount_intent_cache = kmem_cache_create("xfs_refc_intent",
+ sizeof(struct xfs_refcount_intent),
+ 0, 0, NULL);
+
+ return xfs_refcount_intent_cache != NULL ? 0 : -ENOMEM;
+}
+
+void
+xfs_refcount_intent_destroy_cache(void)
+{
+ kmem_cache_destroy(xfs_refcount_intent_cache);
+ xfs_refcount_intent_cache = NULL;
+}
diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h
index 894045968bc6..9eb01edbd89d 100644
--- a/fs/xfs/libxfs/xfs_refcount.h
+++ b/fs/xfs/libxfs/xfs_refcount.h
@@ -83,4 +83,9 @@ extern void xfs_refcount_btrec_to_irec(const union xfs_btree_rec *rec,
extern int xfs_refcount_insert(struct xfs_btree_cur *cur,
struct xfs_refcount_irec *irec, int *stat);
+extern struct kmem_cache *xfs_refcount_intent_cache;
+
+int __init xfs_refcount_intent_init_cache(void);
+void xfs_refcount_intent_destroy_cache(void);
+
#endif /* __XFS_REFCOUNT_H__ */
diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c
index f45929b1b94a..cd322174dbff 100644
--- a/fs/xfs/libxfs/xfs_rmap.c
+++ b/fs/xfs/libxfs/xfs_rmap.c
@@ -24,6 +24,8 @@
#include "xfs_inode.h"
#include "xfs_ag.h"
+struct kmem_cache *xfs_rmap_intent_cache;
+
/*
* Lookup the first record less than or equal to [bno, len, owner, offset]
* in the btree given by cur.
@@ -2485,7 +2487,7 @@ __xfs_rmap_add(
bmap->br_blockcount,
bmap->br_state);
- ri = kmem_alloc(sizeof(struct xfs_rmap_intent), KM_NOFS);
+ ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
INIT_LIST_HEAD(&ri->ri_list);
ri->ri_type = type;
ri->ri_owner = owner;
@@ -2779,3 +2781,20 @@ const struct xfs_owner_info XFS_RMAP_OINFO_REFC = {
const struct xfs_owner_info XFS_RMAP_OINFO_COW = {
.oi_owner = XFS_RMAP_OWN_COW,
};
+
+int __init
+xfs_rmap_intent_init_cache(void)
+{
+ xfs_rmap_intent_cache = kmem_cache_create("xfs_rmap_intent",
+ sizeof(struct xfs_rmap_intent),
+ 0, 0, NULL);
+
+ return xfs_rmap_intent_cache != NULL ? 0 : -ENOMEM;
+}
+
+void
+xfs_rmap_intent_destroy_cache(void)
+{
+ kmem_cache_destroy(xfs_rmap_intent_cache);
+ xfs_rmap_intent_cache = NULL;
+}
diff --git a/fs/xfs/libxfs/xfs_rmap.h b/fs/xfs/libxfs/xfs_rmap.h
index 85dd98ac3f12..b718ebeda372 100644
--- a/fs/xfs/libxfs/xfs_rmap.h
+++ b/fs/xfs/libxfs/xfs_rmap.h
@@ -215,4 +215,9 @@ extern const struct xfs_owner_info XFS_RMAP_OINFO_INODES;
extern const struct xfs_owner_info XFS_RMAP_OINFO_REFC;
extern const struct xfs_owner_info XFS_RMAP_OINFO_COW;
+extern struct kmem_cache *xfs_rmap_intent_cache;
+
+int __init xfs_rmap_intent_init_cache(void);
+void xfs_rmap_intent_destroy_cache(void);
+
#endif /* __XFS_RMAP_H__ */
diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
index 6049f0722181..e1f4d7d5a011 100644
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -384,7 +384,7 @@ xfs_bmap_update_finish_item(
bmap->bi_bmap.br_blockcount = count;
return -EAGAIN;
}
- kmem_free(bmap);
+ kmem_cache_free(xfs_bmap_intent_cache, bmap);
return error;
}
@@ -404,7 +404,7 @@ xfs_bmap_update_cancel_item(
struct xfs_bmap_intent *bmap;
bmap = container_of(item, struct xfs_bmap_intent, bi_list);
- kmem_free(bmap);
+ kmem_cache_free(xfs_bmap_intent_cache, bmap);
}
const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
index f23e86e06bfb..d3da67772d57 100644
--- a/fs/xfs/xfs_refcount_item.c
+++ b/fs/xfs/xfs_refcount_item.c
@@ -384,7 +384,7 @@ xfs_refcount_update_finish_item(
refc->ri_blockcount = new_aglen;
return -EAGAIN;
}
- kmem_free(refc);
+ kmem_cache_free(xfs_refcount_intent_cache, refc);
return error;
}
@@ -404,7 +404,7 @@ xfs_refcount_update_cancel_item(
struct xfs_refcount_intent *refc;
refc = container_of(item, struct xfs_refcount_intent, ri_list);
- kmem_free(refc);
+ kmem_cache_free(xfs_refcount_intent_cache, refc);
}
const struct xfs_defer_op_type xfs_refcount_update_defer_type = {
diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
index b5cdeb10927e..c3966b4c58ef 100644
--- a/fs/xfs/xfs_rmap_item.c
+++ b/fs/xfs/xfs_rmap_item.c
@@ -427,7 +427,7 @@ xfs_rmap_update_finish_item(
rmap->ri_bmap.br_startoff, rmap->ri_bmap.br_startblock,
rmap->ri_bmap.br_blockcount, rmap->ri_bmap.br_state,
state);
- kmem_free(rmap);
+ kmem_cache_free(xfs_rmap_intent_cache, rmap);
return error;
}
@@ -447,7 +447,7 @@ xfs_rmap_update_cancel_item(
struct xfs_rmap_intent *rmap;
rmap = container_of(item, struct xfs_rmap_intent, ri_list);
- kmem_free(rmap);
+ kmem_cache_free(xfs_rmap_intent_cache, rmap);
}
const struct xfs_defer_op_type xfs_rmap_update_defer_type = {
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 0afa47378211..8909e08cbf77 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -38,6 +38,7 @@
#include "xfs_pwork.h"
#include "xfs_ag.h"
#include "xfs_btree.h"
+#include "xfs_defer.h"
#include <linux/magic.h>
#include <linux/fs_context.h>
@@ -1972,11 +1973,15 @@ xfs_init_caches(void)
if (error)
goto out_destroy_bmap_free_item_cache;
+ error = xfs_defer_init_item_caches();
+ if (error)
+ goto out_destroy_btree_cur_cache;
+
xfs_da_state_cache = kmem_cache_create("xfs_da_state",
sizeof(struct xfs_da_state),
0, 0, NULL);
if (!xfs_da_state_cache)
- goto out_destroy_btree_cur_cache;
+ goto out_destroy_defer_item_cache;
xfs_ifork_cache = kmem_cache_create("xfs_ifork",
sizeof(struct xfs_ifork),
@@ -2106,6 +2111,8 @@ xfs_init_caches(void)
kmem_cache_destroy(xfs_ifork_cache);
out_destroy_da_state_cache:
kmem_cache_destroy(xfs_da_state_cache);
+ out_destroy_defer_item_cache:
+ xfs_defer_destroy_item_caches();
out_destroy_btree_cur_cache:
xfs_btree_destroy_cur_caches();
out_destroy_bmap_free_item_cache:
@@ -2140,6 +2147,7 @@ xfs_destroy_caches(void)
kmem_cache_destroy(xfs_ifork_cache);
kmem_cache_destroy(xfs_da_state_cache);
xfs_btree_destroy_cur_caches();
+ xfs_defer_destroy_item_caches();
kmem_cache_destroy(xfs_bmap_free_item_cache);
kmem_cache_destroy(xfs_log_ticket_cache);
}
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/5] xfs: rename xfs_bmap_add_free to xfs_free_extent_later
2021-10-19 18:52 [PATCHSET 0/5] xfs: use slab caches for deferred log items Darrick J. Wong
2021-10-19 18:52 ` [PATCH 1/5] xfs: compact deferred intent item structures Darrick J. Wong
2021-10-19 18:52 ` [PATCH 2/5] xfs: create slab caches for frequently-used deferred items Darrick J. Wong
@ 2021-10-19 18:52 ` Darrick J. Wong
2021-10-20 10:45 ` Chandan Babu R
2021-10-19 18:52 ` [PATCH 4/5] xfs: reduce the size of struct xfs_extent_free_item Darrick J. Wong
2021-10-19 18:52 ` [PATCH 5/5] xfs: remove unused parameter from refcount code Darrick J. Wong
4 siblings, 1 reply; 12+ messages in thread
From: Darrick J. Wong @ 2021-10-19 18:52 UTC (permalink / raw)
To: djwong; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
xfs_bmap_add_free isn't a block mapping function; it schedules deferred
freeing operations for a later point in a compound transaction chain.
While it's primarily used by bunmapi, its use has expanded beyond that.
Move it to xfs_alloc.c and rename the function since it's now general
freeing functionality. Bring the slab cache bits in line with the
way we handle the other intent items.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/libxfs/xfs_ag.c | 2 +
fs/xfs/libxfs/xfs_alloc.c | 71 ++++++++++++++++++++++++++++++++++++++--
fs/xfs/libxfs/xfs_alloc.h | 32 ++++++++++++++++++
fs/xfs/libxfs/xfs_bmap.c | 55 +------------------------------
fs/xfs/libxfs/xfs_bmap.h | 28 ----------------
fs/xfs/libxfs/xfs_bmap_btree.c | 2 +
fs/xfs/libxfs/xfs_defer.c | 5 +++
fs/xfs/libxfs/xfs_ialloc.c | 4 +-
fs/xfs/libxfs/xfs_refcount.c | 6 ++-
fs/xfs/xfs_extfree_item.c | 6 ++-
fs/xfs/xfs_reflink.c | 2 +
fs/xfs/xfs_super.c | 11 +-----
12 files changed, 118 insertions(+), 106 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c
index 005abfd9fd34..d7d875cef07a 100644
--- a/fs/xfs/libxfs/xfs_ag.c
+++ b/fs/xfs/libxfs/xfs_ag.c
@@ -850,7 +850,7 @@ xfs_ag_shrink_space(
if (err2 != -ENOSPC)
goto resv_err;
- __xfs_bmap_add_free(*tpp, args.fsbno, delta, NULL, true);
+ __xfs_free_extent_later(*tpp, args.fsbno, delta, NULL, true);
/*
* Roll the transaction before trying to re-init the per-ag
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index ccfe66df3e62..9bc1a03a8167 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -27,7 +27,7 @@
#include "xfs_ag_resv.h"
#include "xfs_bmap.h"
-extern struct kmem_cache *xfs_bmap_free_item_cache;
+struct kmem_cache *xfs_extfree_item_cache;
struct workqueue_struct *xfs_alloc_wq;
@@ -2440,7 +2440,7 @@ xfs_agfl_reset(
/*
* Defer an AGFL block free. This is effectively equivalent to
- * xfs_bmap_add_free() with some special handling particular to AGFL blocks.
+ * xfs_free_extent_later() with some special handling particular to AGFL blocks.
*
* Deferring AGFL frees helps prevent log reservation overruns due to too many
* allocation operations in a transaction. AGFL frees are prone to this problem
@@ -2459,10 +2459,10 @@ xfs_defer_agfl_block(
struct xfs_mount *mp = tp->t_mountp;
struct xfs_extent_free_item *new; /* new element */
- ASSERT(xfs_bmap_free_item_cache != NULL);
+ ASSERT(xfs_extfree_item_cache != NULL);
ASSERT(oinfo != NULL);
- new = kmem_cache_alloc(xfs_bmap_free_item_cache,
+ new = kmem_cache_alloc(xfs_extfree_item_cache,
GFP_KERNEL | __GFP_NOFAIL);
new->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
new->xefi_blockcount = 1;
@@ -2474,6 +2474,52 @@ xfs_defer_agfl_block(
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &new->xefi_list);
}
+/*
+ * Add the extent to the list of extents to be free at transaction end.
+ * The list is maintained sorted (by block number).
+ */
+void
+__xfs_free_extent_later(
+ struct xfs_trans *tp,
+ xfs_fsblock_t bno,
+ xfs_filblks_t len,
+ const struct xfs_owner_info *oinfo,
+ bool skip_discard)
+{
+ struct xfs_extent_free_item *new; /* new element */
+#ifdef DEBUG
+ struct xfs_mount *mp = tp->t_mountp;
+ xfs_agnumber_t agno;
+ xfs_agblock_t agbno;
+
+ ASSERT(bno != NULLFSBLOCK);
+ ASSERT(len > 0);
+ ASSERT(len <= MAXEXTLEN);
+ ASSERT(!isnullstartblock(bno));
+ agno = XFS_FSB_TO_AGNO(mp, bno);
+ agbno = XFS_FSB_TO_AGBNO(mp, bno);
+ ASSERT(agno < mp->m_sb.sb_agcount);
+ ASSERT(agbno < mp->m_sb.sb_agblocks);
+ ASSERT(len < mp->m_sb.sb_agblocks);
+ ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
+#endif
+ ASSERT(xfs_extfree_item_cache != NULL);
+
+ new = kmem_cache_alloc(xfs_extfree_item_cache,
+ GFP_KERNEL | __GFP_NOFAIL);
+ new->xefi_startblock = bno;
+ new->xefi_blockcount = (xfs_extlen_t)len;
+ if (oinfo)
+ new->xefi_oinfo = *oinfo;
+ else
+ new->xefi_oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
+ new->xefi_skip_discard = skip_discard;
+ trace_xfs_bmap_free_defer(tp->t_mountp,
+ XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
+ XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
+ xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list);
+}
+
#ifdef DEBUG
/*
* Check if an AGF has a free extent record whose length is equal to
@@ -3499,3 +3545,20 @@ xfs_agfl_walk(
return 0;
}
+
+int __init
+xfs_extfree_intent_init_cache(void)
+{
+ xfs_extfree_item_cache = kmem_cache_create("xfs_extfree_intent",
+ sizeof(struct xfs_extent_free_item),
+ 0, 0, NULL);
+
+ return xfs_extfree_item_cache != NULL ? 0 : -ENOMEM;
+}
+
+void
+xfs_extfree_intent_destroy_cache(void)
+{
+ kmem_cache_destroy(xfs_extfree_item_cache);
+ xfs_extfree_item_cache = NULL;
+}
diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
index 2f3f8c2e0860..b61aeb6fbe32 100644
--- a/fs/xfs/libxfs/xfs_alloc.h
+++ b/fs/xfs/libxfs/xfs_alloc.h
@@ -248,4 +248,36 @@ xfs_buf_to_agfl_bno(
return bp->b_addr;
}
+void __xfs_free_extent_later(struct xfs_trans *tp, xfs_fsblock_t bno,
+ xfs_filblks_t len, const struct xfs_owner_info *oinfo,
+ bool skip_discard);
+
+/*
+ * List of extents to be free "later".
+ * The list is kept sorted on xbf_startblock.
+ */
+struct xfs_extent_free_item {
+ struct list_head xefi_list;
+ xfs_fsblock_t xefi_startblock;/* starting fs block number */
+ xfs_extlen_t xefi_blockcount;/* number of blocks in extent */
+ bool xefi_skip_discard;
+ struct xfs_owner_info xefi_oinfo; /* extent owner */
+};
+
+static inline void
+xfs_free_extent_later(
+ struct xfs_trans *tp,
+ xfs_fsblock_t bno,
+ xfs_filblks_t len,
+ const struct xfs_owner_info *oinfo)
+{
+ __xfs_free_extent_later(tp, bno, len, oinfo, false);
+}
+
+
+extern struct kmem_cache *xfs_extfree_item_cache;
+
+int __init xfs_extfree_intent_init_cache(void);
+void xfs_extfree_intent_destroy_cache(void);
+
#endif /* __XFS_ALLOC_H__ */
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index ef2ac0ecaed9..4dccd4d90622 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -38,7 +38,6 @@
#include "xfs_iomap.h"
struct kmem_cache *xfs_bmap_intent_cache;
-struct kmem_cache *xfs_bmap_free_item_cache;
/*
* Miscellaneous helper functions
@@ -522,56 +521,6 @@ xfs_bmap_validate_ret(
#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do { } while (0)
#endif /* DEBUG */
-/*
- * bmap free list manipulation functions
- */
-
-/*
- * Add the extent to the list of extents to be free at transaction end.
- * The list is maintained sorted (by block number).
- */
-void
-__xfs_bmap_add_free(
- struct xfs_trans *tp,
- xfs_fsblock_t bno,
- xfs_filblks_t len,
- const struct xfs_owner_info *oinfo,
- bool skip_discard)
-{
- struct xfs_extent_free_item *new; /* new element */
-#ifdef DEBUG
- struct xfs_mount *mp = tp->t_mountp;
- xfs_agnumber_t agno;
- xfs_agblock_t agbno;
-
- ASSERT(bno != NULLFSBLOCK);
- ASSERT(len > 0);
- ASSERT(len <= MAXEXTLEN);
- ASSERT(!isnullstartblock(bno));
- agno = XFS_FSB_TO_AGNO(mp, bno);
- agbno = XFS_FSB_TO_AGBNO(mp, bno);
- ASSERT(agno < mp->m_sb.sb_agcount);
- ASSERT(agbno < mp->m_sb.sb_agblocks);
- ASSERT(len < mp->m_sb.sb_agblocks);
- ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
-#endif
- ASSERT(xfs_bmap_free_item_cache != NULL);
-
- new = kmem_cache_alloc(xfs_bmap_free_item_cache,
- GFP_KERNEL | __GFP_NOFAIL);
- new->xefi_startblock = bno;
- new->xefi_blockcount = (xfs_extlen_t)len;
- if (oinfo)
- new->xefi_oinfo = *oinfo;
- else
- new->xefi_oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
- new->xefi_skip_discard = skip_discard;
- trace_xfs_bmap_free_defer(tp->t_mountp,
- XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
- XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
- xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list);
-}
-
/*
* Inode fork format manipulation functions
*/
@@ -626,7 +575,7 @@ xfs_bmap_btree_to_extents(
if ((error = xfs_btree_check_block(cur, cblock, 0, cbp)))
return error;
xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork);
- xfs_bmap_add_free(cur->bc_tp, cbno, 1, &oinfo);
+ xfs_free_extent_later(cur->bc_tp, cbno, 1, &oinfo);
ip->i_nblocks--;
xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
xfs_trans_binval(tp, cbp);
@@ -5297,7 +5246,7 @@ xfs_bmap_del_extent_real(
if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) {
xfs_refcount_decrease_extent(tp, del);
} else {
- __xfs_bmap_add_free(tp, del->br_startblock,
+ __xfs_free_extent_later(tp, del->br_startblock,
del->br_blockcount, NULL,
(bflags & XFS_BMAPI_NODISCARD) ||
del->br_state == XFS_EXT_UNWRITTEN);
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
index fa73a56827b1..03d9aaf87413 100644
--- a/fs/xfs/libxfs/xfs_bmap.h
+++ b/fs/xfs/libxfs/xfs_bmap.h
@@ -13,8 +13,6 @@ struct xfs_inode;
struct xfs_mount;
struct xfs_trans;
-extern struct kmem_cache *xfs_bmap_free_item_cache;
-
/*
* Argument structure for xfs_bmap_alloc.
*/
@@ -44,19 +42,6 @@ struct xfs_bmalloca {
int flags;
};
-/*
- * List of extents to be free "later".
- * The list is kept sorted on xbf_startblock.
- */
-struct xfs_extent_free_item
-{
- xfs_fsblock_t xefi_startblock;/* starting fs block number */
- xfs_extlen_t xefi_blockcount;/* number of blocks in extent */
- bool xefi_skip_discard;
- struct list_head xefi_list;
- struct xfs_owner_info xefi_oinfo; /* extent owner */
-};
-
#define XFS_BMAP_MAX_NMAP 4
/*
@@ -189,9 +174,6 @@ unsigned int xfs_bmap_compute_attr_offset(struct xfs_mount *mp);
int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);
void xfs_bmap_local_to_extents_empty(struct xfs_trans *tp,
struct xfs_inode *ip, int whichfork);
-void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno,
- xfs_filblks_t len, const struct xfs_owner_info *oinfo,
- bool skip_discard);
void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork);
int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip,
xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork);
@@ -239,16 +221,6 @@ int xfs_bmap_add_extent_unwritten_real(struct xfs_trans *tp,
struct xfs_iext_cursor *icur, struct xfs_btree_cur **curp,
struct xfs_bmbt_irec *new, int *logflagsp);
-static inline void
-xfs_bmap_add_free(
- struct xfs_trans *tp,
- xfs_fsblock_t bno,
- xfs_filblks_t len,
- const struct xfs_owner_info *oinfo)
-{
- __xfs_bmap_add_free(tp, bno, len, oinfo, false);
-}
-
enum xfs_bmap_intent_type {
XFS_BMAP_MAP = 1,
XFS_BMAP_UNMAP,
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c
index 3c9a45233e60..453309fc85f2 100644
--- a/fs/xfs/libxfs/xfs_bmap_btree.c
+++ b/fs/xfs/libxfs/xfs_bmap_btree.c
@@ -288,7 +288,7 @@ xfs_bmbt_free_block(
struct xfs_owner_info oinfo;
xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, cur->bc_ino.whichfork);
- xfs_bmap_add_free(cur->bc_tp, fsbno, 1, &oinfo);
+ xfs_free_extent_later(cur->bc_tp, fsbno, 1, &oinfo);
ip->i_nblocks--;
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
index 641a5dee4ffc..3c43e5c93e7b 100644
--- a/fs/xfs/libxfs/xfs_defer.c
+++ b/fs/xfs/libxfs/xfs_defer.c
@@ -21,6 +21,7 @@
#include "xfs_rmap.h"
#include "xfs_refcount.h"
#include "xfs_bmap.h"
+#include "xfs_alloc.h"
static struct kmem_cache *xfs_defer_pending_cache;
@@ -848,6 +849,9 @@ xfs_defer_init_item_caches(void)
if (error)
return error;
error = xfs_bmap_intent_init_cache();
+ if (error)
+ return error;
+ error = xfs_extfree_intent_init_cache();
if (error)
return error;
@@ -858,6 +862,7 @@ xfs_defer_init_item_caches(void)
void
xfs_defer_destroy_item_caches(void)
{
+ xfs_extfree_intent_destroy_cache();
xfs_bmap_intent_destroy_cache();
xfs_refcount_intent_destroy_cache();
xfs_rmap_intent_destroy_cache();
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index f78a600ca73f..b418fe0c0679 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -1827,7 +1827,7 @@ xfs_difree_inode_chunk(
if (!xfs_inobt_issparse(rec->ir_holemask)) {
/* not sparse, calculate extent info directly */
- xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, sagbno),
+ xfs_free_extent_later(tp, XFS_AGB_TO_FSB(mp, agno, sagbno),
M_IGEO(mp)->ialloc_blks,
&XFS_RMAP_OINFO_INODES);
return;
@@ -1872,7 +1872,7 @@ xfs_difree_inode_chunk(
ASSERT(agbno % mp->m_sb.sb_spino_align == 0);
ASSERT(contigblk % mp->m_sb.sb_spino_align == 0);
- xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, agbno),
+ xfs_free_extent_later(tp, XFS_AGB_TO_FSB(mp, agno, agbno),
contigblk, &XFS_RMAP_OINFO_INODES);
/* reset range to current bit and carry on... */
diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
index 2c03df715d4f..bb9e256f4970 100644
--- a/fs/xfs/libxfs/xfs_refcount.c
+++ b/fs/xfs/libxfs/xfs_refcount.c
@@ -976,7 +976,7 @@ xfs_refcount_adjust_extents(
fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
cur->bc_ag.pag->pag_agno,
tmp.rc_startblock);
- xfs_bmap_add_free(cur->bc_tp, fsbno,
+ xfs_free_extent_later(cur->bc_tp, fsbno,
tmp.rc_blockcount, oinfo);
}
@@ -1021,7 +1021,7 @@ xfs_refcount_adjust_extents(
fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
cur->bc_ag.pag->pag_agno,
ext.rc_startblock);
- xfs_bmap_add_free(cur->bc_tp, fsbno, ext.rc_blockcount,
+ xfs_free_extent_later(cur->bc_tp, fsbno, ext.rc_blockcount,
oinfo);
}
@@ -1744,7 +1744,7 @@ xfs_refcount_recover_cow_leftovers(
rr->rr_rrec.rc_blockcount);
/* Free the block. */
- xfs_bmap_add_free(tp, fsb, rr->rr_rrec.rc_blockcount, NULL);
+ xfs_free_extent_later(tp, fsb, rr->rr_rrec.rc_blockcount, NULL);
error = xfs_trans_commit(tp);
if (error)
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index 26ac5048ce76..eb378e345f13 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -482,7 +482,7 @@ xfs_extent_free_finish_item(
free->xefi_startblock,
free->xefi_blockcount,
&free->xefi_oinfo, free->xefi_skip_discard);
- kmem_cache_free(xfs_bmap_free_item_cache, free);
+ kmem_cache_free(xfs_extfree_item_cache, free);
return error;
}
@@ -502,7 +502,7 @@ xfs_extent_free_cancel_item(
struct xfs_extent_free_item *free;
free = container_of(item, struct xfs_extent_free_item, xefi_list);
- kmem_cache_free(xfs_bmap_free_item_cache, free);
+ kmem_cache_free(xfs_extfree_item_cache, free);
}
const struct xfs_defer_op_type xfs_extent_free_defer_type = {
@@ -564,7 +564,7 @@ xfs_agfl_free_finish_item(
extp->ext_len = free->xefi_blockcount;
efdp->efd_next_extent++;
- kmem_cache_free(xfs_bmap_free_item_cache, free);
+ kmem_cache_free(xfs_extfree_item_cache, free);
return error;
}
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index 76355f293488..cb0edb1d68ef 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -484,7 +484,7 @@ xfs_reflink_cancel_cow_blocks(
xfs_refcount_free_cow_extent(*tpp, del.br_startblock,
del.br_blockcount);
- xfs_bmap_add_free(*tpp, del.br_startblock,
+ xfs_free_extent_later(*tpp, del.br_startblock,
del.br_blockcount, NULL);
/* Roll the transaction */
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 8909e08cbf77..daa6d76b8dd0 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1963,15 +1963,9 @@ xfs_init_caches(void)
if (!xfs_log_ticket_cache)
goto out;
- xfs_bmap_free_item_cache = kmem_cache_create("xfs_bmap_free_item",
- sizeof(struct xfs_extent_free_item),
- 0, 0, NULL);
- if (!xfs_bmap_free_item_cache)
- goto out_destroy_log_ticket_cache;
-
error = xfs_btree_init_cur_caches();
if (error)
- goto out_destroy_bmap_free_item_cache;
+ goto out_destroy_log_ticket_cache;
error = xfs_defer_init_item_caches();
if (error)
@@ -2115,8 +2109,6 @@ xfs_init_caches(void)
xfs_defer_destroy_item_caches();
out_destroy_btree_cur_cache:
xfs_btree_destroy_cur_caches();
- out_destroy_bmap_free_item_cache:
- kmem_cache_destroy(xfs_bmap_free_item_cache);
out_destroy_log_ticket_cache:
kmem_cache_destroy(xfs_log_ticket_cache);
out:
@@ -2148,7 +2140,6 @@ xfs_destroy_caches(void)
kmem_cache_destroy(xfs_da_state_cache);
xfs_btree_destroy_cur_caches();
xfs_defer_destroy_item_caches();
- kmem_cache_destroy(xfs_bmap_free_item_cache);
kmem_cache_destroy(xfs_log_ticket_cache);
}
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/5] xfs: reduce the size of struct xfs_extent_free_item
2021-10-19 18:52 [PATCHSET 0/5] xfs: use slab caches for deferred log items Darrick J. Wong
` (2 preceding siblings ...)
2021-10-19 18:52 ` [PATCH 3/5] xfs: rename xfs_bmap_add_free to xfs_free_extent_later Darrick J. Wong
@ 2021-10-19 18:52 ` Darrick J. Wong
2021-10-20 10:46 ` Chandan Babu R
2021-10-19 18:52 ` [PATCH 5/5] xfs: remove unused parameter from refcount code Darrick J. Wong
4 siblings, 1 reply; 12+ messages in thread
From: Darrick J. Wong @ 2021-10-19 18:52 UTC (permalink / raw)
To: djwong; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
We only use EFIs to free metadata blocks -- not regular data/attr fork
extents. Remove all the fields that we never use, for a net reduction
of 16 bytes.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/libxfs/xfs_alloc.c | 25 ++++++++++++++++---------
fs/xfs/libxfs/xfs_alloc.h | 8 ++++++--
fs/xfs/xfs_extfree_item.c | 13 ++++++++++---
3 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 9bc1a03a8167..353e53b892e6 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2462,12 +2462,11 @@ xfs_defer_agfl_block(
ASSERT(xfs_extfree_item_cache != NULL);
ASSERT(oinfo != NULL);
- new = kmem_cache_alloc(xfs_extfree_item_cache,
+ new = kmem_cache_zalloc(xfs_extfree_item_cache,
GFP_KERNEL | __GFP_NOFAIL);
new->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
new->xefi_blockcount = 1;
- new->xefi_oinfo = *oinfo;
- new->xefi_skip_discard = false;
+ new->xefi_owner = oinfo->oi_owner;
trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1);
@@ -2505,15 +2504,23 @@ __xfs_free_extent_later(
#endif
ASSERT(xfs_extfree_item_cache != NULL);
- new = kmem_cache_alloc(xfs_extfree_item_cache,
+ new = kmem_cache_zalloc(xfs_extfree_item_cache,
GFP_KERNEL | __GFP_NOFAIL);
new->xefi_startblock = bno;
new->xefi_blockcount = (xfs_extlen_t)len;
- if (oinfo)
- new->xefi_oinfo = *oinfo;
- else
- new->xefi_oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
- new->xefi_skip_discard = skip_discard;
+ if (skip_discard)
+ new->xefi_flags |= XFS_EFI_SKIP_DISCARD;
+ if (oinfo) {
+ ASSERT(oinfo->oi_offset == 0);
+
+ if (oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK)
+ new->xefi_flags |= XFS_EFI_ATTR_FORK;
+ if (oinfo->oi_flags & XFS_OWNER_INFO_BMBT_BLOCK)
+ new->xefi_flags |= XFS_EFI_BMBT_BLOCK;
+ new->xefi_owner = oinfo->oi_owner;
+ } else {
+ new->xefi_owner = XFS_RMAP_OWN_NULL;
+ }
trace_xfs_bmap_free_defer(tp->t_mountp,
XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
index b61aeb6fbe32..1c14a0b1abea 100644
--- a/fs/xfs/libxfs/xfs_alloc.h
+++ b/fs/xfs/libxfs/xfs_alloc.h
@@ -258,12 +258,16 @@ void __xfs_free_extent_later(struct xfs_trans *tp, xfs_fsblock_t bno,
*/
struct xfs_extent_free_item {
struct list_head xefi_list;
+ uint64_t xefi_owner;
xfs_fsblock_t xefi_startblock;/* starting fs block number */
xfs_extlen_t xefi_blockcount;/* number of blocks in extent */
- bool xefi_skip_discard;
- struct xfs_owner_info xefi_oinfo; /* extent owner */
+ unsigned int xefi_flags;
};
+#define XFS_EFI_SKIP_DISCARD (1U << 0) /* don't issue discard */
+#define XFS_EFI_ATTR_FORK (1U << 1) /* freeing attr fork block */
+#define XFS_EFI_BMBT_BLOCK (1U << 2) /* freeing bmap btree block */
+
static inline void
xfs_free_extent_later(
struct xfs_trans *tp,
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index eb378e345f13..47ef9c9c5c17 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -474,14 +474,20 @@ xfs_extent_free_finish_item(
struct list_head *item,
struct xfs_btree_cur **state)
{
+ struct xfs_owner_info oinfo = { };
struct xfs_extent_free_item *free;
int error;
free = container_of(item, struct xfs_extent_free_item, xefi_list);
+ oinfo.oi_owner = free->xefi_owner;
+ if (free->xefi_flags & XFS_EFI_ATTR_FORK)
+ oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
+ if (free->xefi_flags & XFS_EFI_BMBT_BLOCK)
+ oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
error = xfs_trans_free_extent(tp, EFD_ITEM(done),
free->xefi_startblock,
free->xefi_blockcount,
- &free->xefi_oinfo, free->xefi_skip_discard);
+ &oinfo, free->xefi_flags & XFS_EFI_SKIP_DISCARD);
kmem_cache_free(xfs_extfree_item_cache, free);
return error;
}
@@ -525,6 +531,7 @@ xfs_agfl_free_finish_item(
struct list_head *item,
struct xfs_btree_cur **state)
{
+ struct xfs_owner_info oinfo = { };
struct xfs_mount *mp = tp->t_mountp;
struct xfs_efd_log_item *efdp = EFD_ITEM(done);
struct xfs_extent_free_item *free;
@@ -539,13 +546,13 @@ xfs_agfl_free_finish_item(
ASSERT(free->xefi_blockcount == 1);
agno = XFS_FSB_TO_AGNO(mp, free->xefi_startblock);
agbno = XFS_FSB_TO_AGBNO(mp, free->xefi_startblock);
+ oinfo.oi_owner = free->xefi_owner;
trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, free->xefi_blockcount);
error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
if (!error)
- error = xfs_free_agfl_block(tp, agno, agbno, agbp,
- &free->xefi_oinfo);
+ error = xfs_free_agfl_block(tp, agno, agbno, agbp, &oinfo);
/*
* Mark the transaction dirty, even on error. This ensures the
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/5] xfs: remove unused parameter from refcount code
2021-10-19 18:52 [PATCHSET 0/5] xfs: use slab caches for deferred log items Darrick J. Wong
` (3 preceding siblings ...)
2021-10-19 18:52 ` [PATCH 4/5] xfs: reduce the size of struct xfs_extent_free_item Darrick J. Wong
@ 2021-10-19 18:52 ` Darrick J. Wong
2021-10-20 10:46 ` Chandan Babu R
4 siblings, 1 reply; 12+ messages in thread
From: Darrick J. Wong @ 2021-10-19 18:52 UTC (permalink / raw)
To: djwong; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
The owner info parameter is always NULL, so get rid of the parameter.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/libxfs/xfs_refcount.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
index bb9e256f4970..327ba25e9e17 100644
--- a/fs/xfs/libxfs/xfs_refcount.c
+++ b/fs/xfs/libxfs/xfs_refcount.c
@@ -918,8 +918,7 @@ xfs_refcount_adjust_extents(
struct xfs_btree_cur *cur,
xfs_agblock_t *agbno,
xfs_extlen_t *aglen,
- enum xfs_refc_adjust_op adj,
- struct xfs_owner_info *oinfo)
+ enum xfs_refc_adjust_op adj)
{
struct xfs_refcount_irec ext, tmp;
int error;
@@ -977,7 +976,7 @@ xfs_refcount_adjust_extents(
cur->bc_ag.pag->pag_agno,
tmp.rc_startblock);
xfs_free_extent_later(cur->bc_tp, fsbno,
- tmp.rc_blockcount, oinfo);
+ tmp.rc_blockcount, NULL);
}
(*agbno) += tmp.rc_blockcount;
@@ -1021,8 +1020,8 @@ xfs_refcount_adjust_extents(
fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
cur->bc_ag.pag->pag_agno,
ext.rc_startblock);
- xfs_free_extent_later(cur->bc_tp, fsbno, ext.rc_blockcount,
- oinfo);
+ xfs_free_extent_later(cur->bc_tp, fsbno,
+ ext.rc_blockcount, NULL);
}
skip:
@@ -1050,8 +1049,7 @@ xfs_refcount_adjust(
xfs_extlen_t aglen,
xfs_agblock_t *new_agbno,
xfs_extlen_t *new_aglen,
- enum xfs_refc_adjust_op adj,
- struct xfs_owner_info *oinfo)
+ enum xfs_refc_adjust_op adj)
{
bool shape_changed;
int shape_changes = 0;
@@ -1094,8 +1092,7 @@ xfs_refcount_adjust(
cur->bc_ag.refc.shape_changes++;
/* Now that we've taken care of the ends, adjust the middle extents */
- error = xfs_refcount_adjust_extents(cur, new_agbno, new_aglen,
- adj, oinfo);
+ error = xfs_refcount_adjust_extents(cur, new_agbno, new_aglen, adj);
if (error)
goto out_error;
@@ -1190,12 +1187,12 @@ xfs_refcount_finish_one(
switch (type) {
case XFS_REFCOUNT_INCREASE:
error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
- new_len, XFS_REFCOUNT_ADJUST_INCREASE, NULL);
+ new_len, XFS_REFCOUNT_ADJUST_INCREASE);
*new_fsb = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
break;
case XFS_REFCOUNT_DECREASE:
error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
- new_len, XFS_REFCOUNT_ADJUST_DECREASE, NULL);
+ new_len, XFS_REFCOUNT_ADJUST_DECREASE);
*new_fsb = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
break;
case XFS_REFCOUNT_ALLOC_COW:
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/5] xfs: compact deferred intent item structures
2021-10-19 18:52 ` [PATCH 1/5] xfs: compact deferred intent item structures Darrick J. Wong
@ 2021-10-20 10:44 ` Chandan Babu R
0 siblings, 0 replies; 12+ messages in thread
From: Chandan Babu R @ 2021-10-20 10:44 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs
On 20 Oct 2021 at 00:22, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> Rearrange these structs to reduce the amount of unused padding bytes.
> This saves eight bytes for each of the three structs changed here, which
> means they're now all (rmap/bmap are 64 bytes, refc is 32 bytes) even
> powers of two.
>
Looks good to me.
Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
> fs/xfs/libxfs/xfs_bmap.h | 2 +-
> fs/xfs/libxfs/xfs_refcount.h | 2 +-
> fs/xfs/libxfs/xfs_rmap.h | 2 +-
> 3 files changed, 3 insertions(+), 3 deletions(-)
>
>
> diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
> index 2cd7717cf753..db01fe83bb8a 100644
> --- a/fs/xfs/libxfs/xfs_bmap.h
> +++ b/fs/xfs/libxfs/xfs_bmap.h
> @@ -257,8 +257,8 @@ enum xfs_bmap_intent_type {
> struct xfs_bmap_intent {
> struct list_head bi_list;
> enum xfs_bmap_intent_type bi_type;
> - struct xfs_inode *bi_owner;
> int bi_whichfork;
> + struct xfs_inode *bi_owner;
> struct xfs_bmbt_irec bi_bmap;
> };
>
> diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h
> index 02cb3aa405be..894045968bc6 100644
> --- a/fs/xfs/libxfs/xfs_refcount.h
> +++ b/fs/xfs/libxfs/xfs_refcount.h
> @@ -32,8 +32,8 @@ enum xfs_refcount_intent_type {
> struct xfs_refcount_intent {
> struct list_head ri_list;
> enum xfs_refcount_intent_type ri_type;
> - xfs_fsblock_t ri_startblock;
> xfs_extlen_t ri_blockcount;
> + xfs_fsblock_t ri_startblock;
> };
>
> void xfs_refcount_increase_extent(struct xfs_trans *tp,
> diff --git a/fs/xfs/libxfs/xfs_rmap.h b/fs/xfs/libxfs/xfs_rmap.h
> index fd67904ed446..85dd98ac3f12 100644
> --- a/fs/xfs/libxfs/xfs_rmap.h
> +++ b/fs/xfs/libxfs/xfs_rmap.h
> @@ -159,8 +159,8 @@ enum xfs_rmap_intent_type {
> struct xfs_rmap_intent {
> struct list_head ri_list;
> enum xfs_rmap_intent_type ri_type;
> - uint64_t ri_owner;
> int ri_whichfork;
> + uint64_t ri_owner;
> struct xfs_bmbt_irec ri_bmap;
> };
>
--
chandan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/5] xfs: create slab caches for frequently-used deferred items
2021-10-19 18:52 ` [PATCH 2/5] xfs: create slab caches for frequently-used deferred items Darrick J. Wong
@ 2021-10-20 10:45 ` Chandan Babu R
2021-10-21 1:56 ` Darrick J. Wong
0 siblings, 1 reply; 12+ messages in thread
From: Chandan Babu R @ 2021-10-20 10:45 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs
On 20 Oct 2021 at 00:22, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> Create slab caches for the high-level structures that coordinate
> deferred intent items, since they're used fairly heavily.
>
Apart from the nits pointed later in this mail, the remaining changes looks
good to me.
Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
> fs/xfs/libxfs/xfs_bmap.c | 21 +++++++++++++-
> fs/xfs/libxfs/xfs_bmap.h | 5 +++
> fs/xfs/libxfs/xfs_defer.c | 62 +++++++++++++++++++++++++++++++++++++++---
> fs/xfs/libxfs/xfs_defer.h | 3 ++
> fs/xfs/libxfs/xfs_refcount.c | 23 ++++++++++++++--
> fs/xfs/libxfs/xfs_refcount.h | 5 +++
> fs/xfs/libxfs/xfs_rmap.c | 21 ++++++++++++++
> fs/xfs/libxfs/xfs_rmap.h | 5 +++
> fs/xfs/xfs_bmap_item.c | 4 +--
> fs/xfs/xfs_refcount_item.c | 4 +--
> fs/xfs/xfs_rmap_item.c | 4 +--
> fs/xfs/xfs_super.c | 10 ++++++-
> 12 files changed, 151 insertions(+), 16 deletions(-)
>
>
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index 8a993ef6b7f4..ef2ac0ecaed9 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -37,7 +37,7 @@
> #include "xfs_icache.h"
> #include "xfs_iomap.h"
>
> -
> +struct kmem_cache *xfs_bmap_intent_cache;
> struct kmem_cache *xfs_bmap_free_item_cache;
>
> /*
> @@ -6190,7 +6190,7 @@ __xfs_bmap_add(
> bmap->br_blockcount,
> bmap->br_state);
>
> - bi = kmem_alloc(sizeof(struct xfs_bmap_intent), KM_NOFS);
> + bi = kmem_cache_alloc(xfs_bmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
> INIT_LIST_HEAD(&bi->bi_list);
> bi->bi_type = type;
> bi->bi_owner = ip;
> @@ -6301,3 +6301,20 @@ xfs_bmap_validate_extent(
> return __this_address;
> return NULL;
> }
> +
> +int __init
> +xfs_bmap_intent_init_cache(void)
> +{
> + xfs_bmap_intent_cache = kmem_cache_create("xfs_bmap_intent",
> + sizeof(struct xfs_bmap_intent),
> + 0, 0, NULL);
> +
> + return xfs_bmap_intent_cache != NULL ? 0 : -ENOMEM;
> +}
> +
> +void
> +xfs_bmap_intent_destroy_cache(void)
> +{
> + kmem_cache_destroy(xfs_bmap_intent_cache);
> + xfs_bmap_intent_cache = NULL;
> +}
> diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
> index db01fe83bb8a..fa73a56827b1 100644
> --- a/fs/xfs/libxfs/xfs_bmap.h
> +++ b/fs/xfs/libxfs/xfs_bmap.h
> @@ -290,4 +290,9 @@ int xfs_bmapi_remap(struct xfs_trans *tp, struct xfs_inode *ip,
> xfs_fileoff_t bno, xfs_filblks_t len, xfs_fsblock_t startblock,
> int flags);
>
> +extern struct kmem_cache *xfs_bmap_intent_cache;
> +
> +int __init xfs_bmap_intent_init_cache(void);
> +void xfs_bmap_intent_destroy_cache(void);
> +
> #endif /* __XFS_BMAP_H__ */
> diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
> index 136a367d7b16..641a5dee4ffc 100644
> --- a/fs/xfs/libxfs/xfs_defer.c
> +++ b/fs/xfs/libxfs/xfs_defer.c
> @@ -18,6 +18,11 @@
> #include "xfs_trace.h"
> #include "xfs_icache.h"
> #include "xfs_log.h"
> +#include "xfs_rmap.h"
> +#include "xfs_refcount.h"
> +#include "xfs_bmap.h"
> +
> +static struct kmem_cache *xfs_defer_pending_cache;
>
> /*
> * Deferred Operations in XFS
> @@ -365,7 +370,7 @@ xfs_defer_cancel_list(
> ops->cancel_item(pwi);
> }
> ASSERT(dfp->dfp_count == 0);
> - kmem_free(dfp);
> + kmem_cache_free(xfs_defer_pending_cache, dfp);
> }
> }
>
> @@ -462,7 +467,7 @@ xfs_defer_finish_one(
>
> /* Done with the dfp, free it. */
> list_del(&dfp->dfp_list);
> - kmem_free(dfp);
> + kmem_cache_free(xfs_defer_pending_cache, dfp);
> out:
> if (ops->finish_cleanup)
> ops->finish_cleanup(tp, state, error);
> @@ -596,8 +601,8 @@ xfs_defer_add(
> dfp = NULL;
> }
> if (!dfp) {
> - dfp = kmem_alloc(sizeof(struct xfs_defer_pending),
> - KM_NOFS);
> + dfp = kmem_cache_zalloc(xfs_defer_pending_cache,
> + GFP_NOFS | __GFP_NOFAIL);
> dfp->dfp_type = type;
> dfp->dfp_intent = NULL;
> dfp->dfp_done = NULL;
> @@ -809,3 +814,52 @@ xfs_defer_resources_rele(
> dres->dr_bufs = 0;
> dres->dr_ordered = 0;
> }
> +
> +static inline int __init
> +xfs_defer_init_cache(void)
> +{
> + xfs_defer_pending_cache = kmem_cache_create("xfs_defer_pending",
> + sizeof(struct xfs_defer_pending),
> + 0, 0, NULL);
> +
> + return xfs_defer_pending_cache != NULL ? 0 : -ENOMEM;
> +}
> +
> +static inline void
> +xfs_defer_destroy_cache(void)
> +{
> + kmem_cache_destroy(xfs_defer_pending_cache);
> + xfs_defer_pending_cache = NULL;
> +}
> +
> +/* Set up caches for deferred work items. */
> +int __init
> +xfs_defer_init_item_caches(void)
> +{
> + int error;
> +
> + error = xfs_defer_init_cache();
> + if (error)
> + return error;
> + error = xfs_rmap_intent_init_cache();
> + if (error)
> + return error;
> + error = xfs_refcount_intent_init_cache();
> + if (error)
> + return error;
> + error = xfs_bmap_intent_init_cache();
> + if (error)
> + return error;
> +
If the call to xfs_rmap_intent_init_cache() fails, then we don't free up
xfs_defer_pending_cache. Same logic applies to the rest of initialization
functions called above.
> + return 0;
> +}
> +
> +/* Destroy all the deferred work item caches, if they've been allocated. */
> +void
> +xfs_defer_destroy_item_caches(void)
> +{
> + xfs_bmap_intent_destroy_cache();
> + xfs_refcount_intent_destroy_cache();
> + xfs_rmap_intent_destroy_cache();
> + xfs_defer_destroy_cache();
> +}
> diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h
> index 7952695c7c41..7bb8a31ad65b 100644
> --- a/fs/xfs/libxfs/xfs_defer.h
> +++ b/fs/xfs/libxfs/xfs_defer.h
> @@ -122,4 +122,7 @@ void xfs_defer_ops_capture_free(struct xfs_mount *mp,
> struct xfs_defer_capture *d);
> void xfs_defer_resources_rele(struct xfs_defer_resources *dres);
>
> +int __init xfs_defer_init_item_caches(void);
> +void xfs_defer_destroy_item_caches(void);
> +
> #endif /* __XFS_DEFER_H__ */
> diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
> index e5d767a7fc5d..2c03df715d4f 100644
> --- a/fs/xfs/libxfs/xfs_refcount.c
> +++ b/fs/xfs/libxfs/xfs_refcount.c
> @@ -24,6 +24,8 @@
> #include "xfs_rmap.h"
> #include "xfs_ag.h"
>
> +struct kmem_cache *xfs_refcount_intent_cache;
> +
> /* Allowable refcount adjustment amounts. */
> enum xfs_refc_adjust_op {
> XFS_REFCOUNT_ADJUST_INCREASE = 1,
> @@ -1235,8 +1237,8 @@ __xfs_refcount_add(
> type, XFS_FSB_TO_AGBNO(tp->t_mountp, startblock),
> blockcount);
>
> - ri = kmem_alloc(sizeof(struct xfs_refcount_intent),
> - KM_NOFS);
> + ri = kmem_cache_alloc(xfs_refcount_intent_cache,
> + GFP_NOFS | __GFP_NOFAIL);
> INIT_LIST_HEAD(&ri->ri_list);
> ri->ri_type = type;
> ri->ri_startblock = startblock;
> @@ -1782,3 +1784,20 @@ xfs_refcount_has_record(
>
> return xfs_btree_has_record(cur, &low, &high, exists);
> }
> +
> +int __init
> +xfs_refcount_intent_init_cache(void)
> +{
> + xfs_refcount_intent_cache = kmem_cache_create("xfs_refc_intent",
> + sizeof(struct xfs_refcount_intent),
> + 0, 0, NULL);
> +
> + return xfs_refcount_intent_cache != NULL ? 0 : -ENOMEM;
> +}
> +
> +void
> +xfs_refcount_intent_destroy_cache(void)
> +{
> + kmem_cache_destroy(xfs_refcount_intent_cache);
> + xfs_refcount_intent_cache = NULL;
> +}
> diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h
> index 894045968bc6..9eb01edbd89d 100644
> --- a/fs/xfs/libxfs/xfs_refcount.h
> +++ b/fs/xfs/libxfs/xfs_refcount.h
> @@ -83,4 +83,9 @@ extern void xfs_refcount_btrec_to_irec(const union xfs_btree_rec *rec,
> extern int xfs_refcount_insert(struct xfs_btree_cur *cur,
> struct xfs_refcount_irec *irec, int *stat);
>
> +extern struct kmem_cache *xfs_refcount_intent_cache;
> +
> +int __init xfs_refcount_intent_init_cache(void);
> +void xfs_refcount_intent_destroy_cache(void);
> +
> #endif /* __XFS_REFCOUNT_H__ */
> diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c
> index f45929b1b94a..cd322174dbff 100644
> --- a/fs/xfs/libxfs/xfs_rmap.c
> +++ b/fs/xfs/libxfs/xfs_rmap.c
> @@ -24,6 +24,8 @@
> #include "xfs_inode.h"
> #include "xfs_ag.h"
>
> +struct kmem_cache *xfs_rmap_intent_cache;
> +
> /*
> * Lookup the first record less than or equal to [bno, len, owner, offset]
> * in the btree given by cur.
> @@ -2485,7 +2487,7 @@ __xfs_rmap_add(
> bmap->br_blockcount,
> bmap->br_state);
>
> - ri = kmem_alloc(sizeof(struct xfs_rmap_intent), KM_NOFS);
> + ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
> INIT_LIST_HEAD(&ri->ri_list);
> ri->ri_type = type;
> ri->ri_owner = owner;
> @@ -2779,3 +2781,20 @@ const struct xfs_owner_info XFS_RMAP_OINFO_REFC = {
> const struct xfs_owner_info XFS_RMAP_OINFO_COW = {
> .oi_owner = XFS_RMAP_OWN_COW,
> };
> +
> +int __init
> +xfs_rmap_intent_init_cache(void)
> +{
> + xfs_rmap_intent_cache = kmem_cache_create("xfs_rmap_intent",
> + sizeof(struct xfs_rmap_intent),
> + 0, 0, NULL);
> +
> + return xfs_rmap_intent_cache != NULL ? 0 : -ENOMEM;
> +}
> +
> +void
> +xfs_rmap_intent_destroy_cache(void)
> +{
> + kmem_cache_destroy(xfs_rmap_intent_cache);
> + xfs_rmap_intent_cache = NULL;
> +}
> diff --git a/fs/xfs/libxfs/xfs_rmap.h b/fs/xfs/libxfs/xfs_rmap.h
> index 85dd98ac3f12..b718ebeda372 100644
> --- a/fs/xfs/libxfs/xfs_rmap.h
> +++ b/fs/xfs/libxfs/xfs_rmap.h
> @@ -215,4 +215,9 @@ extern const struct xfs_owner_info XFS_RMAP_OINFO_INODES;
> extern const struct xfs_owner_info XFS_RMAP_OINFO_REFC;
> extern const struct xfs_owner_info XFS_RMAP_OINFO_COW;
>
> +extern struct kmem_cache *xfs_rmap_intent_cache;
> +
> +int __init xfs_rmap_intent_init_cache(void);
> +void xfs_rmap_intent_destroy_cache(void);
> +
> #endif /* __XFS_RMAP_H__ */
> diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
> index 6049f0722181..e1f4d7d5a011 100644
> --- a/fs/xfs/xfs_bmap_item.c
> +++ b/fs/xfs/xfs_bmap_item.c
> @@ -384,7 +384,7 @@ xfs_bmap_update_finish_item(
> bmap->bi_bmap.br_blockcount = count;
> return -EAGAIN;
> }
> - kmem_free(bmap);
> + kmem_cache_free(xfs_bmap_intent_cache, bmap);
> return error;
> }
>
> @@ -404,7 +404,7 @@ xfs_bmap_update_cancel_item(
> struct xfs_bmap_intent *bmap;
>
> bmap = container_of(item, struct xfs_bmap_intent, bi_list);
> - kmem_free(bmap);
> + kmem_cache_free(xfs_bmap_intent_cache, bmap);
> }
>
> const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
> diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
> index f23e86e06bfb..d3da67772d57 100644
> --- a/fs/xfs/xfs_refcount_item.c
> +++ b/fs/xfs/xfs_refcount_item.c
> @@ -384,7 +384,7 @@ xfs_refcount_update_finish_item(
> refc->ri_blockcount = new_aglen;
> return -EAGAIN;
> }
> - kmem_free(refc);
> + kmem_cache_free(xfs_refcount_intent_cache, refc);
> return error;
> }
>
> @@ -404,7 +404,7 @@ xfs_refcount_update_cancel_item(
> struct xfs_refcount_intent *refc;
>
> refc = container_of(item, struct xfs_refcount_intent, ri_list);
> - kmem_free(refc);
> + kmem_cache_free(xfs_refcount_intent_cache, refc);
> }
>
> const struct xfs_defer_op_type xfs_refcount_update_defer_type = {
> diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
> index b5cdeb10927e..c3966b4c58ef 100644
> --- a/fs/xfs/xfs_rmap_item.c
> +++ b/fs/xfs/xfs_rmap_item.c
> @@ -427,7 +427,7 @@ xfs_rmap_update_finish_item(
> rmap->ri_bmap.br_startoff, rmap->ri_bmap.br_startblock,
> rmap->ri_bmap.br_blockcount, rmap->ri_bmap.br_state,
> state);
> - kmem_free(rmap);
> + kmem_cache_free(xfs_rmap_intent_cache, rmap);
> return error;
> }
>
> @@ -447,7 +447,7 @@ xfs_rmap_update_cancel_item(
> struct xfs_rmap_intent *rmap;
>
> rmap = container_of(item, struct xfs_rmap_intent, ri_list);
> - kmem_free(rmap);
> + kmem_cache_free(xfs_rmap_intent_cache, rmap);
> }
>
> const struct xfs_defer_op_type xfs_rmap_update_defer_type = {
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 0afa47378211..8909e08cbf77 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -38,6 +38,7 @@
> #include "xfs_pwork.h"
> #include "xfs_ag.h"
> #include "xfs_btree.h"
> +#include "xfs_defer.h"
>
> #include <linux/magic.h>
> #include <linux/fs_context.h>
> @@ -1972,11 +1973,15 @@ xfs_init_caches(void)
> if (error)
> goto out_destroy_bmap_free_item_cache;
>
> + error = xfs_defer_init_item_caches();
> + if (error)
> + goto out_destroy_btree_cur_cache;
> +
> xfs_da_state_cache = kmem_cache_create("xfs_da_state",
> sizeof(struct xfs_da_state),
> 0, 0, NULL);
> if (!xfs_da_state_cache)
> - goto out_destroy_btree_cur_cache;
> + goto out_destroy_defer_item_cache;
>
> xfs_ifork_cache = kmem_cache_create("xfs_ifork",
> sizeof(struct xfs_ifork),
> @@ -2106,6 +2111,8 @@ xfs_init_caches(void)
> kmem_cache_destroy(xfs_ifork_cache);
> out_destroy_da_state_cache:
> kmem_cache_destroy(xfs_da_state_cache);
> + out_destroy_defer_item_cache:
> + xfs_defer_destroy_item_caches();
> out_destroy_btree_cur_cache:
> xfs_btree_destroy_cur_caches();
> out_destroy_bmap_free_item_cache:
> @@ -2140,6 +2147,7 @@ xfs_destroy_caches(void)
> kmem_cache_destroy(xfs_ifork_cache);
> kmem_cache_destroy(xfs_da_state_cache);
> xfs_btree_destroy_cur_caches();
> + xfs_defer_destroy_item_caches();
Since caches are being freed in the reverse order of their creation,
xfs_defer_destroy_item_caches() should be invoked before
xfs_btree_destroy_cur_caches().
> kmem_cache_destroy(xfs_bmap_free_item_cache);
> kmem_cache_destroy(xfs_log_ticket_cache);
> }
--
chandan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/5] xfs: rename xfs_bmap_add_free to xfs_free_extent_later
2021-10-19 18:52 ` [PATCH 3/5] xfs: rename xfs_bmap_add_free to xfs_free_extent_later Darrick J. Wong
@ 2021-10-20 10:45 ` Chandan Babu R
0 siblings, 0 replies; 12+ messages in thread
From: Chandan Babu R @ 2021-10-20 10:45 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs
On 20 Oct 2021 at 00:22, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> xfs_bmap_add_free isn't a block mapping function; it schedules deferred
> freeing operations for a later point in a compound transaction chain.
> While it's primarily used by bunmapi, its use has expanded beyond that.
> Move it to xfs_alloc.c and rename the function since it's now general
> freeing functionality. Bring the slab cache bits in line with the
> way we handle the other intent items.
Looks good to me.
Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>
>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
> fs/xfs/libxfs/xfs_ag.c | 2 +
> fs/xfs/libxfs/xfs_alloc.c | 71 ++++++++++++++++++++++++++++++++++++++--
> fs/xfs/libxfs/xfs_alloc.h | 32 ++++++++++++++++++
> fs/xfs/libxfs/xfs_bmap.c | 55 +------------------------------
> fs/xfs/libxfs/xfs_bmap.h | 28 ----------------
> fs/xfs/libxfs/xfs_bmap_btree.c | 2 +
> fs/xfs/libxfs/xfs_defer.c | 5 +++
> fs/xfs/libxfs/xfs_ialloc.c | 4 +-
> fs/xfs/libxfs/xfs_refcount.c | 6 ++-
> fs/xfs/xfs_extfree_item.c | 6 ++-
> fs/xfs/xfs_reflink.c | 2 +
> fs/xfs/xfs_super.c | 11 +-----
> 12 files changed, 118 insertions(+), 106 deletions(-)
>
>
> diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c
> index 005abfd9fd34..d7d875cef07a 100644
> --- a/fs/xfs/libxfs/xfs_ag.c
> +++ b/fs/xfs/libxfs/xfs_ag.c
> @@ -850,7 +850,7 @@ xfs_ag_shrink_space(
> if (err2 != -ENOSPC)
> goto resv_err;
>
> - __xfs_bmap_add_free(*tpp, args.fsbno, delta, NULL, true);
> + __xfs_free_extent_later(*tpp, args.fsbno, delta, NULL, true);
>
> /*
> * Roll the transaction before trying to re-init the per-ag
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index ccfe66df3e62..9bc1a03a8167 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -27,7 +27,7 @@
> #include "xfs_ag_resv.h"
> #include "xfs_bmap.h"
>
> -extern struct kmem_cache *xfs_bmap_free_item_cache;
> +struct kmem_cache *xfs_extfree_item_cache;
>
> struct workqueue_struct *xfs_alloc_wq;
>
> @@ -2440,7 +2440,7 @@ xfs_agfl_reset(
>
> /*
> * Defer an AGFL block free. This is effectively equivalent to
> - * xfs_bmap_add_free() with some special handling particular to AGFL blocks.
> + * xfs_free_extent_later() with some special handling particular to AGFL blocks.
> *
> * Deferring AGFL frees helps prevent log reservation overruns due to too many
> * allocation operations in a transaction. AGFL frees are prone to this problem
> @@ -2459,10 +2459,10 @@ xfs_defer_agfl_block(
> struct xfs_mount *mp = tp->t_mountp;
> struct xfs_extent_free_item *new; /* new element */
>
> - ASSERT(xfs_bmap_free_item_cache != NULL);
> + ASSERT(xfs_extfree_item_cache != NULL);
> ASSERT(oinfo != NULL);
>
> - new = kmem_cache_alloc(xfs_bmap_free_item_cache,
> + new = kmem_cache_alloc(xfs_extfree_item_cache,
> GFP_KERNEL | __GFP_NOFAIL);
> new->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
> new->xefi_blockcount = 1;
> @@ -2474,6 +2474,52 @@ xfs_defer_agfl_block(
> xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &new->xefi_list);
> }
>
> +/*
> + * Add the extent to the list of extents to be free at transaction end.
> + * The list is maintained sorted (by block number).
> + */
> +void
> +__xfs_free_extent_later(
> + struct xfs_trans *tp,
> + xfs_fsblock_t bno,
> + xfs_filblks_t len,
> + const struct xfs_owner_info *oinfo,
> + bool skip_discard)
> +{
> + struct xfs_extent_free_item *new; /* new element */
> +#ifdef DEBUG
> + struct xfs_mount *mp = tp->t_mountp;
> + xfs_agnumber_t agno;
> + xfs_agblock_t agbno;
> +
> + ASSERT(bno != NULLFSBLOCK);
> + ASSERT(len > 0);
> + ASSERT(len <= MAXEXTLEN);
> + ASSERT(!isnullstartblock(bno));
> + agno = XFS_FSB_TO_AGNO(mp, bno);
> + agbno = XFS_FSB_TO_AGBNO(mp, bno);
> + ASSERT(agno < mp->m_sb.sb_agcount);
> + ASSERT(agbno < mp->m_sb.sb_agblocks);
> + ASSERT(len < mp->m_sb.sb_agblocks);
> + ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
> +#endif
> + ASSERT(xfs_extfree_item_cache != NULL);
> +
> + new = kmem_cache_alloc(xfs_extfree_item_cache,
> + GFP_KERNEL | __GFP_NOFAIL);
> + new->xefi_startblock = bno;
> + new->xefi_blockcount = (xfs_extlen_t)len;
> + if (oinfo)
> + new->xefi_oinfo = *oinfo;
> + else
> + new->xefi_oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
> + new->xefi_skip_discard = skip_discard;
> + trace_xfs_bmap_free_defer(tp->t_mountp,
> + XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
> + XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
> + xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list);
> +}
> +
> #ifdef DEBUG
> /*
> * Check if an AGF has a free extent record whose length is equal to
> @@ -3499,3 +3545,20 @@ xfs_agfl_walk(
>
> return 0;
> }
> +
> +int __init
> +xfs_extfree_intent_init_cache(void)
> +{
> + xfs_extfree_item_cache = kmem_cache_create("xfs_extfree_intent",
> + sizeof(struct xfs_extent_free_item),
> + 0, 0, NULL);
> +
> + return xfs_extfree_item_cache != NULL ? 0 : -ENOMEM;
> +}
> +
> +void
> +xfs_extfree_intent_destroy_cache(void)
> +{
> + kmem_cache_destroy(xfs_extfree_item_cache);
> + xfs_extfree_item_cache = NULL;
> +}
> diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
> index 2f3f8c2e0860..b61aeb6fbe32 100644
> --- a/fs/xfs/libxfs/xfs_alloc.h
> +++ b/fs/xfs/libxfs/xfs_alloc.h
> @@ -248,4 +248,36 @@ xfs_buf_to_agfl_bno(
> return bp->b_addr;
> }
>
> +void __xfs_free_extent_later(struct xfs_trans *tp, xfs_fsblock_t bno,
> + xfs_filblks_t len, const struct xfs_owner_info *oinfo,
> + bool skip_discard);
> +
> +/*
> + * List of extents to be free "later".
> + * The list is kept sorted on xbf_startblock.
> + */
> +struct xfs_extent_free_item {
> + struct list_head xefi_list;
> + xfs_fsblock_t xefi_startblock;/* starting fs block number */
> + xfs_extlen_t xefi_blockcount;/* number of blocks in extent */
> + bool xefi_skip_discard;
> + struct xfs_owner_info xefi_oinfo; /* extent owner */
> +};
> +
> +static inline void
> +xfs_free_extent_later(
> + struct xfs_trans *tp,
> + xfs_fsblock_t bno,
> + xfs_filblks_t len,
> + const struct xfs_owner_info *oinfo)
> +{
> + __xfs_free_extent_later(tp, bno, len, oinfo, false);
> +}
> +
> +
> +extern struct kmem_cache *xfs_extfree_item_cache;
> +
> +int __init xfs_extfree_intent_init_cache(void);
> +void xfs_extfree_intent_destroy_cache(void);
> +
> #endif /* __XFS_ALLOC_H__ */
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index ef2ac0ecaed9..4dccd4d90622 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -38,7 +38,6 @@
> #include "xfs_iomap.h"
>
> struct kmem_cache *xfs_bmap_intent_cache;
> -struct kmem_cache *xfs_bmap_free_item_cache;
>
> /*
> * Miscellaneous helper functions
> @@ -522,56 +521,6 @@ xfs_bmap_validate_ret(
> #define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do { } while (0)
> #endif /* DEBUG */
>
> -/*
> - * bmap free list manipulation functions
> - */
> -
> -/*
> - * Add the extent to the list of extents to be free at transaction end.
> - * The list is maintained sorted (by block number).
> - */
> -void
> -__xfs_bmap_add_free(
> - struct xfs_trans *tp,
> - xfs_fsblock_t bno,
> - xfs_filblks_t len,
> - const struct xfs_owner_info *oinfo,
> - bool skip_discard)
> -{
> - struct xfs_extent_free_item *new; /* new element */
> -#ifdef DEBUG
> - struct xfs_mount *mp = tp->t_mountp;
> - xfs_agnumber_t agno;
> - xfs_agblock_t agbno;
> -
> - ASSERT(bno != NULLFSBLOCK);
> - ASSERT(len > 0);
> - ASSERT(len <= MAXEXTLEN);
> - ASSERT(!isnullstartblock(bno));
> - agno = XFS_FSB_TO_AGNO(mp, bno);
> - agbno = XFS_FSB_TO_AGBNO(mp, bno);
> - ASSERT(agno < mp->m_sb.sb_agcount);
> - ASSERT(agbno < mp->m_sb.sb_agblocks);
> - ASSERT(len < mp->m_sb.sb_agblocks);
> - ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
> -#endif
> - ASSERT(xfs_bmap_free_item_cache != NULL);
> -
> - new = kmem_cache_alloc(xfs_bmap_free_item_cache,
> - GFP_KERNEL | __GFP_NOFAIL);
> - new->xefi_startblock = bno;
> - new->xefi_blockcount = (xfs_extlen_t)len;
> - if (oinfo)
> - new->xefi_oinfo = *oinfo;
> - else
> - new->xefi_oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
> - new->xefi_skip_discard = skip_discard;
> - trace_xfs_bmap_free_defer(tp->t_mountp,
> - XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
> - XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
> - xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list);
> -}
> -
> /*
> * Inode fork format manipulation functions
> */
> @@ -626,7 +575,7 @@ xfs_bmap_btree_to_extents(
> if ((error = xfs_btree_check_block(cur, cblock, 0, cbp)))
> return error;
> xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork);
> - xfs_bmap_add_free(cur->bc_tp, cbno, 1, &oinfo);
> + xfs_free_extent_later(cur->bc_tp, cbno, 1, &oinfo);
> ip->i_nblocks--;
> xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
> xfs_trans_binval(tp, cbp);
> @@ -5297,7 +5246,7 @@ xfs_bmap_del_extent_real(
> if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) {
> xfs_refcount_decrease_extent(tp, del);
> } else {
> - __xfs_bmap_add_free(tp, del->br_startblock,
> + __xfs_free_extent_later(tp, del->br_startblock,
> del->br_blockcount, NULL,
> (bflags & XFS_BMAPI_NODISCARD) ||
> del->br_state == XFS_EXT_UNWRITTEN);
> diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
> index fa73a56827b1..03d9aaf87413 100644
> --- a/fs/xfs/libxfs/xfs_bmap.h
> +++ b/fs/xfs/libxfs/xfs_bmap.h
> @@ -13,8 +13,6 @@ struct xfs_inode;
> struct xfs_mount;
> struct xfs_trans;
>
> -extern struct kmem_cache *xfs_bmap_free_item_cache;
> -
> /*
> * Argument structure for xfs_bmap_alloc.
> */
> @@ -44,19 +42,6 @@ struct xfs_bmalloca {
> int flags;
> };
>
> -/*
> - * List of extents to be free "later".
> - * The list is kept sorted on xbf_startblock.
> - */
> -struct xfs_extent_free_item
> -{
> - xfs_fsblock_t xefi_startblock;/* starting fs block number */
> - xfs_extlen_t xefi_blockcount;/* number of blocks in extent */
> - bool xefi_skip_discard;
> - struct list_head xefi_list;
> - struct xfs_owner_info xefi_oinfo; /* extent owner */
> -};
> -
> #define XFS_BMAP_MAX_NMAP 4
>
> /*
> @@ -189,9 +174,6 @@ unsigned int xfs_bmap_compute_attr_offset(struct xfs_mount *mp);
> int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);
> void xfs_bmap_local_to_extents_empty(struct xfs_trans *tp,
> struct xfs_inode *ip, int whichfork);
> -void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno,
> - xfs_filblks_t len, const struct xfs_owner_info *oinfo,
> - bool skip_discard);
> void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork);
> int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip,
> xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork);
> @@ -239,16 +221,6 @@ int xfs_bmap_add_extent_unwritten_real(struct xfs_trans *tp,
> struct xfs_iext_cursor *icur, struct xfs_btree_cur **curp,
> struct xfs_bmbt_irec *new, int *logflagsp);
>
> -static inline void
> -xfs_bmap_add_free(
> - struct xfs_trans *tp,
> - xfs_fsblock_t bno,
> - xfs_filblks_t len,
> - const struct xfs_owner_info *oinfo)
> -{
> - __xfs_bmap_add_free(tp, bno, len, oinfo, false);
> -}
> -
> enum xfs_bmap_intent_type {
> XFS_BMAP_MAP = 1,
> XFS_BMAP_UNMAP,
> diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c
> index 3c9a45233e60..453309fc85f2 100644
> --- a/fs/xfs/libxfs/xfs_bmap_btree.c
> +++ b/fs/xfs/libxfs/xfs_bmap_btree.c
> @@ -288,7 +288,7 @@ xfs_bmbt_free_block(
> struct xfs_owner_info oinfo;
>
> xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, cur->bc_ino.whichfork);
> - xfs_bmap_add_free(cur->bc_tp, fsbno, 1, &oinfo);
> + xfs_free_extent_later(cur->bc_tp, fsbno, 1, &oinfo);
> ip->i_nblocks--;
>
> xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
> diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
> index 641a5dee4ffc..3c43e5c93e7b 100644
> --- a/fs/xfs/libxfs/xfs_defer.c
> +++ b/fs/xfs/libxfs/xfs_defer.c
> @@ -21,6 +21,7 @@
> #include "xfs_rmap.h"
> #include "xfs_refcount.h"
> #include "xfs_bmap.h"
> +#include "xfs_alloc.h"
>
> static struct kmem_cache *xfs_defer_pending_cache;
>
> @@ -848,6 +849,9 @@ xfs_defer_init_item_caches(void)
> if (error)
> return error;
> error = xfs_bmap_intent_init_cache();
> + if (error)
> + return error;
> + error = xfs_extfree_intent_init_cache();
> if (error)
> return error;
>
> @@ -858,6 +862,7 @@ xfs_defer_init_item_caches(void)
> void
> xfs_defer_destroy_item_caches(void)
> {
> + xfs_extfree_intent_destroy_cache();
> xfs_bmap_intent_destroy_cache();
> xfs_refcount_intent_destroy_cache();
> xfs_rmap_intent_destroy_cache();
> diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
> index f78a600ca73f..b418fe0c0679 100644
> --- a/fs/xfs/libxfs/xfs_ialloc.c
> +++ b/fs/xfs/libxfs/xfs_ialloc.c
> @@ -1827,7 +1827,7 @@ xfs_difree_inode_chunk(
>
> if (!xfs_inobt_issparse(rec->ir_holemask)) {
> /* not sparse, calculate extent info directly */
> - xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, sagbno),
> + xfs_free_extent_later(tp, XFS_AGB_TO_FSB(mp, agno, sagbno),
> M_IGEO(mp)->ialloc_blks,
> &XFS_RMAP_OINFO_INODES);
> return;
> @@ -1872,7 +1872,7 @@ xfs_difree_inode_chunk(
>
> ASSERT(agbno % mp->m_sb.sb_spino_align == 0);
> ASSERT(contigblk % mp->m_sb.sb_spino_align == 0);
> - xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, agbno),
> + xfs_free_extent_later(tp, XFS_AGB_TO_FSB(mp, agno, agbno),
> contigblk, &XFS_RMAP_OINFO_INODES);
>
> /* reset range to current bit and carry on... */
> diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
> index 2c03df715d4f..bb9e256f4970 100644
> --- a/fs/xfs/libxfs/xfs_refcount.c
> +++ b/fs/xfs/libxfs/xfs_refcount.c
> @@ -976,7 +976,7 @@ xfs_refcount_adjust_extents(
> fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
> cur->bc_ag.pag->pag_agno,
> tmp.rc_startblock);
> - xfs_bmap_add_free(cur->bc_tp, fsbno,
> + xfs_free_extent_later(cur->bc_tp, fsbno,
> tmp.rc_blockcount, oinfo);
> }
>
> @@ -1021,7 +1021,7 @@ xfs_refcount_adjust_extents(
> fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
> cur->bc_ag.pag->pag_agno,
> ext.rc_startblock);
> - xfs_bmap_add_free(cur->bc_tp, fsbno, ext.rc_blockcount,
> + xfs_free_extent_later(cur->bc_tp, fsbno, ext.rc_blockcount,
> oinfo);
> }
>
> @@ -1744,7 +1744,7 @@ xfs_refcount_recover_cow_leftovers(
> rr->rr_rrec.rc_blockcount);
>
> /* Free the block. */
> - xfs_bmap_add_free(tp, fsb, rr->rr_rrec.rc_blockcount, NULL);
> + xfs_free_extent_later(tp, fsb, rr->rr_rrec.rc_blockcount, NULL);
>
> error = xfs_trans_commit(tp);
> if (error)
> diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
> index 26ac5048ce76..eb378e345f13 100644
> --- a/fs/xfs/xfs_extfree_item.c
> +++ b/fs/xfs/xfs_extfree_item.c
> @@ -482,7 +482,7 @@ xfs_extent_free_finish_item(
> free->xefi_startblock,
> free->xefi_blockcount,
> &free->xefi_oinfo, free->xefi_skip_discard);
> - kmem_cache_free(xfs_bmap_free_item_cache, free);
> + kmem_cache_free(xfs_extfree_item_cache, free);
> return error;
> }
>
> @@ -502,7 +502,7 @@ xfs_extent_free_cancel_item(
> struct xfs_extent_free_item *free;
>
> free = container_of(item, struct xfs_extent_free_item, xefi_list);
> - kmem_cache_free(xfs_bmap_free_item_cache, free);
> + kmem_cache_free(xfs_extfree_item_cache, free);
> }
>
> const struct xfs_defer_op_type xfs_extent_free_defer_type = {
> @@ -564,7 +564,7 @@ xfs_agfl_free_finish_item(
> extp->ext_len = free->xefi_blockcount;
> efdp->efd_next_extent++;
>
> - kmem_cache_free(xfs_bmap_free_item_cache, free);
> + kmem_cache_free(xfs_extfree_item_cache, free);
> return error;
> }
>
> diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
> index 76355f293488..cb0edb1d68ef 100644
> --- a/fs/xfs/xfs_reflink.c
> +++ b/fs/xfs/xfs_reflink.c
> @@ -484,7 +484,7 @@ xfs_reflink_cancel_cow_blocks(
> xfs_refcount_free_cow_extent(*tpp, del.br_startblock,
> del.br_blockcount);
>
> - xfs_bmap_add_free(*tpp, del.br_startblock,
> + xfs_free_extent_later(*tpp, del.br_startblock,
> del.br_blockcount, NULL);
>
> /* Roll the transaction */
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 8909e08cbf77..daa6d76b8dd0 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -1963,15 +1963,9 @@ xfs_init_caches(void)
> if (!xfs_log_ticket_cache)
> goto out;
>
> - xfs_bmap_free_item_cache = kmem_cache_create("xfs_bmap_free_item",
> - sizeof(struct xfs_extent_free_item),
> - 0, 0, NULL);
> - if (!xfs_bmap_free_item_cache)
> - goto out_destroy_log_ticket_cache;
> -
> error = xfs_btree_init_cur_caches();
> if (error)
> - goto out_destroy_bmap_free_item_cache;
> + goto out_destroy_log_ticket_cache;
>
> error = xfs_defer_init_item_caches();
> if (error)
> @@ -2115,8 +2109,6 @@ xfs_init_caches(void)
> xfs_defer_destroy_item_caches();
> out_destroy_btree_cur_cache:
> xfs_btree_destroy_cur_caches();
> - out_destroy_bmap_free_item_cache:
> - kmem_cache_destroy(xfs_bmap_free_item_cache);
> out_destroy_log_ticket_cache:
> kmem_cache_destroy(xfs_log_ticket_cache);
> out:
> @@ -2148,7 +2140,6 @@ xfs_destroy_caches(void)
> kmem_cache_destroy(xfs_da_state_cache);
> xfs_btree_destroy_cur_caches();
> xfs_defer_destroy_item_caches();
> - kmem_cache_destroy(xfs_bmap_free_item_cache);
> kmem_cache_destroy(xfs_log_ticket_cache);
> }
>
--
chandan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5] xfs: reduce the size of struct xfs_extent_free_item
2021-10-19 18:52 ` [PATCH 4/5] xfs: reduce the size of struct xfs_extent_free_item Darrick J. Wong
@ 2021-10-20 10:46 ` Chandan Babu R
0 siblings, 0 replies; 12+ messages in thread
From: Chandan Babu R @ 2021-10-20 10:46 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs
On 20 Oct 2021 at 00:22, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> We only use EFIs to free metadata blocks -- not regular data/attr fork
> extents. Remove all the fields that we never use, for a net reduction
> of 16 bytes.
>
Looks good to me.
Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
> fs/xfs/libxfs/xfs_alloc.c | 25 ++++++++++++++++---------
> fs/xfs/libxfs/xfs_alloc.h | 8 ++++++--
> fs/xfs/xfs_extfree_item.c | 13 ++++++++++---
> 3 files changed, 32 insertions(+), 14 deletions(-)
>
>
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index 9bc1a03a8167..353e53b892e6 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -2462,12 +2462,11 @@ xfs_defer_agfl_block(
> ASSERT(xfs_extfree_item_cache != NULL);
> ASSERT(oinfo != NULL);
>
> - new = kmem_cache_alloc(xfs_extfree_item_cache,
> + new = kmem_cache_zalloc(xfs_extfree_item_cache,
> GFP_KERNEL | __GFP_NOFAIL);
> new->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
> new->xefi_blockcount = 1;
> - new->xefi_oinfo = *oinfo;
> - new->xefi_skip_discard = false;
> + new->xefi_owner = oinfo->oi_owner;
>
> trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1);
>
> @@ -2505,15 +2504,23 @@ __xfs_free_extent_later(
> #endif
> ASSERT(xfs_extfree_item_cache != NULL);
>
> - new = kmem_cache_alloc(xfs_extfree_item_cache,
> + new = kmem_cache_zalloc(xfs_extfree_item_cache,
> GFP_KERNEL | __GFP_NOFAIL);
> new->xefi_startblock = bno;
> new->xefi_blockcount = (xfs_extlen_t)len;
> - if (oinfo)
> - new->xefi_oinfo = *oinfo;
> - else
> - new->xefi_oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
> - new->xefi_skip_discard = skip_discard;
> + if (skip_discard)
> + new->xefi_flags |= XFS_EFI_SKIP_DISCARD;
> + if (oinfo) {
> + ASSERT(oinfo->oi_offset == 0);
> +
> + if (oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK)
> + new->xefi_flags |= XFS_EFI_ATTR_FORK;
> + if (oinfo->oi_flags & XFS_OWNER_INFO_BMBT_BLOCK)
> + new->xefi_flags |= XFS_EFI_BMBT_BLOCK;
> + new->xefi_owner = oinfo->oi_owner;
> + } else {
> + new->xefi_owner = XFS_RMAP_OWN_NULL;
> + }
> trace_xfs_bmap_free_defer(tp->t_mountp,
> XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
> XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
> diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
> index b61aeb6fbe32..1c14a0b1abea 100644
> --- a/fs/xfs/libxfs/xfs_alloc.h
> +++ b/fs/xfs/libxfs/xfs_alloc.h
> @@ -258,12 +258,16 @@ void __xfs_free_extent_later(struct xfs_trans *tp, xfs_fsblock_t bno,
> */
> struct xfs_extent_free_item {
> struct list_head xefi_list;
> + uint64_t xefi_owner;
> xfs_fsblock_t xefi_startblock;/* starting fs block number */
> xfs_extlen_t xefi_blockcount;/* number of blocks in extent */
> - bool xefi_skip_discard;
> - struct xfs_owner_info xefi_oinfo; /* extent owner */
> + unsigned int xefi_flags;
> };
>
> +#define XFS_EFI_SKIP_DISCARD (1U << 0) /* don't issue discard */
> +#define XFS_EFI_ATTR_FORK (1U << 1) /* freeing attr fork block */
> +#define XFS_EFI_BMBT_BLOCK (1U << 2) /* freeing bmap btree block */
> +
> static inline void
> xfs_free_extent_later(
> struct xfs_trans *tp,
> diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
> index eb378e345f13..47ef9c9c5c17 100644
> --- a/fs/xfs/xfs_extfree_item.c
> +++ b/fs/xfs/xfs_extfree_item.c
> @@ -474,14 +474,20 @@ xfs_extent_free_finish_item(
> struct list_head *item,
> struct xfs_btree_cur **state)
> {
> + struct xfs_owner_info oinfo = { };
> struct xfs_extent_free_item *free;
> int error;
>
> free = container_of(item, struct xfs_extent_free_item, xefi_list);
> + oinfo.oi_owner = free->xefi_owner;
> + if (free->xefi_flags & XFS_EFI_ATTR_FORK)
> + oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
> + if (free->xefi_flags & XFS_EFI_BMBT_BLOCK)
> + oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
> error = xfs_trans_free_extent(tp, EFD_ITEM(done),
> free->xefi_startblock,
> free->xefi_blockcount,
> - &free->xefi_oinfo, free->xefi_skip_discard);
> + &oinfo, free->xefi_flags & XFS_EFI_SKIP_DISCARD);
> kmem_cache_free(xfs_extfree_item_cache, free);
> return error;
> }
> @@ -525,6 +531,7 @@ xfs_agfl_free_finish_item(
> struct list_head *item,
> struct xfs_btree_cur **state)
> {
> + struct xfs_owner_info oinfo = { };
> struct xfs_mount *mp = tp->t_mountp;
> struct xfs_efd_log_item *efdp = EFD_ITEM(done);
> struct xfs_extent_free_item *free;
> @@ -539,13 +546,13 @@ xfs_agfl_free_finish_item(
> ASSERT(free->xefi_blockcount == 1);
> agno = XFS_FSB_TO_AGNO(mp, free->xefi_startblock);
> agbno = XFS_FSB_TO_AGBNO(mp, free->xefi_startblock);
> + oinfo.oi_owner = free->xefi_owner;
>
> trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, free->xefi_blockcount);
>
> error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
> if (!error)
> - error = xfs_free_agfl_block(tp, agno, agbno, agbp,
> - &free->xefi_oinfo);
> + error = xfs_free_agfl_block(tp, agno, agbno, agbp, &oinfo);
>
> /*
> * Mark the transaction dirty, even on error. This ensures the
--
chandan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 5/5] xfs: remove unused parameter from refcount code
2021-10-19 18:52 ` [PATCH 5/5] xfs: remove unused parameter from refcount code Darrick J. Wong
@ 2021-10-20 10:46 ` Chandan Babu R
0 siblings, 0 replies; 12+ messages in thread
From: Chandan Babu R @ 2021-10-20 10:46 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs
On 20 Oct 2021 at 00:22, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> The owner info parameter is always NULL, so get rid of the parameter.
Looks good to me.
Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>
>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
> fs/xfs/libxfs/xfs_refcount.c | 19 ++++++++-----------
> 1 file changed, 8 insertions(+), 11 deletions(-)
>
>
> diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
> index bb9e256f4970..327ba25e9e17 100644
> --- a/fs/xfs/libxfs/xfs_refcount.c
> +++ b/fs/xfs/libxfs/xfs_refcount.c
> @@ -918,8 +918,7 @@ xfs_refcount_adjust_extents(
> struct xfs_btree_cur *cur,
> xfs_agblock_t *agbno,
> xfs_extlen_t *aglen,
> - enum xfs_refc_adjust_op adj,
> - struct xfs_owner_info *oinfo)
> + enum xfs_refc_adjust_op adj)
> {
> struct xfs_refcount_irec ext, tmp;
> int error;
> @@ -977,7 +976,7 @@ xfs_refcount_adjust_extents(
> cur->bc_ag.pag->pag_agno,
> tmp.rc_startblock);
> xfs_free_extent_later(cur->bc_tp, fsbno,
> - tmp.rc_blockcount, oinfo);
> + tmp.rc_blockcount, NULL);
> }
>
> (*agbno) += tmp.rc_blockcount;
> @@ -1021,8 +1020,8 @@ xfs_refcount_adjust_extents(
> fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
> cur->bc_ag.pag->pag_agno,
> ext.rc_startblock);
> - xfs_free_extent_later(cur->bc_tp, fsbno, ext.rc_blockcount,
> - oinfo);
> + xfs_free_extent_later(cur->bc_tp, fsbno,
> + ext.rc_blockcount, NULL);
> }
>
> skip:
> @@ -1050,8 +1049,7 @@ xfs_refcount_adjust(
> xfs_extlen_t aglen,
> xfs_agblock_t *new_agbno,
> xfs_extlen_t *new_aglen,
> - enum xfs_refc_adjust_op adj,
> - struct xfs_owner_info *oinfo)
> + enum xfs_refc_adjust_op adj)
> {
> bool shape_changed;
> int shape_changes = 0;
> @@ -1094,8 +1092,7 @@ xfs_refcount_adjust(
> cur->bc_ag.refc.shape_changes++;
>
> /* Now that we've taken care of the ends, adjust the middle extents */
> - error = xfs_refcount_adjust_extents(cur, new_agbno, new_aglen,
> - adj, oinfo);
> + error = xfs_refcount_adjust_extents(cur, new_agbno, new_aglen, adj);
> if (error)
> goto out_error;
>
> @@ -1190,12 +1187,12 @@ xfs_refcount_finish_one(
> switch (type) {
> case XFS_REFCOUNT_INCREASE:
> error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
> - new_len, XFS_REFCOUNT_ADJUST_INCREASE, NULL);
> + new_len, XFS_REFCOUNT_ADJUST_INCREASE);
> *new_fsb = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
> break;
> case XFS_REFCOUNT_DECREASE:
> error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
> - new_len, XFS_REFCOUNT_ADJUST_DECREASE, NULL);
> + new_len, XFS_REFCOUNT_ADJUST_DECREASE);
> *new_fsb = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
> break;
> case XFS_REFCOUNT_ALLOC_COW:
--
chandan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/5] xfs: create slab caches for frequently-used deferred items
2021-10-20 10:45 ` Chandan Babu R
@ 2021-10-21 1:56 ` Darrick J. Wong
0 siblings, 0 replies; 12+ messages in thread
From: Darrick J. Wong @ 2021-10-21 1:56 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs
On Wed, Oct 20, 2021 at 04:15:34PM +0530, Chandan Babu R wrote:
> On 20 Oct 2021 at 00:22, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > Create slab caches for the high-level structures that coordinate
> > deferred intent items, since they're used fairly heavily.
> >
>
> Apart from the nits pointed later in this mail, the remaining changes looks
> good to me.
>
> Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>
>
> > Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> > ---
> > fs/xfs/libxfs/xfs_bmap.c | 21 +++++++++++++-
> > fs/xfs/libxfs/xfs_bmap.h | 5 +++
> > fs/xfs/libxfs/xfs_defer.c | 62 +++++++++++++++++++++++++++++++++++++++---
> > fs/xfs/libxfs/xfs_defer.h | 3 ++
> > fs/xfs/libxfs/xfs_refcount.c | 23 ++++++++++++++--
> > fs/xfs/libxfs/xfs_refcount.h | 5 +++
> > fs/xfs/libxfs/xfs_rmap.c | 21 ++++++++++++++
> > fs/xfs/libxfs/xfs_rmap.h | 5 +++
> > fs/xfs/xfs_bmap_item.c | 4 +--
> > fs/xfs/xfs_refcount_item.c | 4 +--
> > fs/xfs/xfs_rmap_item.c | 4 +--
> > fs/xfs/xfs_super.c | 10 ++++++-
> > 12 files changed, 151 insertions(+), 16 deletions(-)
> >
> >
> > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> > index 8a993ef6b7f4..ef2ac0ecaed9 100644
> > --- a/fs/xfs/libxfs/xfs_bmap.c
> > +++ b/fs/xfs/libxfs/xfs_bmap.c
> > @@ -37,7 +37,7 @@
> > #include "xfs_icache.h"
> > #include "xfs_iomap.h"
> >
> > -
> > +struct kmem_cache *xfs_bmap_intent_cache;
> > struct kmem_cache *xfs_bmap_free_item_cache;
> >
> > /*
> > @@ -6190,7 +6190,7 @@ __xfs_bmap_add(
> > bmap->br_blockcount,
> > bmap->br_state);
> >
> > - bi = kmem_alloc(sizeof(struct xfs_bmap_intent), KM_NOFS);
> > + bi = kmem_cache_alloc(xfs_bmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
> > INIT_LIST_HEAD(&bi->bi_list);
> > bi->bi_type = type;
> > bi->bi_owner = ip;
> > @@ -6301,3 +6301,20 @@ xfs_bmap_validate_extent(
> > return __this_address;
> > return NULL;
> > }
> > +
> > +int __init
> > +xfs_bmap_intent_init_cache(void)
> > +{
> > + xfs_bmap_intent_cache = kmem_cache_create("xfs_bmap_intent",
> > + sizeof(struct xfs_bmap_intent),
> > + 0, 0, NULL);
> > +
> > + return xfs_bmap_intent_cache != NULL ? 0 : -ENOMEM;
> > +}
> > +
> > +void
> > +xfs_bmap_intent_destroy_cache(void)
> > +{
> > + kmem_cache_destroy(xfs_bmap_intent_cache);
> > + xfs_bmap_intent_cache = NULL;
> > +}
> > diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
> > index db01fe83bb8a..fa73a56827b1 100644
> > --- a/fs/xfs/libxfs/xfs_bmap.h
> > +++ b/fs/xfs/libxfs/xfs_bmap.h
> > @@ -290,4 +290,9 @@ int xfs_bmapi_remap(struct xfs_trans *tp, struct xfs_inode *ip,
> > xfs_fileoff_t bno, xfs_filblks_t len, xfs_fsblock_t startblock,
> > int flags);
> >
> > +extern struct kmem_cache *xfs_bmap_intent_cache;
> > +
> > +int __init xfs_bmap_intent_init_cache(void);
> > +void xfs_bmap_intent_destroy_cache(void);
> > +
> > #endif /* __XFS_BMAP_H__ */
> > diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
> > index 136a367d7b16..641a5dee4ffc 100644
> > --- a/fs/xfs/libxfs/xfs_defer.c
> > +++ b/fs/xfs/libxfs/xfs_defer.c
> > @@ -18,6 +18,11 @@
> > #include "xfs_trace.h"
> > #include "xfs_icache.h"
> > #include "xfs_log.h"
> > +#include "xfs_rmap.h"
> > +#include "xfs_refcount.h"
> > +#include "xfs_bmap.h"
> > +
> > +static struct kmem_cache *xfs_defer_pending_cache;
> >
> > /*
> > * Deferred Operations in XFS
> > @@ -365,7 +370,7 @@ xfs_defer_cancel_list(
> > ops->cancel_item(pwi);
> > }
> > ASSERT(dfp->dfp_count == 0);
> > - kmem_free(dfp);
> > + kmem_cache_free(xfs_defer_pending_cache, dfp);
> > }
> > }
> >
> > @@ -462,7 +467,7 @@ xfs_defer_finish_one(
> >
> > /* Done with the dfp, free it. */
> > list_del(&dfp->dfp_list);
> > - kmem_free(dfp);
> > + kmem_cache_free(xfs_defer_pending_cache, dfp);
> > out:
> > if (ops->finish_cleanup)
> > ops->finish_cleanup(tp, state, error);
> > @@ -596,8 +601,8 @@ xfs_defer_add(
> > dfp = NULL;
> > }
> > if (!dfp) {
> > - dfp = kmem_alloc(sizeof(struct xfs_defer_pending),
> > - KM_NOFS);
> > + dfp = kmem_cache_zalloc(xfs_defer_pending_cache,
> > + GFP_NOFS | __GFP_NOFAIL);
> > dfp->dfp_type = type;
> > dfp->dfp_intent = NULL;
> > dfp->dfp_done = NULL;
> > @@ -809,3 +814,52 @@ xfs_defer_resources_rele(
> > dres->dr_bufs = 0;
> > dres->dr_ordered = 0;
> > }
> > +
> > +static inline int __init
> > +xfs_defer_init_cache(void)
> > +{
> > + xfs_defer_pending_cache = kmem_cache_create("xfs_defer_pending",
> > + sizeof(struct xfs_defer_pending),
> > + 0, 0, NULL);
> > +
> > + return xfs_defer_pending_cache != NULL ? 0 : -ENOMEM;
> > +}
> > +
> > +static inline void
> > +xfs_defer_destroy_cache(void)
> > +{
> > + kmem_cache_destroy(xfs_defer_pending_cache);
> > + xfs_defer_pending_cache = NULL;
> > +}
> > +
> > +/* Set up caches for deferred work items. */
> > +int __init
> > +xfs_defer_init_item_caches(void)
> > +{
> > + int error;
> > +
> > + error = xfs_defer_init_cache();
> > + if (error)
> > + return error;
> > + error = xfs_rmap_intent_init_cache();
> > + if (error)
> > + return error;
> > + error = xfs_refcount_intent_init_cache();
> > + if (error)
> > + return error;
> > + error = xfs_bmap_intent_init_cache();
> > + if (error)
> > + return error;
> > +
>
> If the call to xfs_rmap_intent_init_cache() fails, then we don't free up
> xfs_defer_pending_cache. Same logic applies to the rest of initialization
> functions called above.
Ooh, good catch. I'll go fix that.
> > + return 0;
> > +}
> > +
> > +/* Destroy all the deferred work item caches, if they've been allocated. */
> > +void
> > +xfs_defer_destroy_item_caches(void)
> > +{
> > + xfs_bmap_intent_destroy_cache();
> > + xfs_refcount_intent_destroy_cache();
> > + xfs_rmap_intent_destroy_cache();
> > + xfs_defer_destroy_cache();
> > +}
> > diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h
> > index 7952695c7c41..7bb8a31ad65b 100644
> > --- a/fs/xfs/libxfs/xfs_defer.h
> > +++ b/fs/xfs/libxfs/xfs_defer.h
> > @@ -122,4 +122,7 @@ void xfs_defer_ops_capture_free(struct xfs_mount *mp,
> > struct xfs_defer_capture *d);
> > void xfs_defer_resources_rele(struct xfs_defer_resources *dres);
> >
> > +int __init xfs_defer_init_item_caches(void);
> > +void xfs_defer_destroy_item_caches(void);
> > +
> > #endif /* __XFS_DEFER_H__ */
> > diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
> > index e5d767a7fc5d..2c03df715d4f 100644
> > --- a/fs/xfs/libxfs/xfs_refcount.c
> > +++ b/fs/xfs/libxfs/xfs_refcount.c
> > @@ -24,6 +24,8 @@
> > #include "xfs_rmap.h"
> > #include "xfs_ag.h"
> >
> > +struct kmem_cache *xfs_refcount_intent_cache;
> > +
> > /* Allowable refcount adjustment amounts. */
> > enum xfs_refc_adjust_op {
> > XFS_REFCOUNT_ADJUST_INCREASE = 1,
> > @@ -1235,8 +1237,8 @@ __xfs_refcount_add(
> > type, XFS_FSB_TO_AGBNO(tp->t_mountp, startblock),
> > blockcount);
> >
> > - ri = kmem_alloc(sizeof(struct xfs_refcount_intent),
> > - KM_NOFS);
> > + ri = kmem_cache_alloc(xfs_refcount_intent_cache,
> > + GFP_NOFS | __GFP_NOFAIL);
> > INIT_LIST_HEAD(&ri->ri_list);
> > ri->ri_type = type;
> > ri->ri_startblock = startblock;
> > @@ -1782,3 +1784,20 @@ xfs_refcount_has_record(
> >
> > return xfs_btree_has_record(cur, &low, &high, exists);
> > }
> > +
> > +int __init
> > +xfs_refcount_intent_init_cache(void)
> > +{
> > + xfs_refcount_intent_cache = kmem_cache_create("xfs_refc_intent",
> > + sizeof(struct xfs_refcount_intent),
> > + 0, 0, NULL);
> > +
> > + return xfs_refcount_intent_cache != NULL ? 0 : -ENOMEM;
> > +}
> > +
> > +void
> > +xfs_refcount_intent_destroy_cache(void)
> > +{
> > + kmem_cache_destroy(xfs_refcount_intent_cache);
> > + xfs_refcount_intent_cache = NULL;
> > +}
> > diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h
> > index 894045968bc6..9eb01edbd89d 100644
> > --- a/fs/xfs/libxfs/xfs_refcount.h
> > +++ b/fs/xfs/libxfs/xfs_refcount.h
> > @@ -83,4 +83,9 @@ extern void xfs_refcount_btrec_to_irec(const union xfs_btree_rec *rec,
> > extern int xfs_refcount_insert(struct xfs_btree_cur *cur,
> > struct xfs_refcount_irec *irec, int *stat);
> >
> > +extern struct kmem_cache *xfs_refcount_intent_cache;
> > +
> > +int __init xfs_refcount_intent_init_cache(void);
> > +void xfs_refcount_intent_destroy_cache(void);
> > +
> > #endif /* __XFS_REFCOUNT_H__ */
> > diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c
> > index f45929b1b94a..cd322174dbff 100644
> > --- a/fs/xfs/libxfs/xfs_rmap.c
> > +++ b/fs/xfs/libxfs/xfs_rmap.c
> > @@ -24,6 +24,8 @@
> > #include "xfs_inode.h"
> > #include "xfs_ag.h"
> >
> > +struct kmem_cache *xfs_rmap_intent_cache;
> > +
> > /*
> > * Lookup the first record less than or equal to [bno, len, owner, offset]
> > * in the btree given by cur.
> > @@ -2485,7 +2487,7 @@ __xfs_rmap_add(
> > bmap->br_blockcount,
> > bmap->br_state);
> >
> > - ri = kmem_alloc(sizeof(struct xfs_rmap_intent), KM_NOFS);
> > + ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
> > INIT_LIST_HEAD(&ri->ri_list);
> > ri->ri_type = type;
> > ri->ri_owner = owner;
> > @@ -2779,3 +2781,20 @@ const struct xfs_owner_info XFS_RMAP_OINFO_REFC = {
> > const struct xfs_owner_info XFS_RMAP_OINFO_COW = {
> > .oi_owner = XFS_RMAP_OWN_COW,
> > };
> > +
> > +int __init
> > +xfs_rmap_intent_init_cache(void)
> > +{
> > + xfs_rmap_intent_cache = kmem_cache_create("xfs_rmap_intent",
> > + sizeof(struct xfs_rmap_intent),
> > + 0, 0, NULL);
> > +
> > + return xfs_rmap_intent_cache != NULL ? 0 : -ENOMEM;
> > +}
> > +
> > +void
> > +xfs_rmap_intent_destroy_cache(void)
> > +{
> > + kmem_cache_destroy(xfs_rmap_intent_cache);
> > + xfs_rmap_intent_cache = NULL;
> > +}
> > diff --git a/fs/xfs/libxfs/xfs_rmap.h b/fs/xfs/libxfs/xfs_rmap.h
> > index 85dd98ac3f12..b718ebeda372 100644
> > --- a/fs/xfs/libxfs/xfs_rmap.h
> > +++ b/fs/xfs/libxfs/xfs_rmap.h
> > @@ -215,4 +215,9 @@ extern const struct xfs_owner_info XFS_RMAP_OINFO_INODES;
> > extern const struct xfs_owner_info XFS_RMAP_OINFO_REFC;
> > extern const struct xfs_owner_info XFS_RMAP_OINFO_COW;
> >
> > +extern struct kmem_cache *xfs_rmap_intent_cache;
> > +
> > +int __init xfs_rmap_intent_init_cache(void);
> > +void xfs_rmap_intent_destroy_cache(void);
> > +
> > #endif /* __XFS_RMAP_H__ */
> > diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
> > index 6049f0722181..e1f4d7d5a011 100644
> > --- a/fs/xfs/xfs_bmap_item.c
> > +++ b/fs/xfs/xfs_bmap_item.c
> > @@ -384,7 +384,7 @@ xfs_bmap_update_finish_item(
> > bmap->bi_bmap.br_blockcount = count;
> > return -EAGAIN;
> > }
> > - kmem_free(bmap);
> > + kmem_cache_free(xfs_bmap_intent_cache, bmap);
> > return error;
> > }
> >
> > @@ -404,7 +404,7 @@ xfs_bmap_update_cancel_item(
> > struct xfs_bmap_intent *bmap;
> >
> > bmap = container_of(item, struct xfs_bmap_intent, bi_list);
> > - kmem_free(bmap);
> > + kmem_cache_free(xfs_bmap_intent_cache, bmap);
> > }
> >
> > const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
> > diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
> > index f23e86e06bfb..d3da67772d57 100644
> > --- a/fs/xfs/xfs_refcount_item.c
> > +++ b/fs/xfs/xfs_refcount_item.c
> > @@ -384,7 +384,7 @@ xfs_refcount_update_finish_item(
> > refc->ri_blockcount = new_aglen;
> > return -EAGAIN;
> > }
> > - kmem_free(refc);
> > + kmem_cache_free(xfs_refcount_intent_cache, refc);
> > return error;
> > }
> >
> > @@ -404,7 +404,7 @@ xfs_refcount_update_cancel_item(
> > struct xfs_refcount_intent *refc;
> >
> > refc = container_of(item, struct xfs_refcount_intent, ri_list);
> > - kmem_free(refc);
> > + kmem_cache_free(xfs_refcount_intent_cache, refc);
> > }
> >
> > const struct xfs_defer_op_type xfs_refcount_update_defer_type = {
> > diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
> > index b5cdeb10927e..c3966b4c58ef 100644
> > --- a/fs/xfs/xfs_rmap_item.c
> > +++ b/fs/xfs/xfs_rmap_item.c
> > @@ -427,7 +427,7 @@ xfs_rmap_update_finish_item(
> > rmap->ri_bmap.br_startoff, rmap->ri_bmap.br_startblock,
> > rmap->ri_bmap.br_blockcount, rmap->ri_bmap.br_state,
> > state);
> > - kmem_free(rmap);
> > + kmem_cache_free(xfs_rmap_intent_cache, rmap);
> > return error;
> > }
> >
> > @@ -447,7 +447,7 @@ xfs_rmap_update_cancel_item(
> > struct xfs_rmap_intent *rmap;
> >
> > rmap = container_of(item, struct xfs_rmap_intent, ri_list);
> > - kmem_free(rmap);
> > + kmem_cache_free(xfs_rmap_intent_cache, rmap);
> > }
> >
> > const struct xfs_defer_op_type xfs_rmap_update_defer_type = {
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index 0afa47378211..8909e08cbf77 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -38,6 +38,7 @@
> > #include "xfs_pwork.h"
> > #include "xfs_ag.h"
> > #include "xfs_btree.h"
> > +#include "xfs_defer.h"
> >
> > #include <linux/magic.h>
> > #include <linux/fs_context.h>
> > @@ -1972,11 +1973,15 @@ xfs_init_caches(void)
> > if (error)
> > goto out_destroy_bmap_free_item_cache;
> >
> > + error = xfs_defer_init_item_caches();
> > + if (error)
> > + goto out_destroy_btree_cur_cache;
> > +
> > xfs_da_state_cache = kmem_cache_create("xfs_da_state",
> > sizeof(struct xfs_da_state),
> > 0, 0, NULL);
> > if (!xfs_da_state_cache)
> > - goto out_destroy_btree_cur_cache;
> > + goto out_destroy_defer_item_cache;
> >
> > xfs_ifork_cache = kmem_cache_create("xfs_ifork",
> > sizeof(struct xfs_ifork),
> > @@ -2106,6 +2111,8 @@ xfs_init_caches(void)
> > kmem_cache_destroy(xfs_ifork_cache);
> > out_destroy_da_state_cache:
> > kmem_cache_destroy(xfs_da_state_cache);
> > + out_destroy_defer_item_cache:
> > + xfs_defer_destroy_item_caches();
> > out_destroy_btree_cur_cache:
> > xfs_btree_destroy_cur_caches();
> > out_destroy_bmap_free_item_cache:
> > @@ -2140,6 +2147,7 @@ xfs_destroy_caches(void)
> > kmem_cache_destroy(xfs_ifork_cache);
> > kmem_cache_destroy(xfs_da_state_cache);
> > xfs_btree_destroy_cur_caches();
> > + xfs_defer_destroy_item_caches();
>
> Since caches are being freed in the reverse order of their creation,
> xfs_defer_destroy_item_caches() should be invoked before
> xfs_btree_destroy_cur_caches().
Fixed. Thanks for the review!
--D
> > kmem_cache_destroy(xfs_bmap_free_item_cache);
> > kmem_cache_destroy(xfs_log_ticket_cache);
> > }
>
>
> --
> chandan
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2021-10-21 1:56 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-19 18:52 [PATCHSET 0/5] xfs: use slab caches for deferred log items Darrick J. Wong
2021-10-19 18:52 ` [PATCH 1/5] xfs: compact deferred intent item structures Darrick J. Wong
2021-10-20 10:44 ` Chandan Babu R
2021-10-19 18:52 ` [PATCH 2/5] xfs: create slab caches for frequently-used deferred items Darrick J. Wong
2021-10-20 10:45 ` Chandan Babu R
2021-10-21 1:56 ` Darrick J. Wong
2021-10-19 18:52 ` [PATCH 3/5] xfs: rename xfs_bmap_add_free to xfs_free_extent_later Darrick J. Wong
2021-10-20 10:45 ` Chandan Babu R
2021-10-19 18:52 ` [PATCH 4/5] xfs: reduce the size of struct xfs_extent_free_item Darrick J. Wong
2021-10-20 10:46 ` Chandan Babu R
2021-10-19 18:52 ` [PATCH 5/5] xfs: remove unused parameter from refcount code Darrick J. Wong
2021-10-20 10:46 ` Chandan Babu R
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.