mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-01 10:42:11 +00:00
xfs: move draining of deferred operations to the generic group structure
Prepare supporting the upcoming realtime groups feature by moving the deferred operation draining to the generic xfs_group structure. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
parent
2ed27a5464
commit
34cf3a6f39
@ -112,7 +112,6 @@ xfs_perag_uninit(
|
||||
#ifdef __KERNEL__
|
||||
struct xfs_perag *pag = to_perag(xg);
|
||||
|
||||
xfs_defer_drain_free(&pag->pag_intents_drain);
|
||||
cancel_delayed_work_sync(&pag->pag_blockgc_work);
|
||||
xfs_buf_cache_destroy(&pag->pag_bcache);
|
||||
#endif
|
||||
@ -234,7 +233,6 @@ xfs_perag_alloc(
|
||||
spin_lock_init(&pag->pagb_lock);
|
||||
INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
|
||||
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
|
||||
xfs_defer_drain_init(&pag->pag_intents_drain);
|
||||
init_waitqueue_head(&pag->pagb_wait);
|
||||
pag->pagb_tree = RB_ROOT;
|
||||
xfs_hooks_init(&pag->pag_rmap_update_hooks);
|
||||
@ -242,7 +240,7 @@ xfs_perag_alloc(
|
||||
|
||||
error = xfs_buf_cache_init(&pag->pag_bcache);
|
||||
if (error)
|
||||
goto out_defer_drain_free;
|
||||
goto out_free_perag;
|
||||
|
||||
/*
|
||||
* Pre-calculated geometry
|
||||
@ -260,8 +258,7 @@ xfs_perag_alloc(
|
||||
|
||||
out_buf_cache_destroy:
|
||||
xfs_buf_cache_destroy(&pag->pag_bcache);
|
||||
out_defer_drain_free:
|
||||
xfs_defer_drain_free(&pag->pag_intents_drain);
|
||||
out_free_perag:
|
||||
kfree(pag);
|
||||
return error;
|
||||
}
|
||||
|
@ -97,15 +97,6 @@ struct xfs_perag {
|
||||
/* background prealloc block trimming */
|
||||
struct delayed_work pag_blockgc_work;
|
||||
|
||||
/*
|
||||
* We use xfs_drain to track the number of deferred log intent items
|
||||
* that have been queued (but not yet processed) so that waiters (e.g.
|
||||
* scrub) will not lock resources when other threads are in the middle
|
||||
* of processing a chain of intent items only to find momentary
|
||||
* inconsistencies.
|
||||
*/
|
||||
struct xfs_defer_drain pag_intents_drain;
|
||||
|
||||
/* Hook to feed rmapbt updates to an active online repair. */
|
||||
struct xfs_hooks pag_rmap_update_hooks;
|
||||
#endif /* __KERNEL__ */
|
||||
|
@ -160,6 +160,8 @@ xfs_group_free(
|
||||
|
||||
XFS_IS_CORRUPT(mp, atomic_read(&xg->xg_ref) != 0);
|
||||
|
||||
xfs_defer_drain_free(&xg->xg_intents_drain);
|
||||
|
||||
if (uninit)
|
||||
uninit(xg);
|
||||
|
||||
@ -185,6 +187,7 @@ xfs_group_insert(
|
||||
#ifdef __KERNEL__
|
||||
spin_lock_init(&xg->xg_state_lock);
|
||||
#endif
|
||||
xfs_defer_drain_init(&xg->xg_intents_drain);
|
||||
|
||||
/* Active ref owned by mount indicates group is online. */
|
||||
atomic_set(&xg->xg_active_ref, 1);
|
||||
@ -192,6 +195,7 @@ xfs_group_insert(
|
||||
error = xa_insert(&mp->m_groups[type].xa, index, xg, GFP_KERNEL);
|
||||
if (error) {
|
||||
WARN_ON_ONCE(error == -EBUSY);
|
||||
xfs_defer_drain_free(&xg->xg_intents_drain);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,15 @@ struct xfs_group {
|
||||
uint16_t xg_checked;
|
||||
uint16_t xg_sick;
|
||||
spinlock_t xg_state_lock;
|
||||
|
||||
/*
|
||||
* We use xfs_drain to track the number of deferred log intent items
|
||||
* that have been queued (but not yet processed) so that waiters (e.g.
|
||||
* scrub) will not lock resources when other threads are in the middle
|
||||
* of processing a chain of intent items only to find momentary
|
||||
* inconsistencies.
|
||||
*/
|
||||
struct xfs_defer_drain xg_intents_drain;
|
||||
#endif /* __KERNEL__ */
|
||||
};
|
||||
|
||||
|
@ -513,7 +513,7 @@ xchk_perag_drain_and_lock(
|
||||
* Obviously, this should be slanted against scrub and in favor
|
||||
* of runtime threads.
|
||||
*/
|
||||
if (!xfs_perag_intent_busy(sa->pag))
|
||||
if (!xfs_group_intent_busy(pag_group(sa->pag)))
|
||||
return 0;
|
||||
|
||||
if (sa->agf_bp) {
|
||||
@ -528,7 +528,7 @@ xchk_perag_drain_and_lock(
|
||||
|
||||
if (!(sc->flags & XCHK_FSGATES_DRAIN))
|
||||
return -ECHRNG;
|
||||
error = xfs_perag_intent_drain(sa->pag);
|
||||
error = xfs_group_intent_drain(pag_group(sa->pag));
|
||||
if (error == -ERESTARTSYS)
|
||||
error = -EINTR;
|
||||
} while (!error);
|
||||
|
@ -94,24 +94,26 @@ static inline int xfs_defer_drain_wait(struct xfs_defer_drain *dr)
|
||||
}
|
||||
|
||||
/*
|
||||
* Declare an intent to update AG metadata. Other threads that need exclusive
|
||||
* access can decide to back off if they see declared intentions.
|
||||
* Declare an intent to update group metadata. Other threads that need
|
||||
* exclusive access can decide to back off if they see declared intentions.
|
||||
*/
|
||||
static void
|
||||
xfs_perag_intent_hold(
|
||||
struct xfs_perag *pag)
|
||||
xfs_group_intent_hold(
|
||||
struct xfs_group *xg)
|
||||
{
|
||||
trace_xfs_perag_intent_hold(pag, __return_address);
|
||||
xfs_defer_drain_grab(&pag->pag_intents_drain);
|
||||
trace_xfs_group_intent_hold(xg, __return_address);
|
||||
xfs_defer_drain_grab(&xg->xg_intents_drain);
|
||||
}
|
||||
|
||||
/* Release our intent to update this AG's metadata. */
|
||||
/*
|
||||
* Release our intent to update this groups metadata.
|
||||
*/
|
||||
static void
|
||||
xfs_perag_intent_rele(
|
||||
struct xfs_perag *pag)
|
||||
xfs_group_intent_rele(
|
||||
struct xfs_group *xg)
|
||||
{
|
||||
trace_xfs_perag_intent_rele(pag, __return_address);
|
||||
xfs_defer_drain_rele(&pag->pag_intents_drain);
|
||||
trace_xfs_group_intent_rele(xg, __return_address);
|
||||
xfs_defer_drain_rele(&xg->xg_intents_drain);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -129,7 +131,7 @@ xfs_perag_intent_get(
|
||||
if (!pag)
|
||||
return NULL;
|
||||
|
||||
xfs_perag_intent_hold(pag);
|
||||
xfs_group_intent_hold(pag_group(pag));
|
||||
return pag;
|
||||
}
|
||||
|
||||
@ -141,7 +143,7 @@ void
|
||||
xfs_perag_intent_put(
|
||||
struct xfs_perag *pag)
|
||||
{
|
||||
xfs_perag_intent_rele(pag);
|
||||
xfs_group_intent_rele(pag_group(pag));
|
||||
xfs_perag_put(pag);
|
||||
}
|
||||
|
||||
@ -150,17 +152,19 @@ xfs_perag_intent_put(
|
||||
* Callers must not hold any AG header buffers.
|
||||
*/
|
||||
int
|
||||
xfs_perag_intent_drain(
|
||||
struct xfs_perag *pag)
|
||||
xfs_group_intent_drain(
|
||||
struct xfs_group *xg)
|
||||
{
|
||||
trace_xfs_perag_wait_intents(pag, __return_address);
|
||||
return xfs_defer_drain_wait(&pag->pag_intents_drain);
|
||||
trace_xfs_group_wait_intents(xg, __return_address);
|
||||
return xfs_defer_drain_wait(&xg->xg_intents_drain);
|
||||
}
|
||||
|
||||
/* Has anyone declared an intent to update this AG? */
|
||||
/*
|
||||
* Has anyone declared an intent to update this group?
|
||||
*/
|
||||
bool
|
||||
xfs_perag_intent_busy(
|
||||
struct xfs_perag *pag)
|
||||
xfs_group_intent_busy(
|
||||
struct xfs_group *xg)
|
||||
{
|
||||
return xfs_defer_drain_busy(&pag->pag_intents_drain);
|
||||
return xfs_defer_drain_busy(&xg->xg_intents_drain);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#ifndef XFS_DRAIN_H_
|
||||
#define XFS_DRAIN_H_
|
||||
|
||||
struct xfs_group;
|
||||
struct xfs_perag;
|
||||
|
||||
#ifdef CONFIG_XFS_DRAIN_INTENTS
|
||||
@ -65,8 +66,9 @@ struct xfs_perag *xfs_perag_intent_get(struct xfs_mount *mp,
|
||||
xfs_fsblock_t fsbno);
|
||||
void xfs_perag_intent_put(struct xfs_perag *pag);
|
||||
|
||||
int xfs_perag_intent_drain(struct xfs_perag *pag);
|
||||
bool xfs_perag_intent_busy(struct xfs_perag *pag);
|
||||
int xfs_group_intent_drain(struct xfs_group *xg);
|
||||
bool xfs_group_intent_busy(struct xfs_group *xg);
|
||||
|
||||
#else
|
||||
struct xfs_defer_drain { /* empty */ };
|
||||
|
||||
|
@ -4684,35 +4684,39 @@ TRACE_EVENT(xfs_force_shutdown,
|
||||
);
|
||||
|
||||
#ifdef CONFIG_XFS_DRAIN_INTENTS
|
||||
DECLARE_EVENT_CLASS(xfs_perag_intents_class,
|
||||
TP_PROTO(const struct xfs_perag *pag, void *caller_ip),
|
||||
TP_ARGS(pag, caller_ip),
|
||||
DECLARE_EVENT_CLASS(xfs_group_intents_class,
|
||||
TP_PROTO(const struct xfs_group *xg, void *caller_ip),
|
||||
TP_ARGS(xg, caller_ip),
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(xfs_agnumber_t, agno)
|
||||
__field(enum xfs_group_type, type)
|
||||
__field(uint32_t, index)
|
||||
__field(long, nr_intents)
|
||||
__field(void *, caller_ip)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->dev = pag_mount(pag)->m_super->s_dev;
|
||||
__entry->agno = pag_agno(pag);
|
||||
__entry->nr_intents = atomic_read(&pag->pag_intents_drain.dr_count);
|
||||
__entry->dev = xg->xg_mount->m_super->s_dev;
|
||||
__entry->type = xg->xg_type;
|
||||
__entry->index = xg->xg_gno;
|
||||
__entry->nr_intents =
|
||||
atomic_read(&xg->xg_intents_drain.dr_count);
|
||||
__entry->caller_ip = caller_ip;
|
||||
),
|
||||
TP_printk("dev %d:%d agno 0x%x intents %ld caller %pS",
|
||||
TP_printk("dev %d:%d %sno 0x%x intents %ld caller %pS",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
__entry->agno,
|
||||
__print_symbolic(__entry->type, XG_TYPE_STRINGS),
|
||||
__entry->index,
|
||||
__entry->nr_intents,
|
||||
__entry->caller_ip)
|
||||
);
|
||||
|
||||
#define DEFINE_PERAG_INTENTS_EVENT(name) \
|
||||
DEFINE_EVENT(xfs_perag_intents_class, name, \
|
||||
TP_PROTO(const struct xfs_perag *pag, void *caller_ip), \
|
||||
TP_ARGS(pag, caller_ip))
|
||||
DEFINE_PERAG_INTENTS_EVENT(xfs_perag_intent_hold);
|
||||
DEFINE_PERAG_INTENTS_EVENT(xfs_perag_intent_rele);
|
||||
DEFINE_PERAG_INTENTS_EVENT(xfs_perag_wait_intents);
|
||||
#define DEFINE_GROUP_INTENTS_EVENT(name) \
|
||||
DEFINE_EVENT(xfs_group_intents_class, name, \
|
||||
TP_PROTO(const struct xfs_group *xg, void *caller_ip), \
|
||||
TP_ARGS(xg, caller_ip))
|
||||
DEFINE_GROUP_INTENTS_EVENT(xfs_group_intent_hold);
|
||||
DEFINE_GROUP_INTENTS_EVENT(xfs_group_intent_rele);
|
||||
DEFINE_GROUP_INTENTS_EVENT(xfs_group_wait_intents);
|
||||
|
||||
#endif /* CONFIG_XFS_DRAIN_INTENTS */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user