diff options
author | Karsten Graul <kgraul@linux.ibm.com> | 2020-04-30 15:55:39 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-04-30 21:44:33 +0200 |
commit | a6688d919b220bd714948e03bb3caa8a66895005 (patch) | |
tree | f516aa8b543659c2094fba1fbd706cd55ae29342 /net/smc | |
parent | net/smc: add event-based llc_flow framework (diff) | |
download | linux-a6688d919b220bd714948e03bb3caa8a66895005.tar.xz linux-a6688d919b220bd714948e03bb3caa8a66895005.zip |
net/smc: enqueue all received LLC messages
Introduce smc_llc_enqueue() to enqueue LLC messages, and adapt
smc_llc_rx_handler() to enqueue all received LLC messages.
smc_llc_enqueue() also makes it possible to enqueue LLC messages from
local code.
Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Reviewed-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/smc')
-rw-r--r-- | net/smc/smc_llc.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c index 647cf1a2dfa5..a146b3b43580 100644 --- a/net/smc/smc_llc.c +++ b/net/smc/smc_llc.c @@ -719,11 +719,14 @@ again: } /* process llc responses in tasklet context */ -static void smc_llc_rx_response(struct smc_link *link, union smc_llc_msg *llc) +static void smc_llc_rx_response(struct smc_link *link, + struct smc_llc_qentry *qentry) { + u8 llc_type = qentry->msg.raw.hdr.common.type; + union smc_llc_msg *llc = &qentry->msg; int rc = 0; - switch (llc->raw.hdr.common.type) { + switch (llc_type) { case SMC_LLC_TEST_LINK: if (link->state == SMC_LNK_ACTIVE) complete(&link->llc_testlink_resp); @@ -759,40 +762,49 @@ static void smc_llc_rx_response(struct smc_link *link, union smc_llc_msg *llc) complete(&link->llc_delete_rkey_resp); break; } + kfree(qentry); } -/* copy received msg and add it to the event queue */ -static void smc_llc_rx_handler(struct ib_wc *wc, void *buf) +static void smc_llc_enqueue(struct smc_link *link, union smc_llc_msg *llc) { - struct smc_link *link = (struct smc_link *)wc->qp->qp_context; struct smc_link_group *lgr = link->lgr; struct smc_llc_qentry *qentry; - union smc_llc_msg *llc = buf; unsigned long flags; - if (wc->byte_len < sizeof(*llc)) - return; /* short message */ - if (llc->raw.hdr.length != sizeof(*llc)) - return; /* invalid message */ - - /* process responses immediately */ - if (llc->raw.hdr.flags & SMC_LLC_FLAG_RESP) { - smc_llc_rx_response(link, llc); - return; - } - qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC); if (!qentry) return; qentry->link = link; INIT_LIST_HEAD(&qentry->list); memcpy(&qentry->msg, llc, sizeof(union smc_llc_msg)); + + /* process responses immediately */ + if (llc->raw.hdr.flags & SMC_LLC_FLAG_RESP) { + smc_llc_rx_response(link, qentry); + return; + } + + /* add requests to event queue */ spin_lock_irqsave(&lgr->llc_event_q_lock, flags); list_add_tail(&qentry->list, &lgr->llc_event_q); spin_unlock_irqrestore(&lgr->llc_event_q_lock, flags); schedule_work(&link->lgr->llc_event_work); } +/* copy received msg and add it to the event queue */ +static void smc_llc_rx_handler(struct ib_wc *wc, void *buf) +{ + struct smc_link *link = (struct smc_link *)wc->qp->qp_context; + union smc_llc_msg *llc = buf; + + if (wc->byte_len < sizeof(*llc)) + return; /* short message */ + if (llc->raw.hdr.length != sizeof(*llc)) + return; /* invalid message */ + + smc_llc_enqueue(link, llc); +} + /***************************** worker, utils *********************************/ static void smc_llc_testlink_work(struct work_struct *work) |