Skip to content

Commit 778412a

Browse files
hfreudehcahca
authored andcommitted
s390/ap: rearm APQNs bindings complete completion
The APQN bindings complete completion was used to reflect that 1st the AP bus initial scan is done and 2nd all the detected APQNs have been bound to a device driver. This was a single-shot action. However, as the AP bus supports hot-plug it may be that new APQNs appear reflected as new AP queue and card devices which need to be bound to appropriate device drivers. So the condition that all existing AP queue devices are bound to device drivers may go away for a certain time. This patch now checks during AP bus scan for maybe new AP devices appearing and does a re-init of the internal completion variable. So the AP bus function ap_wait_apqn_bindings_complete() now may block on this condition variable even later after initial scan is through when new APQNs appear which need to get bound. This patch also moves the check for binding complete invocation from the probe function to the end of the AP bus scan function. This change also covers some weird scenarios where during a card hotplug the binding of the card device was sufficient for binding complete but the queue devices where still in the process of being discovered. As of now this change has no impact on existing code. The behavior change in the now later bindings complete should not impact any code (and has been tested so far). The only exploiter is the zcrypt function zcrypt_wait_api_operational() which only initial calls ap_wait_apqn_bindings_complete(). However, this new behavior of the AP bus wait for APQNs bindings complete function will be used in a later patch exploiting this for the zcrypt API layer. Signed-off-by: Harald Freudenberger <[email protected]> Reviewed-by: Holger Dengler <[email protected]> Signed-off-by: Heiko Carstens <[email protected]>
1 parent bbe37e3 commit 778412a

File tree

3 files changed

+80
-21
lines changed

3 files changed

+80
-21
lines changed

drivers/s390/crypto/ap_bus.c

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ static atomic64_t ap_scan_bus_count;
9090
/* # of bindings complete since init */
9191
static atomic64_t ap_bindings_complete_count = ATOMIC64_INIT(0);
9292

93-
/* completion for initial APQN bindings complete */
94-
static DECLARE_COMPLETION(ap_init_apqn_bindings_complete);
93+
/* completion for APQN bindings complete */
94+
static DECLARE_COMPLETION(ap_apqn_bindings_complete);
9595

9696
static struct ap_config_info *ap_qci_info;
9797
static struct ap_config_info *ap_qci_info_old;
@@ -754,7 +754,7 @@ static void ap_calc_bound_apqns(unsigned int *apqns, unsigned int *bound)
754754
}
755755

756756
/*
757-
* After initial ap bus scan do check if all existing APQNs are
757+
* After ap bus scan do check if all existing APQNs are
758758
* bound to device drivers.
759759
*/
760760
static void ap_check_bindings_complete(void)
@@ -764,9 +764,9 @@ static void ap_check_bindings_complete(void)
764764
if (atomic64_read(&ap_scan_bus_count) >= 1) {
765765
ap_calc_bound_apqns(&apqns, &bound);
766766
if (bound == apqns) {
767-
if (!completion_done(&ap_init_apqn_bindings_complete)) {
768-
complete_all(&ap_init_apqn_bindings_complete);
769-
AP_DBF_INFO("%s complete\n", __func__);
767+
if (!completion_done(&ap_apqn_bindings_complete)) {
768+
complete_all(&ap_apqn_bindings_complete);
769+
pr_debug("%s all apqn bindings complete\n", __func__);
770770
}
771771
ap_send_bindings_complete_uevent();
772772
}
@@ -783,27 +783,29 @@ static void ap_check_bindings_complete(void)
783783
* -ETIME is returned. On failures negative return values are
784784
* returned to the caller.
785785
*/
786-
int ap_wait_init_apqn_bindings_complete(unsigned long timeout)
786+
int ap_wait_apqn_bindings_complete(unsigned long timeout)
787787
{
788+
int rc = 0;
788789
long l;
789790

790-
if (completion_done(&ap_init_apqn_bindings_complete))
791+
if (completion_done(&ap_apqn_bindings_complete))
791792
return 0;
792793

793794
if (timeout)
794795
l = wait_for_completion_interruptible_timeout(
795-
&ap_init_apqn_bindings_complete, timeout);
796+
&ap_apqn_bindings_complete, timeout);
796797
else
797798
l = wait_for_completion_interruptible(
798-
&ap_init_apqn_bindings_complete);
799+
&ap_apqn_bindings_complete);
799800
if (l < 0)
800-
return l == -ERESTARTSYS ? -EINTR : l;
801+
rc = l == -ERESTARTSYS ? -EINTR : l;
801802
else if (l == 0 && timeout)
802-
return -ETIME;
803+
rc = -ETIME;
803804

804-
return 0;
805+
pr_debug("%s rc=%d\n", __func__, rc);
806+
return rc;
805807
}
806-
EXPORT_SYMBOL(ap_wait_init_apqn_bindings_complete);
808+
EXPORT_SYMBOL(ap_wait_apqn_bindings_complete);
807809

