diff options
author | Harald Freudenberger <freude@linux.ibm.com> | 2021-04-13 18:11:09 +0200 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2021-06-16 23:46:18 +0200 |
commit | df6f508c68dbc65def0098cbdf8de7683ae551d2 (patch) | |
tree | d1cbc60422c08f5e9d01bdbacd0a5f7cf36d64d1 /drivers/s390/crypto/zcrypt_card.c | |
parent | s390/decompressor: replace use of perl with simple sed/tr (diff) | |
download | linux-df6f508c68dbc65def0098cbdf8de7683ae551d2.tar.xz linux-df6f508c68dbc65def0098cbdf8de7683ae551d2.zip |
s390/ap/zcrypt: notify userspace with online, config and mode info
This patch brings 3 reworked/new uevent changes:
* All AP uevents caused by an ap card or queue device now carry an
additional uevent env value MODE=<accel|cca|ep11>. Here is an
example:
KERNEL[1267.301292] add /devices/ap/card0a (ap)
ACTION=add
DEVPATH=/devices/ap/card0a
SUBSYSTEM=ap
DEVTYPE=ap_card
DEV_TYPE=000D
MODALIAS=ap:t0D
MODE=ep11 <- this is new
SEQNUM=1095
This is true for bind, unbind, add, remove, and change uevents
related to ap card or ap queue devices.
* On a change of the soft online attribute on a zcrypt queue or card
device a new CHANGE uevent is sent with an env value ONLINE=<0|1>.
Example uevent:
KERNEL[613.067531] change /devices/ap/card09/09.0011 (ap)
ACTION=change
DEVPATH=/devices/ap/card09/09.0011
SUBSYSTEM=ap
ONLINE=0 <- this is new
DEVTYPE=ap_queue
DRIVER=cex4queue
MODE=cca
SEQNUM=1070
- On a change of the config state of an zcrypt card device a new
CHANGE uevent is sent with an env value CONFIG=<0|1>.
Example uevent:
KERNEL[876.258680] change /devices/ap/card09 (ap)
ACTION=change
DEVPATH=/devices/ap/card09
SUBSYSTEM=ap
CONFIG=0 <- this is new
DEVTYPE=ap_card
DRIVER=cex4card
DEV_TYPE=000D
MODALIAS=ap:t0D
MODE=cca
SEQNUM=1073
Setting a card config on/off causes the dependent queue devices to
follow the config state change and thus uevents informing about the
config state change for the queue devices are also emitted.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'drivers/s390/crypto/zcrypt_card.c')
-rw-r--r-- | drivers/s390/crypto/zcrypt_card.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/s390/crypto/zcrypt_card.c b/drivers/s390/crypto/zcrypt_card.c index 09fe6bb8880b..40fd5d37d26a 100644 --- a/drivers/s390/crypto/zcrypt_card.c +++ b/drivers/s390/crypto/zcrypt_card.c @@ -64,7 +64,8 @@ static ssize_t online_store(struct device *dev, struct ap_card *ac = to_ap_card(dev); struct zcrypt_card *zc = ac->private; struct zcrypt_queue *zq; - int online, id; + int online, id, i = 0, maxzqs = 0; + struct zcrypt_queue **zq_uelist = NULL; if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1) return -EINVAL; @@ -77,10 +78,35 @@ static ssize_t online_store(struct device *dev, ZCRYPT_DBF(DBF_INFO, "card=%02x online=%d\n", id, online); + ap_send_online_uevent(&ac->ap_dev, online); + spin_lock(&zcrypt_list_lock); + /* + * As we are in atomic context here, directly sending uevents + * does not work. So collect the zqueues in a dynamic array + * and process them after zcrypt_list_lock release. As we get/put + * the zqueue objects, we make sure they exist after lock release. + */ + list_for_each_entry(zq, &zc->zqueues, list) + maxzqs++; + if (maxzqs > 0) + zq_uelist = kcalloc(maxzqs + 1, sizeof(zq), GFP_ATOMIC); list_for_each_entry(zq, &zc->zqueues, list) - zcrypt_queue_force_online(zq, online); + if (zcrypt_queue_force_online(zq, online)) + if (zq_uelist) { + zcrypt_queue_get(zq); + zq_uelist[i++] = zq; + } spin_unlock(&zcrypt_list_lock); + if (zq_uelist) { + for (i = 0; zq_uelist[i]; i++) { + zq = zq_uelist[i]; + ap_send_online_uevent(&zq->queue->ap_dev, online); + zcrypt_queue_put(zq); + } + kfree(zq_uelist); + } + return count; } |