lkml.org 
[lkml]   [2016]   [Nov]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip:smp/hotplug] x86/cpuid: Convert to hotplug state machine
    Commit-ID:  20ce2eb8e46cee14a3f608b201fbb117055a3d6f
    Gitweb: http://git.kernel.org/tip/20ce2eb8e46cee14a3f608b201fbb117055a3d6f
    Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    AuthorDate: Thu, 17 Nov 2016 19:35:23 +0100
    Committer: Thomas Gleixner <tglx@linutronix.de>
    CommitDate: Mon, 21 Nov 2016 16:37:05 +0100

    x86/cpuid: Convert to hotplug state machine

    Install the callbacks via the state machine and let the core invoke
    the callbacks on the already online CPUs.

    Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    Cc: rt@linuxtronix.de
    Link: http://lkml.kernel.org/r/20161117183541.8588-3-bigeasy@linutronix.de
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

    ---
    arch/x86/kernel/cpuid.c | 64 ++++++++--------------------------------------
    include/linux/cpuhotplug.h | 1 +
    2 files changed, 12 insertions(+), 53 deletions(-)

    diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
    index 2836de3..fd85e93 100644
    --- a/arch/x86/kernel/cpuid.c
    +++ b/arch/x86/kernel/cpuid.c
    @@ -115,7 +115,7 @@ static const struct file_operations cpuid_fops = {
    .open = cpuid_open,
    };

    -static int cpuid_device_create(int cpu)
    +static int cpuid_device_create(unsigned int cpu)
    {
    struct device *dev;

    @@ -124,35 +124,12 @@ static int cpuid_device_create(int cpu)
    return PTR_ERR_OR_ZERO(dev);
    }

    -static void cpuid_device_destroy(int cpu)
    +static int cpuid_device_destroy(unsigned int cpu)
    {
    device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
    + return 0;
    }

    -static int cpuid_class_cpu_callback(struct notifier_block *nfb,
    - unsigned long action, void *hcpu)
    -{
    - unsigned int cpu = (unsigned long)hcpu;
    - int err = 0;
    -
    - switch (action) {
    - case CPU_UP_PREPARE:
    - err = cpuid_device_create(cpu);
    - break;
    - case CPU_UP_CANCELED:
    - case CPU_UP_CANCELED_FROZEN:
    - case CPU_DEAD:
    - cpuid_device_destroy(cpu);
    - break;
    - }
    - return notifier_from_errno(err);
    -}
    -
    -static struct notifier_block cpuid_class_cpu_notifier =
    -{
    - .notifier_call = cpuid_class_cpu_callback,
    -};
    -
    static char *cpuid_devnode(struct device *dev, umode_t *mode)
    {
    return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt));
    @@ -160,15 +137,13 @@ static char *cpuid_devnode(struct device *dev, umode_t *mode)

    static int __init cpuid_init(void)
    {
    - int i, err = 0;
    - i = 0;
    + int err;

    if (__register_chrdev(CPUID_MAJOR, 0, NR_CPUS,
    "cpu/cpuid", &cpuid_fops)) {
    printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
    CPUID_MAJOR);
    - err = -EBUSY;
    - goto out;
    + return -EBUSY;
    }
    cpuid_class = class_create(THIS_MODULE, "cpuid");
    if (IS_ERR(cpuid_class)) {
    @@ -177,42 +152,25 @@ static int __init cpuid_init(void)
    }
    cpuid_class->devnode = cpuid_devnode;

    - cpu_notifier_register_begin();
    - for_each_online_cpu(i) {
    - err = cpuid_device_create(i);
    - if (err != 0)
    - goto out_class;
    - }
    - __register_hotcpu_notifier(&cpuid_class_cpu_notifier);
    - cpu_notifier_register_done();
    + err = cpuhp_setup_state(CPUHP_X86_CPUID_PREPARE, "x86/cpuid:prepare",
    + cpuid_device_create, cpuid_device_destroy);
    + if (err)
    + goto out_class;

    - err = 0;
    - goto out;
    + return 0;

    out_class:
    - i = 0;
    - for_each_online_cpu(i) {
    - cpuid_device_destroy(i);
    - }
    - cpu_notifier_register_done();
    class_destroy(cpuid_class);
    out_chrdev:
    __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
    -out:
    return err;
    }

    static void __exit cpuid_exit(void)
    {
    - int cpu = 0;
    -
    - cpu_notifier_register_begin();
    - for_each_online_cpu(cpu)
    - cpuid_device_destroy(cpu);
    + cpuhp_remove_state(CPUHP_X86_CPUID_PREPARE);
    class_destroy(cpuid_class);
    __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
    - __unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
    - cpu_notifier_register_done();
    }

    module_init(cpuid_init);
    diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
    index 79b96f6..bc340ef 100644
    --- a/include/linux/cpuhotplug.h
    +++ b/include/linux/cpuhotplug.h
    @@ -59,6 +59,7 @@ enum cpuhp_state {
    CPUHP_BLK_MQ_PREPARE,
    CPUHP_NET_FLOW_PREPARE,
    CPUHP_TOPOLOGY_PREPARE,
    + CPUHP_X86_CPUID_PREPARE,
    CPUHP_TIMERS_DEAD,
    CPUHP_NOTF_ERR_INJ_PREPARE,
    CPUHP_MIPS_SOC_PREPARE,
    \
     
     \ /
      Last update: 2016-11-21 16:47    [W:4.268 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site