| From foo@baz Wed Mar 28 18:37:51 CEST 2018 |
| From: Julian Wiedmann <jwi@linux.vnet.ibm.com> |
| Date: Tue, 20 Mar 2018 07:59:14 +0100 |
| Subject: s390/qeth: lock read device while queueing next buffer |
| |
| From: Julian Wiedmann <jwi@linux.vnet.ibm.com> |
| |
| |
| [ Upstream commit 17bf8c9b3d499d5168537c98b61eb7a1fcbca6c2 ] |
| |
| For calling ccw_device_start(), issue_next_read() needs to hold the |
| device's ccwlock. |
| This is satisfied for the IRQ handler path (where qeth_irq() gets called |
| under the ccwlock), but we need explicit locking for the initial call by |
| the MPC initialization. |
| |
| Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/s390/net/qeth_core_main.c | 16 +++++++++++++--- |
| 1 file changed, 13 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/s390/net/qeth_core_main.c |
| +++ b/drivers/s390/net/qeth_core_main.c |
| @@ -526,8 +526,7 @@ static inline int qeth_is_cq(struct qeth |
| queue == card->qdio.no_in_queues - 1; |
| } |
| |
| - |
| -static int qeth_issue_next_read(struct qeth_card *card) |
| +static int __qeth_issue_next_read(struct qeth_card *card) |
| { |
| int rc; |
| struct qeth_cmd_buffer *iob; |
| @@ -558,6 +557,17 @@ static int qeth_issue_next_read(struct q |
| return rc; |
| } |
| |
| +static int qeth_issue_next_read(struct qeth_card *card) |
| +{ |
| + int ret; |
| + |
| + spin_lock_irq(get_ccwdev_lock(CARD_RDEV(card))); |
| + ret = __qeth_issue_next_read(card); |
| + spin_unlock_irq(get_ccwdev_lock(CARD_RDEV(card))); |
| + |
| + return ret; |
| +} |
| + |
| static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) |
| { |
| struct qeth_reply *reply; |
| @@ -1183,7 +1193,7 @@ static void qeth_irq(struct ccw_device * |
| return; |
| if (channel == &card->read && |
| channel->state == CH_STATE_UP) |
| - qeth_issue_next_read(card); |
| + __qeth_issue_next_read(card); |
| |
| iob = channel->iob; |
| index = channel->buf_no; |