808810
static int __ap_queue_devices_with_id_unregister(struct device *dev, void *data)
809811
{
@@ -940,8 +942,6 @@ static int ap_device_probe(struct device *dev)
940942
if (is_queue_dev(dev))
941943
hash_del(&to_ap_queue(dev)->hnode);
942944
spin_unlock_bh(&ap_queues_lock);
943-
} else {
944-
ap_check_bindings_complete();
945945
}
946946

947947
out:
@@ -2136,6 +2136,49 @@ static bool ap_get_configuration(void)
21362136
sizeof(struct ap_config_info)) != 0;
21372137
}
21382138

2139+
/*
2140+
* ap_config_has_new_aps - Check current against old qci info if
2141+
* new adapters have appeared. Returns true if at least one new
2142+
* adapter in the apm mask is showing up. Existing adapters or
2143+
* receding adapters are not counted.
2144+
*/
2145+
static bool ap_config_has_new_aps(void)
2146+
{
2147+
2148+
unsigned long m[BITS_TO_LONGS(AP_DEVICES)];
2149+
2150+
if (!ap_qci_info)
2151+
return false;
2152+
2153+
bitmap_andnot(m, (unsigned long *)ap_qci_info->apm,
2154+
(unsigned long *)ap_qci_info_old->apm, AP_DEVICES);
2155+
if (!bitmap_empty(m, AP_DEVICES))
2156+
return true;
2157+
2158+
return false;
2159+
}
2160+
2161+
/*
2162+
* ap_config_has_new_doms - Check current against old qci info if
2163+
* new (usage) domains have appeared. Returns true if at least one
2164+
* new domain in the aqm mask is showing up. Existing domains or
2165+
* receding domains are not counted.
2166+
*/
2167+
static bool ap_config_has_new_doms(void)
2168+
{
2169+
unsigned long m[BITS_TO_LONGS(AP_DOMAINS)];
2170+
2171+
if (!ap_qci_info)
2172+
return false;
2173+
2174+
bitmap_andnot(m, (unsigned long *)ap_qci_info->aqm,
2175+
(unsigned long *)ap_qci_info_old->aqm, AP_DOMAINS);
2176+
if (!bitmap_empty(m, AP_DOMAINS))
2177+
return true;
2178+
2179+
return false;
2180+
}
2181+
21392182
/**
21402183
* ap_scan_bus(): Scan the AP bus for new devices
21412184
* Runs periodically, workqueue timer (ap_config_time)
@@ -2147,10 +2190,21 @@ static void ap_scan_bus(struct work_struct *unused)
21472190

21482191
pr_debug(">%s\n", __func__);
21492192

2150-
/* config change notify */
2193+
/* (re-)fetch configuration via QCI */
21512194
config_changed = ap_get_configuration();
2152-
if (config_changed)
2195+
if (config_changed) {
2196+
if (ap_config_has_new_aps() || ap_config_has_new_doms()) {
2197+
/*
2198+
* Appearance of new adapters and/or domains need to
2199+
* build new ap devices which need to get bound to an
2200+
* device driver. Thus reset the APQN bindings complete
2201+
* completion.
2202+
*/
2203+
reinit_completion(&ap_apqn_bindings_complete);
2204+
}
2205+
/* post a config change notify */
21532206
notify_config_changed();
2207+
}
21542208
ap_select_domain();
21552209

21562210
/* loop over all possible adapters */
@@ -2177,9 +2231,10 @@ static void ap_scan_bus(struct work_struct *unused)
21772231
if (atomic64_inc_return(&ap_scan_bus_count) == 1) {
21782232
pr_debug("%s init scan complete\n", __func__);
21792233
ap_send_init_scan_done_uevent();
2180-
ap_check_bindings_complete();
21812234
}
21822235

2236+
ap_check_bindings_complete();
2237+
21832238
mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
21842239

21852240
pr_debug("<%s\n", __func__);

drivers/s390/crypto/ap_bus.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,12 @@ int ap_parse_mask_str(const char *str,
352352
* the return value is 0. If the timeout (in jiffies) hits instead
353353
* -ETIME is returned. On failures negative return values are
354354
* returned to the caller.
355+
* It may be that the AP bus scan finds new devices. Then the
356+
* condition that all APQNs are bound to their device drivers
357+
* is reset to false and this call again blocks until either all
358+
* APQNs are bound to a device driver or the timeout hits again.
355359
*/
356-
int ap_wait_init_apqn_bindings_complete(unsigned long timeout);
360+
int ap_wait_apqn_bindings_complete(unsigned long timeout);
357361

358362
void ap_send_config_uevent(struct ap_device *ap_dev, bool cfg);
359363
void ap_send_online_uevent(struct ap_device *ap_dev, int online);

drivers/s390/crypto/zcrypt_api.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2008,7 +2008,7 @@ int zcrypt_wait_api_operational(void)
20082008
switch (zcrypt_wait_api_state) {
20092009
case 0:
20102010
/* initial state, invoke wait for the ap bus complete */
2011-
rc = ap_wait_init_apqn_bindings_complete(
2011+
rc = ap_wait_apqn_bindings_complete(
20122012
msecs_to_jiffies(60 * 1000));
20132013
switch (rc) {
20142014
case 0:

0 commit comments

Comments
 (0)