Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/chsc: use notifier for AP configuration changes

The direct dependency of chsc and the AP bus prevents the
modularization of ap bus. Introduce a notifier interface for AP
changes, which decouples the producer of the change events (chsc) from
the consumer (ap_bus).

Remove the ap_cfg_chg() interface and replace it with the notifier
invocation. The ap bus module registers a notification handler, which
triggers the AP bus scan.

Cc: Vineeth Vijayan <vneethv@linux.ibm.com>
Cc: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Acked-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>

authored by

Holger Dengler and committed by
Alexander Gordeev
2a483d33 05272aa4

+50 -15
-11
arch/s390/include/asm/ap.h
··· 549 549 return reg1.status; 550 550 } 551 551 552 - /* 553 - * Interface to tell the AP bus code that a configuration 554 - * change has happened. The bus code should at least do 555 - * an ap bus resource rescan. 556 - */ 557 - #if IS_ENABLED(CONFIG_ZCRYPT) 558 - void ap_bus_cfg_chg(void); 559 - #else 560 - static inline void ap_bus_cfg_chg(void){} 561 - #endif 562 - 563 552 #endif /* _ASM_S390_AP_H_ */
+15
arch/s390/include/asm/chsc.h
··· 11 11 12 12 #include <uapi/asm/chsc.h> 13 13 14 + /* struct from linux/notifier.h */ 15 + struct notifier_block; 16 + 14 17 /** 15 18 * Operation codes for CHSC PNSO: 16 19 * PNSO_OC_NET_BRIDGE_INFO - only addresses that are visible to a bridgeport ··· 68 65 struct chsc_pnso_naihdr naihdr; 69 66 struct chsc_pnso_naid_l2 entries[]; 70 67 } __packed __aligned(PAGE_SIZE); 68 + 69 + /* 70 + * notifier interface - registered notifiers gets called on 71 + * the following events: 72 + * - ap config changed (CHSC_NOTIFY_AP_CFG) 73 + */ 74 + enum chsc_notify_type { 75 + CHSC_NOTIFY_AP_CFG = 3, 76 + }; 77 + 78 + int chsc_notifier_register(struct notifier_block *nb); 79 + int chsc_notifier_unregister(struct notifier_block *nb); 71 80 72 81 #endif /* _ASM_S390_CHSC_H */
+16 -2
drivers/s390/cio/chsc.c
··· 24 24 #include <asm/crw.h> 25 25 #include <asm/isc.h> 26 26 #include <asm/ebcdic.h> 27 - #include <asm/ap.h> 28 27 29 28 #include "css.h" 30 29 #include "cio.h" ··· 38 39 39 40 #define SEI_VF_FLA 0xc0 /* VF flag for Full Link Address */ 40 41 #define SEI_RS_CHPID 0x4 /* 4 in RS field indicates CHPID */ 42 + 43 + static BLOCKING_NOTIFIER_HEAD(chsc_notifiers); 44 + 45 + int chsc_notifier_register(struct notifier_block *nb) 46 + { 47 + return blocking_notifier_chain_register(&chsc_notifiers, nb); 48 + } 49 + EXPORT_SYMBOL(chsc_notifier_register); 50 + 51 + int chsc_notifier_unregister(struct notifier_block *nb) 52 + { 53 + return blocking_notifier_chain_unregister(&chsc_notifiers, nb); 54 + } 55 + EXPORT_SYMBOL(chsc_notifier_unregister); 41 56 42 57 /** 43 58 * chsc_error_from_response() - convert a chsc response to an error ··· 594 581 if (sei_area->rs != 5) 595 582 return; 596 583 597 - ap_bus_cfg_chg(); 584 + blocking_notifier_call_chain(&chsc_notifiers, 585 + CHSC_NOTIFY_AP_CFG, NULL); 598 586 } 599 587 600 588 static void chsc_process_sei_fces_event(struct chsc_sei_nt0_area *sei_area)
+19 -2
drivers/s390/crypto/ap_bus.c
··· 39 39 #include <linux/ctype.h> 40 40 #include <linux/module.h> 41 41 #include <asm/uv.h> 42 + #include <asm/chsc.h> 42 43 43 44 #include "ap_bus.h" 44 45 #include "ap_debug.h" ··· 1025 1024 /* 1026 1025 * A config change has happened, force an ap bus rescan. 1027 1026 */ 1028 - void ap_bus_cfg_chg(void) 1027 + static int ap_bus_cfg_chg(struct notifier_block *nb, 1028 + unsigned long action, void *data) 1029 1029 { 1030 + if (action != CHSC_NOTIFY_AP_CFG) 1031 + return NOTIFY_DONE; 1032 + 1030 1033 pr_debug("%s config change, forcing bus rescan\n", __func__); 1031 1034 1032 1035 ap_bus_force_rescan(); 1036 + 1037 + return NOTIFY_OK; 1033 1038 } 1039 + 1040 + static struct notifier_block ap_bus_nb = { 1041 + .notifier_call = ap_bus_cfg_chg, 1042 + }; 1034 1043 1035 1044 /* 1036 1045 * hex2bitmap() - parse hex mask string and set bitmap. ··· 2302 2291 2303 2292 queue_work(system_long_wq, &ap_scan_bus_work); 2304 2293 2294 + rc = chsc_notifier_register(&ap_bus_nb); 2295 + if (rc) 2296 + goto out; 2297 + 2305 2298 /* Start the low priority AP bus poll thread. */ 2306 2299 if (!ap_thread_flag) 2307 2300 return 0; 2308 2301 2309 2302 rc = ap_poll_thread_start(); 2310 2303 if (rc) 2311 - goto out; 2304 + goto out_notifier; 2312 2305 2313 2306 return 0; 2314 2307 2308 + out_notifier: 2309 + chsc_notifier_unregister(&ap_bus_nb); 2315 2310 out: 2316 2311 cancel_work(&ap_scan_bus_work); 2317 2312 hrtimer_cancel(&ap_poll_timer);