* [PATCH net] s390/qeth: serialize cmd reply with concurrent timeout
@ 2019-08-12 14:44 Julian Wiedmann
2019-08-14 2:28 ` Jakub Kicinski
0 siblings, 1 reply; 2+ messages in thread
From: Julian Wiedmann @ 2019-08-12 14:44 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
Callbacks for a cmd reply run outside the protection of card->lock, to
allow for additional cmds to be issued & enqueued in parallel.
When qeth_send_control_data() bails out for a cmd without having
received a reply (eg. due to timeout), its callback may concurrently be
processing a reply that just arrived. In this case, the callback
potentially accesses a stale reply->reply_param area that eg. was
on-stack and has already been released.
To avoid this race, add some locking so that qeth_send_control_data()
can (1) wait for a concurrently running callback, and (2) zap any
pending callback that still wants to run.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_core.h | 1 +
drivers/s390/net/qeth_core_main.c | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index c7ee07ce3615..28db887d38ed 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -629,6 +629,7 @@ struct qeth_seqno {
struct qeth_reply {
struct list_head list;
struct completion received;
+ spinlock_t lock;
int (*callback)(struct qeth_card *, struct qeth_reply *,
unsigned long);
u32 seqno;
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 4d0caeebc802..9c3310c4d61d 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -544,6 +544,7 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
if (reply) {
refcount_set(&reply->refcnt, 1);
init_completion(&reply->received);
+ spin_lock_init(&reply->lock);
}
return reply;
}
@@ -799,6 +800,13 @@ static void qeth_issue_next_read_cb(struct qeth_card *card,
if (!reply->callback) {
rc = 0;
+ goto no_callback;
+ }
+
+ spin_lock_irqsave(&reply->lock, flags);
+ if (reply->rc) {
+ /* Bail out when the requestor has already left: */
+ rc = reply->rc;
} else {
if (cmd) {
reply->offset = (u16)((char *)cmd - (char *)iob->data);
@@ -807,7 +815,9 @@ static void qeth_issue_next_read_cb(struct qeth_card *card,
rc = reply->callback(card, reply, (unsigned long)iob);
}
}
+ spin_unlock_irqrestore(&reply->lock, flags);
+no_callback:
if (rc <= 0)
qeth_notify_reply(reply, rc);
qeth_put_reply(reply);
@@ -1749,6 +1759,16 @@ static int qeth_send_control_data(struct qeth_card *card,
rc = (timeout == -ERESTARTSYS) ? -EINTR : -ETIME;
qeth_dequeue_reply(card, reply);
+
+ if (reply_cb) {
+ /* Wait until the callback for a late reply has completed: */
+ spin_lock_irq(&reply->lock);
+ if (rc)
+ /* Zap any callback that's still pending: */
+ reply->rc = rc;
+ spin_unlock_irq(&reply->lock);
+ }
+
if (!rc)
rc = reply->rc;
qeth_put_reply(reply);
--
2.17.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH net] s390/qeth: serialize cmd reply with concurrent timeout
2019-08-12 14:44 [PATCH net] s390/qeth: serialize cmd reply with concurrent timeout Julian Wiedmann
@ 2019-08-14 2:28 ` Jakub Kicinski
0 siblings, 0 replies; 2+ messages in thread
From: Jakub Kicinski @ 2019-08-14 2:28 UTC (permalink / raw)
To: Julian Wiedmann
Cc: David Miller, netdev, linux-s390, Heiko Carstens, Stefan Raspl,
Ursula Braun
On Mon, 12 Aug 2019 16:44:35 +0200, Julian Wiedmann wrote:
> Callbacks for a cmd reply run outside the protection of card->lock, to
> allow for additional cmds to be issued & enqueued in parallel.
>
> When qeth_send_control_data() bails out for a cmd without having
> received a reply (eg. due to timeout), its callback may concurrently be
> processing a reply that just arrived. In this case, the callback
> potentially accesses a stale reply->reply_param area that eg. was
> on-stack and has already been released.
>
> To avoid this race, add some locking so that qeth_send_control_data()
> can (1) wait for a concurrently running callback, and (2) zap any
> pending callback that still wants to run.
>
> Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Applied to net, thank you.
Please consider adding the Fixes tag for net submissions.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-08-14 2:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-12 14:44 [PATCH net] s390/qeth: serialize cmd reply with concurrent timeout Julian Wiedmann
2019-08-14 2:28 ` Jakub Kicinski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).