summaryrefslogtreecommitdiff
path: root/drivers/s390/net/qeth_l2_sys.c
diff options
context:
space:
mode:
authorJulian Wiedmann <jwi@linux.ibm.com>2020-08-27 11:17:05 +0300
committerDavid S. Miller <davem@davemloft.net>2020-08-27 17:42:04 +0300
commit9d6a569a4cbab5a8b4c959d4e312daeecb7c9f09 (patch)
treee732cab8bf1d22e1905706e4fe31a7a266b3bf3f /drivers/s390/net/qeth_l2_sys.c
parent65b0494ed5b567ca78a2bf1ffc1b4054fcbfe141 (diff)
downloadlinux-9d6a569a4cbab5a8b4c959d4e312daeecb7c9f09.tar.xz
s390/qeth: strictly order bridge address events
The current code for bridge address events has two shortcomings in its control sequence: 1. after disabling address events via PNSO, we don't flush the remaining events from the event_wq. So if the feature is re-enabled fast enough, stale events could leak over. 2. PNSO and the events' arrival via the READ ccw device are unordered. So even if we flushed the workqueue, it's difficult to say whether the READ device might produce more events onto the workqueue afterwards. Fix this by 1. explicitly fencing off the events when we no longer care, in the READ device's event handler. This ensures that once we flush the workqueue, it doesn't get additional address events. 2. Flush the workqueue after disabling the events & fencing them off. As the code that triggers the flush will typically hold the sbp_lock, we need to rework the worker code to avoid a deadlock here in case of a 'notifications-stopped' event. In case of lock contention, requeue such an event with a delay. We'll eventually aquire the lock, or spot that the feature has been disabled and the event can thus be discarded. This leaves the theoretical race that a stale event could arrive _after_ we re-enabled ourselves to receive events again. Such an event would be impossible to distinguish from a 'good' event, nothing we can do about it. Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> Reviewed-by: Alexandra Winter <wintera@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390/net/qeth_l2_sys.c')
-rw-r--r--drivers/s390/net/qeth_l2_sys.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/s390/net/qeth_l2_sys.c b/drivers/s390/net/qeth_l2_sys.c
index 86bcae992f72..4695d25e54f2 100644
--- a/drivers/s390/net/qeth_l2_sys.c
+++ b/drivers/s390/net/qeth_l2_sys.c
@@ -157,6 +157,7 @@ static ssize_t qeth_bridgeport_hostnotification_store(struct device *dev,
rc = -EBUSY;
else if (qeth_card_hw_is_reachable(card)) {
rc = qeth_bridgeport_an_set(card, enable);
+ /* sbp_lock ensures ordering vs notifications-stopped events */
if (!rc)
card->options.sbp.hostnotification = enable;
} else