]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: move draining of deferred operations to the generic group structure
authorChristoph Hellwig <hch@lst.de>
Thu, 19 Sep 2024 07:07:48 +0000 (09:07 +0200)
committerChristoph Hellwig <hch@lst.de>
Sun, 22 Sep 2024 05:37:31 +0000 (07:37 +0200)
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>
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_ag.h
fs/xfs/libxfs/xfs_group.c
fs/xfs/libxfs/xfs_group.h
fs/xfs/scrub/common.c
fs/xfs/xfs_drain.c
fs/xfs/xfs_drain.h
fs/xfs/xfs_trace.h

index a4f5aacf575a8ee7224fd5758bf0e93c5c501d97..72589f485d9c86b86e962b6a06f8438aa3a1c057 100644 (file)
@@ -111,7 +111,6 @@ xfs_perag_uninit(
 {
        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);
 }
@@ -211,7 +210,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);
@@ -219,7 +217,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
@@ -237,8 +235,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;
 }
index d95af53e10d7e9ed5118e0facf4d3b5e1986b7fe..8ec00c6d9bd9e2fb00e590fe47d087dd51f2a127 100644 (file)
@@ -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__ */
index a68477639fd025f255bc9ed9ac3e82c64d5a6773..6d6d64288e49cfcf9565bb863d942c0ee8208371 100644 (file)
@@ -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;
        }
 
index 93b247dd12c4308b4031a74d26588aedeae389f9..3184214310a609c4c6a895dfd39f56d28e829ace 100644 (file)
@@ -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__ */
 };
 
index 28095ed490fbf600773b22de180f58a0026dae7f..b71768c2a8c129f953a7f41b96d13e410031944d 100644 (file)
@@ -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(&sa->pag->pag_group))
                        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(&sa->pag->pag_group);
                if (error == -ERESTARTSYS)
                        error = -EINTR;
        } while (!error);
index 3f280971b498b8d1199e5668d38c4ef40d214ca5..3d234016c53547236217afb44c33b76b5f38d52e 100644 (file)
@@ -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->pag_group);
        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->pag_group);
        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);
 }
index f39c90946ab71ff46368dc3508e7ad621b8d7cde..3e6143572e52d2fa5f66b62d5c25f23857b91735 100644 (file)
@@ -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 */ };
 
index ac2ec21d3486fef985a67ed0b93edf65260c1120..40f535538dc0ec5e321f4841985a212a01ed6abc 100644 (file)
@@ -4689,35 +4689,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_index;
+               __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 */