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>
This commit is contained in:
Holger Dengler 2024-02-19 17:32:54 +01:00 committed by Alexander Gordeev
parent 05272aa499
commit 2a483d333f
4 changed files with 50 additions and 15 deletions

View File

@ -549,15 +549,4 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
return reg1.status;
}
/*
* Interface to tell the AP bus code that a configuration
* change has happened. The bus code should at least do
* an ap bus resource rescan.
*/
#if IS_ENABLED(CONFIG_ZCRYPT)
void ap_bus_cfg_chg(void);
#else
static inline void ap_bus_cfg_chg(void){}
#endif
#endif /* _ASM_S390_AP_H_ */

View File

@ -11,6 +11,9 @@
#include <uapi/asm/chsc.h>
/* struct from linux/notifier.h */
struct notifier_block;
/**
* Operation codes for CHSC PNSO:
* PNSO_OC_NET_BRIDGE_INFO - only addresses that are visible to a bridgeport
@ -66,4 +69,16 @@ struct chsc_pnso_area {
struct chsc_pnso_naid_l2 entries[];
} __packed __aligned(PAGE_SIZE);
/*
* notifier interface - registered notifiers gets called on
* the following events:
* - ap config changed (CHSC_NOTIFY_AP_CFG)
*/
enum chsc_notify_type {
CHSC_NOTIFY_AP_CFG = 3,
};
int chsc_notifier_register(struct notifier_block *nb);
int chsc_notifier_unregister(struct notifier_block *nb);
#endif /* _ASM_S390_CHSC_H */

View File

@ -24,7 +24,6 @@
#include <asm/crw.h>
#include <asm/isc.h>
#include <asm/ebcdic.h>
#include <asm/ap.h>
#include "css.h"
#include "cio.h"
@ -40,6 +39,20 @@ static DEFINE_SPINLOCK(chsc_page_lock);
#define SEI_VF_FLA 0xc0 /* VF flag for Full Link Address */
#define SEI_RS_CHPID 0x4 /* 4 in RS field indicates CHPID */
static BLOCKING_NOTIFIER_HEAD(chsc_notifiers);
int chsc_notifier_register(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&chsc_notifiers, nb);
}
EXPORT_SYMBOL(chsc_notifier_register);
int chsc_notifier_unregister(struct notifier_block *nb)
{
return blocking_notifier_chain_unregister(&chsc_notifiers, nb);
}
EXPORT_SYMBOL(chsc_notifier_unregister);
/**
* chsc_error_from_response() - convert a chsc response to an error
* @response: chsc response code
@ -581,7 +594,8 @@ static void chsc_process_sei_ap_cfg_chg(struct chsc_sei_nt0_area *sei_area)
if (sei_area->rs != 5)
return;
ap_bus_cfg_chg();
blocking_notifier_call_chain(&chsc_notifiers,
CHSC_NOTIFY_AP_CFG, NULL);
}
static void chsc_process_sei_fces_event(struct chsc_sei_nt0_area *sei_area)

View File

@ -39,6 +39,7 @@
#include <linux/ctype.h>
#include <linux/module.h>
#include <asm/uv.h>
#include <asm/chsc.h>
#include "ap_bus.h"
#include "ap_debug.h"
@ -1024,13 +1025,23 @@ EXPORT_SYMBOL(ap_bus_force_rescan);
/*
* A config change has happened, force an ap bus rescan.
*/
void ap_bus_cfg_chg(void)
static int ap_bus_cfg_chg(struct notifier_block *nb,
unsigned long action, void *data)
{
if (action != CHSC_NOTIFY_AP_CFG)
return NOTIFY_DONE;
pr_debug("%s config change, forcing bus rescan\n", __func__);
ap_bus_force_rescan();
return NOTIFY_OK;
}
static struct notifier_block ap_bus_nb = {
.notifier_call = ap_bus_cfg_chg,
};
/*
* hex2bitmap() - parse hex mask string and set bitmap.
* Valid strings are "0x012345678" with at least one valid hex number.
@ -2291,16 +2302,22 @@ static inline int __init ap_async_init(void)
queue_work(system_long_wq, &ap_scan_bus_work);
rc = chsc_notifier_register(&ap_bus_nb);
if (rc)
goto out;
/* Start the low priority AP bus poll thread. */
if (!ap_thread_flag)
return 0;
rc = ap_poll_thread_start();
if (rc)
goto out;
goto out_notifier;
return 0;
out_notifier:
chsc_notifier_unregister(&ap_bus_nb);
out:
cancel_work(&ap_scan_bus_work);
hrtimer_cancel(&ap_poll_timer);