xfs: introduce CPU hotplug infrastructure
authorDave Chinner <dchinner@redhat.com>
Fri, 6 Aug 2021 18:05:37 +0000 (11:05 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Fri, 6 Aug 2021 18:05:37 +0000 (11:05 -0700)
We need to move to per-cpu state for both deferred inode
inactivation and CIL tracking, but to do that we
need to handle CPUs being removed from the system by the hot-plug
code. Introduce generic XFS infrastructure to handle CPU hotplug
events that is set up at module init time and torn down at module
exit time.

Initially, we only need CPU dead notifications, so we only set
up a callback for these notifications. The infrastructure can be
updated in future for other CPU hotplug state machine notifications
easily if ever needed.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
[djwong: rearrange some macros, fix function prototypes]
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/xfs_super.c
include/linux/cpuhotplug.h

index 36fc81e52dc22aff892614410f606c1cb0f678a2..d47fac7c8afd749da2279b58846585d710527528 100644 (file)
@@ -2111,6 +2111,39 @@ xfs_destroy_workqueues(void)
        destroy_workqueue(xfs_alloc_wq);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int
+xfs_cpu_dead(
+       unsigned int            cpu)
+{
+       return 0;
+}
+
+static int __init
+xfs_cpu_hotplug_init(void)
+{
+       int     error;
+
+       error = cpuhp_setup_state_nocalls(CPUHP_XFS_DEAD, "xfs:dead", NULL,
+                       xfs_cpu_dead);
+       if (error < 0)
+               xfs_alert(NULL,
+"Failed to initialise CPU hotplug, error %d. XFS is non-functional.",
+                       error);
+       return error;
+}
+
+static void
+xfs_cpu_hotplug_destroy(void)
+{
+       cpuhp_remove_state_nocalls(CPUHP_XFS_DEAD);
+}
+
+#else /* !CONFIG_HOTPLUG_CPU */
+static inline int xfs_cpu_hotplug_init(void) { return 0; }
+static inline void xfs_cpu_hotplug_destroy(void) {}
+#endif
+
 STATIC int __init
 init_xfs_fs(void)
 {
@@ -2123,10 +2156,14 @@ init_xfs_fs(void)
 
        xfs_dir_startup();
 
-       error = xfs_init_zones();
+       error = xfs_cpu_hotplug_init();
        if (error)
                goto out;
 
+       error = xfs_init_zones();
+       if (error)
+               goto out_destroy_hp;
+
        error = xfs_init_workqueues();
        if (error)
                goto out_destroy_zones;
@@ -2206,6 +2243,8 @@ init_xfs_fs(void)
        xfs_destroy_workqueues();
  out_destroy_zones:
        xfs_destroy_zones();
+ out_destroy_hp:
+       xfs_cpu_hotplug_destroy();
  out:
        return error;
 }
@@ -2228,6 +2267,7 @@ exit_xfs_fs(void)
        xfs_destroy_workqueues();
        xfs_destroy_zones();
        xfs_uuid_table_free();
+       xfs_cpu_hotplug_destroy();
 }
 
 module_init(init_xfs_fs);
index f39b34b138710985305ff645f6e89c08c311dc6c..439adc05be4e18f89d8566106e96fccb6b327a55 100644 (file)
@@ -52,6 +52,7 @@ enum cpuhp_state {
        CPUHP_FS_BUFF_DEAD,
        CPUHP_PRINTK_DEAD,
        CPUHP_MM_MEMCQ_DEAD,
+       CPUHP_XFS_DEAD,
        CPUHP_PERCPU_CNT_DEAD,
        CPUHP_RADIX_DEAD,
        CPUHP_PAGE_ALLOC,