From 0b60f9ead5d4816e7e3d6e28f4a0d22d4a1b2513 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 3 Feb 2014 14:03:04 -0500 Subject: s390: use device_remove_file_self() instead of device_schedule_callback() driver-core now supports synchrnous self-deletion of attributes and the asynchrnous removal mechanism is scheduled for removal. Use it instead of device_schedule_callback(). * Conversions in arch/s390/pci/pci_sysfs.c and drivers/s390/block/dcssblk.c are straightforward. * drivers/s390/cio/ccwgroup.c is a bit more tricky because ccwgroup_notifier() was (ab)using device_schedule_callback() to purely obtain a process context to kick off ungroup operation which may block from a notifier callback. Rename ccwgroup_ungroup_callback() to ccwgroup_ungroup() and make it take ccwgroup_device * instead. The new function is now called directly from ccwgroup_ungroup_store(). ccwgroup_notifier() chain is updated to explicitly bounce through ccwgroup_device->ungroup_work. This also removes possible failure from memory pressure. Only compile-tested. Signed-off-by: Tejun Heo Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: linux390@de.ibm.com Cc: linux-s390@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/s390/include/asm/ccwgroup.h | 1 + arch/s390/pci/pci_sysfs.c | 18 ++++++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h index 23723ce5ca7..6e670f88d12 100644 --- a/arch/s390/include/asm/ccwgroup.h +++ b/arch/s390/include/asm/ccwgroup.h @@ -23,6 +23,7 @@ struct ccwgroup_device { unsigned int count; struct device dev; struct ccw_device *cdev[0]; + struct work_struct ungroup_work; }; /** diff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c index cf8a12ff733..ab4a9139300 100644 --- a/arch/s390/pci/pci_sysfs.c +++ b/arch/s390/pci/pci_sysfs.c @@ -48,29 +48,27 @@ static ssize_t show_pfgid(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(pfgid, S_IRUGO, show_pfgid, NULL); -static void recover_callback(struct device *dev) +static ssize_t store_recover(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct pci_dev *pdev = to_pci_dev(dev); struct zpci_dev *zdev = get_zdev(pdev); int ret; + if (!device_remove_file_self(dev, attr)) + return count; + pci_stop_and_remove_bus_device(pdev); ret = zpci_disable_device(zdev); if (ret) - return; + return ret; ret = zpci_enable_device(zdev); if (ret) - return; + return ret; pci_rescan_bus(zdev->bus); -} - -static ssize_t store_recover(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int rc = device_schedule_callback(dev, recover_callback); - return rc ? rc : count; + return count; } static DEVICE_ATTR(recover, S_IWUSR, NULL, store_recover); -- cgit v1.2.3-70-g09d2 From 2b9c1f03278ab7cd421f14ce24dee39091ecb064 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 8 Feb 2014 13:34:10 +0100 Subject: x86: align x86 arch with generic CPU modalias handling The x86 CPU feature modalias handling existed before it was reimplemented generically. This patch aligns the x86 handling so that it (a) reuses some more code that is now generic; (b) uses the generic format for the modalias module metadata entry, i.e., it now uses 'cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:,XXXX,YYYY' instead of the 'x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:,XXXX,YYYY' that was used before. Signed-off-by: Ard Biesheuvel Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- arch/x86/Kconfig | 4 +--- arch/x86/include/asm/cpufeature.h | 7 +++++++ arch/x86/kernel/cpu/match.c | 42 --------------------------------------- drivers/base/Kconfig | 5 ----- drivers/base/cpu.c | 10 +++------- include/linux/cpu.h | 7 ------- scripts/mod/file2alias.c | 10 +++++----- 7 files changed, 16 insertions(+), 69 deletions(-) (limited to 'arch') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 0af5250d914..7fab7e0b1a7 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -127,6 +127,7 @@ config X86 select HAVE_DEBUG_STACKOVERFLOW select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 select HAVE_CC_STACKPROTECTOR + select GENERIC_CPU_AUTOPROBE config INSTRUCTION_DECODER def_bool y @@ -195,9 +196,6 @@ config ARCH_HAS_CPU_RELAX config ARCH_HAS_CACHE_LINE_SIZE def_bool y -config ARCH_HAS_CPU_AUTOPROBE - def_bool y - config HAVE_SETUP_PER_CPU_AREA def_bool y diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index e099f9502ac..d86dc3deea6 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -541,6 +541,13 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) #define static_cpu_has_bug(bit) static_cpu_has((bit)) #define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit)) +#define MAX_CPU_FEATURES (NCAPINTS * 32) +#define cpu_have_feature boot_cpu_has + +#define CPU_FEATURE_TYPEFMT "x86,ven%04Xfam%04Xmod%04X" +#define CPU_FEATURE_TYPEVAL boot_cpu_data.x86_vendor, boot_cpu_data.x86, \ + boot_cpu_data.x86_model + #endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */ #endif /* _ASM_X86_CPUFEATURE_H */ diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c index 36565373af8..afa9f0d487e 100644 --- a/arch/x86/kernel/cpu/match.c +++ b/arch/x86/kernel/cpu/match.c @@ -47,45 +47,3 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) return NULL; } EXPORT_SYMBOL(x86_match_cpu); - -ssize_t arch_print_cpu_modalias(struct device *dev, - struct device_attribute *attr, - char *bufptr) -{ - int size = PAGE_SIZE; - int i, n; - char *buf = bufptr; - - n = snprintf(buf, size, "x86cpu:vendor:%04X:family:%04X:" - "model:%04X:feature:", - boot_cpu_data.x86_vendor, - boot_cpu_data.x86, - boot_cpu_data.x86_model); - size -= n; - buf += n; - size -= 1; - for (i = 0; i < NCAPINTS*32; i++) { - if (boot_cpu_has(i)) { - n = snprintf(buf, size, ",%04X", i); - if (n >= size) { - WARN(1, "x86 features overflow page\n"); - break; - } - size -= n; - buf += n; - } - } - *buf++ = '\n'; - return buf - bufptr; -} - -int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (buf) { - arch_print_cpu_modalias(NULL, NULL, buf); - add_uevent_var(env, "MODALIAS=%s", buf); - kfree(buf); - } - return 0; -} diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 3f0d3732df7..8fa8deab644 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -185,13 +185,8 @@ config GENERIC_CPU_DEVICES bool default n -config HAVE_CPU_AUTOPROBE - def_bool ARCH_HAS_CPU_AUTOPROBE - config GENERIC_CPU_AUTOPROBE bool - depends on !ARCH_HAS_CPU_AUTOPROBE - select HAVE_CPU_AUTOPROBE config SOC_BUS bool diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 8a38bf8c792..006b1bc5297 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -287,7 +287,6 @@ static void cpu_device_release(struct device *dev) */ } -#ifdef CONFIG_HAVE_CPU_AUTOPROBE #ifdef CONFIG_GENERIC_CPU_AUTOPROBE static ssize_t print_cpu_modalias(struct device *dev, struct device_attribute *attr, @@ -310,9 +309,6 @@ static ssize_t print_cpu_modalias(struct device *dev, buf[n++] = '\n'; return n; } -#else -#define print_cpu_modalias arch_print_cpu_modalias -#endif static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env) { @@ -346,7 +342,7 @@ int register_cpu(struct cpu *cpu, int num) cpu->dev.offline_disabled = !cpu->hotpluggable; cpu->dev.offline = !cpu_online(num); cpu->dev.of_node = of_get_cpu_node(num, NULL); -#ifdef CONFIG_HAVE_CPU_AUTOPROBE +#ifdef CONFIG_GENERIC_CPU_AUTOPROBE cpu->dev.bus->uevent = cpu_uevent; #endif cpu->dev.groups = common_cpu_attr_groups; @@ -370,7 +366,7 @@ struct device *get_cpu_device(unsigned cpu) } EXPORT_SYMBOL_GPL(get_cpu_device); -#ifdef CONFIG_HAVE_CPU_AUTOPROBE +#ifdef CONFIG_GENERIC_CPU_AUTOPROBE static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL); #endif @@ -384,7 +380,7 @@ static struct attribute *cpu_root_attrs[] = { &cpu_attrs[2].attr.attr, &dev_attr_kernel_max.attr, &dev_attr_offline.attr, -#ifdef CONFIG_HAVE_CPU_AUTOPROBE +#ifdef CONFIG_GENERIC_CPU_AUTOPROBE &dev_attr_modalias.attr, #endif NULL diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 03e235ad1bb..03e962e23ea 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -46,13 +46,6 @@ extern ssize_t arch_cpu_release(const char *, size_t); #endif struct notifier_block; -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE -extern int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env); -extern ssize_t arch_print_cpu_modalias(struct device *dev, - struct device_attribute *attr, - char *bufptr); -#endif - /* * CPU notifier priorities. */ diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 506146e5f4a..25f6f597055 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1110,7 +1110,7 @@ static int do_amba_entry(const char *filename, } ADD_TO_DEVTABLE("amba", amba_id, do_amba_entry); -/* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,* +/* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,* * All fields are numbers. It would be nicer to use strings for vendor * and feature, but getting those out of the build system here is too * complicated. @@ -1124,10 +1124,10 @@ static int do_x86cpu_entry(const char *filename, void *symval, DEF_FIELD(symval, x86_cpu_id, model); DEF_FIELD(symval, x86_cpu_id, vendor); - strcpy(alias, "x86cpu:"); - ADD(alias, "vendor:", vendor != X86_VENDOR_ANY, vendor); - ADD(alias, ":family:", family != X86_FAMILY_ANY, family); - ADD(alias, ":model:", model != X86_MODEL_ANY, model); + strcpy(alias, "cpu:type:x86,"); + ADD(alias, "ven", vendor != X86_VENDOR_ANY, vendor); + ADD(alias, "fam", family != X86_FAMILY_ANY, family); + ADD(alias, "mod", model != X86_MODEL_ANY, model); strcat(alias, ":feature:*"); if (feature != X86_FEATURE_ANY) sprintf(alias + strlen(alias), "%04X*", feature); -- cgit v1.2.3-70-g09d2