Commit 2a483d33 authored by Holger Dengler's avatar Holger Dengler Committed by Alexander Gordeev
Browse files

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: default avatarHolger Dengler <dengler@linux.ibm.com>
Reviewed-by: default avatarHarald Freudenberger <freude@linux.ibm.com>
Acked-by: default avatarVineeth Vijayan <vneethv@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent 05272aa4
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -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_ */
+15 −0
Original line number Diff line number Diff line
@@ -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 */
+16 −2
Original line number Diff line number Diff line
@@ -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)
+19 −2
Original line number Diff line number Diff line
@@ -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);