|
Petr Tesarik |
0cbe94 |
From: Petr Tesarik <ptesarik@suse.com>
|
|
Petr Tesarik |
0cbe94 |
Subject: net/smc: kABI workarounds for struct smc_link
|
|
Petr Tesarik |
0cbe94 |
Patch-mainline: Never, kABI workaround
|
|
Petr Tesarik |
0cbe94 |
References: git-fixes
|
|
Petr Tesarik |
0cbe94 |
|
|
Petr Tesarik |
0cbe94 |
Commit e9b1a4f867ae9c1dbd1d71cd09cbdb3239fb4968 adds two new fields
|
|
Petr Tesarik |
0cbe94 |
to struct smc_link, which breaks kABI. It is not possible to mask
|
|
Petr Tesarik |
0cbe94 |
the change by moving the fields to the end of the structure, because
|
|
Petr Tesarik |
0cbe94 |
struct smc_link itself is embedded in struct smc_link_group.
|
|
Petr Tesarik |
0cbe94 |
|
|
Petr Tesarik |
0cbe94 |
However, struct smc_link is never allocated outside of struct
|
|
Petr Tesarik |
0cbe94 |
smc_link_group; it even contains its index in the lnk[] array
|
|
Petr Tesarik |
0cbe94 |
(link_idx), so it is possible to move those fields to another array
|
|
Petr Tesarik |
0cbe94 |
in struct smc_link_group, and use the backpointer plus the index
|
|
Petr Tesarik |
0cbe94 |
to access the corresponding fields.
|
|
Petr Tesarik |
0cbe94 |
|
|
Petr Tesarik |
0cbe94 |
It is safe to enlarge struct smc_link_group, because it is only ever
|
|
Petr Tesarik |
0cbe94 |
allocated by smc_lgr_create() and never embedded in another data
|
|
Petr Tesarik |
0cbe94 |
structure.
|
|
Petr Tesarik |
0cbe94 |
|
|
Petr Tesarik |
0cbe94 |
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
|
|
Petr Tesarik |
0cbe94 |
---
|
|
Petr Tesarik |
0cbe94 |
net/smc/smc_core.c | 2 +-
|
|
Petr Tesarik |
0cbe94 |
net/smc/smc_core.h | 12 ++++++++++--
|
|
Petr Tesarik |
0cbe94 |
net/smc/smc_wr.c | 10 ++++++----
|
|
Petr Tesarik |
0cbe94 |
net/smc/smc_wr.h | 5 ++++-
|
|
Petr Tesarik |
0cbe94 |
4 files changed, 21 insertions(+), 8 deletions(-)
|
|
Petr Tesarik |
0cbe94 |
|
|
Petr Tesarik |
0cbe94 |
--- a/net/smc/smc_core.c
|
|
Petr Tesarik |
0cbe94 |
+++ b/net/smc/smc_core.c
|
|
Petr Tesarik |
0cbe94 |
@@ -750,7 +750,7 @@ int smcr_link_init(struct smc_link_group
|
|
Petr Tesarik |
0cbe94 |
lnk->link_id = smcr_next_link_id(lgr);
|
|
Petr Tesarik |
0cbe94 |
lnk->lgr = lgr;
|
|
Petr Tesarik |
0cbe94 |
lnk->link_idx = link_idx;
|
|
Petr Tesarik |
0cbe94 |
- lnk->wr_rx_id_compl = 0;
|
|
Petr Tesarik |
0cbe94 |
+ lgr->lnk_kabi_fixup[link_idx].wr_rx_id_compl = 0;
|
|
Petr Tesarik |
0cbe94 |
smc_ibdev_cnt_inc(lnk);
|
|
Petr Tesarik |
0cbe94 |
smcr_copy_dev_info_to_link(lnk);
|
|
Petr Tesarik |
0cbe94 |
atomic_set(&lnk->conn_cnt, 0);
|
|
Petr Tesarik |
0cbe94 |
--- a/net/smc/smc_core.h
|
|
Petr Tesarik |
0cbe94 |
+++ b/net/smc/smc_core.h
|
|
Petr Tesarik |
0cbe94 |
@@ -115,10 +115,8 @@ struct smc_link {
|
|
Petr Tesarik |
0cbe94 |
dma_addr_t wr_rx_dma_addr; /* DMA address of wr_rx_bufs */
|
|
Petr Tesarik |
0cbe94 |
dma_addr_t wr_rx_v2_dma_addr; /* DMA address of v2 rx buf*/
|
|
Petr Tesarik |
0cbe94 |
u64 wr_rx_id; /* seq # of last recv WR */
|
|
Petr Tesarik |
0cbe94 |
- u64 wr_rx_id_compl; /* seq # of last completed WR */
|
|
Petr Tesarik |
0cbe94 |
u32 wr_rx_cnt; /* number of WR recv buffers */
|
|
Petr Tesarik |
0cbe94 |
unsigned long wr_rx_tstamp; /* jiffies when last buf rx */
|
|
Petr Tesarik |
0cbe94 |
- wait_queue_head_t wr_rx_empty_wait; /* wait for RQ empty */
|
|
Petr Tesarik |
0cbe94 |
|
|
Petr Tesarik |
0cbe94 |
struct ib_reg_wr wr_reg; /* WR register memory region */
|
|
Petr Tesarik |
0cbe94 |
wait_queue_head_t wr_reg_wait; /* wait for wr_reg result */
|
|
Petr Tesarik |
0cbe94 |
@@ -151,6 +149,12 @@ struct smc_link {
|
|
Petr Tesarik |
0cbe94 |
atomic_t conn_cnt; /* connections on this link */
|
|
Petr Tesarik |
0cbe94 |
};
|
|
Petr Tesarik |
0cbe94 |
|
|
Petr Tesarik |
0cbe94 |
+/* Extra fields removed from struct smc_link to preserve kABI. */
|
|
Petr Tesarik |
0cbe94 |
+struct smc_link_kabi_fixup {
|
|
Petr Tesarik |
0cbe94 |
+ u64 wr_rx_id_compl; /* seq # of last completed WR */
|
|
Petr Tesarik |
0cbe94 |
+ wait_queue_head_t wr_rx_empty_wait; /* wait for RQ empty */
|
|
Petr Tesarik |
0cbe94 |
+};
|
|
Petr Tesarik |
0cbe94 |
+
|
|
Petr Tesarik |
0cbe94 |
/* For now we just allow one parallel link per link group. The SMC protocol
|
|
Petr Tesarik |
0cbe94 |
* allows more (up to 8).
|
|
Petr Tesarik |
0cbe94 |
*/
|
|
Petr Tesarik |
0cbe94 |
@@ -308,6 +312,10 @@ struct smc_link_group {
|
|
Petr Tesarik |
0cbe94 |
u8 nexthop_mac[ETH_ALEN];
|
|
Petr Tesarik |
0cbe94 |
u8 uses_gateway;
|
|
Petr Tesarik |
0cbe94 |
__be32 saddr;
|
|
Petr Tesarik |
0cbe94 |
+#ifndef __GENKSYMS__
|
|
Petr Tesarik |
0cbe94 |
+ struct smc_link_kabi_fixup lnk_kabi_fixup[SMC_LINKS_PER_LGR_MAX];
|
|
Petr Tesarik |
0cbe94 |
+ /* extra lnk fields */
|
|
Petr Tesarik |
0cbe94 |
+#endif
|
|
Petr Tesarik |
0cbe94 |
};
|
|
Petr Tesarik |
0cbe94 |
struct { /* SMC-D */
|
|
Petr Tesarik |
0cbe94 |
u64 peer_gid;
|
|
Petr Tesarik |
0cbe94 |
--- a/net/smc/smc_wr.c
|
|
Petr Tesarik |
0cbe94 |
+++ b/net/smc/smc_wr.c
|
|
Petr Tesarik |
0cbe94 |
@@ -454,11 +454,13 @@ static inline void smc_wr_rx_demultiplex
|
|
Petr Tesarik |
0cbe94 |
static inline void smc_wr_rx_process_cqes(struct ib_wc wc[], int num)
|
|
Petr Tesarik |
0cbe94 |
{
|
|
Petr Tesarik |
0cbe94 |
struct smc_link *link;
|
|
Petr Tesarik |
0cbe94 |
+ struct smc_link_kabi_fixup *link_kabi_fixup;
|
|
Petr Tesarik |
0cbe94 |
int i;
|
|
Petr Tesarik |
0cbe94 |
|
|
Petr Tesarik |
0cbe94 |
for (i = 0; i < num; i++) {
|
|
Petr Tesarik |
0cbe94 |
link = wc[i].qp->qp_context;
|
|
Petr Tesarik |
0cbe94 |
- link->wr_rx_id_compl = wc[i].wr_id;
|
|
Petr Tesarik |
0cbe94 |
+ link_kabi_fixup = &link->lgr->lnk_kabi_fixup[link->link_idx];
|
|
Petr Tesarik |
0cbe94 |
+ link_kabi_fixup->wr_rx_id_compl = wc[i].wr_id;
|
|
Petr Tesarik |
0cbe94 |
if (wc[i].status == IB_WC_SUCCESS) {
|
|
Petr Tesarik |
0cbe94 |
link->wr_rx_tstamp = jiffies;
|
|
Petr Tesarik |
0cbe94 |
smc_wr_rx_demultiplex(&wc[i]);
|
|
Petr Tesarik |
0cbe94 |
@@ -470,8 +472,8 @@ static inline void smc_wr_rx_process_cqe
|
|
Petr Tesarik |
0cbe94 |
case IB_WC_RNR_RETRY_EXC_ERR:
|
|
Petr Tesarik |
0cbe94 |
case IB_WC_WR_FLUSH_ERR:
|
|
Petr Tesarik |
0cbe94 |
smcr_link_down_cond_sched(link);
|
|
Petr Tesarik |
0cbe94 |
- if (link->wr_rx_id_compl == link->wr_rx_id)
|
|
Petr Tesarik |
0cbe94 |
- wake_up(&link->wr_rx_empty_wait);
|
|
Petr Tesarik |
0cbe94 |
+ if (link_kabi_fixup->wr_rx_id_compl == link->wr_rx_id)
|
|
Petr Tesarik |
0cbe94 |
+ wake_up(&link_kabi_fixup->wr_rx_empty_wait);
|
|
Petr Tesarik |
0cbe94 |
break;
|
|
Petr Tesarik |
0cbe94 |
default:
|
|
Petr Tesarik |
0cbe94 |
smc_wr_rx_post(link); /* refill WR RX */
|
|
Petr Tesarik |
0cbe94 |
@@ -897,7 +899,7 @@ int smc_wr_create_link(struct smc_link *
|
|
Petr Tesarik |
0cbe94 |
atomic_set(&lnk->wr_tx_refcnt, 0);
|
|
Petr Tesarik |
0cbe94 |
init_waitqueue_head(&lnk->wr_reg_wait);
|
|
Petr Tesarik |
0cbe94 |
atomic_set(&lnk->wr_reg_refcnt, 0);
|
|
Petr Tesarik |
0cbe94 |
- init_waitqueue_head(&lnk->wr_rx_empty_wait);
|
|
Petr Tesarik |
0cbe94 |
+ init_waitqueue_head(&lnk->lgr->lnk_kabi_fixup[lnk->link_idx].wr_rx_empty_wait);
|
|
Petr Tesarik |
0cbe94 |
return rc;
|
|
Petr Tesarik |
0cbe94 |
|
|
Petr Tesarik |
0cbe94 |
dma_unmap:
|
|
Petr Tesarik |
0cbe94 |
--- a/net/smc/smc_wr.h
|
|
Petr Tesarik |
0cbe94 |
+++ b/net/smc/smc_wr.h
|
|
Petr Tesarik |
0cbe94 |
@@ -75,7 +75,10 @@ static inline void smc_wr_tx_link_put(st
|
|
Petr Tesarik |
0cbe94 |
|
|
Petr Tesarik |
0cbe94 |
static inline void smc_wr_drain_cq(struct smc_link *lnk)
|
|
Petr Tesarik |
0cbe94 |
{
|
|
Petr Tesarik |
0cbe94 |
- wait_event(lnk->wr_rx_empty_wait, lnk->wr_rx_id_compl == lnk->wr_rx_id);
|
|
Petr Tesarik |
0cbe94 |
+ struct smc_link_kabi_fixup *lnk_fixup =
|
|
Petr Tesarik |
0cbe94 |
+ &lnk->lgr->lnk_kabi_fixup[lnk->link_idx];
|
|
Petr Tesarik |
0cbe94 |
+ wait_event(lnk_fixup->wr_rx_empty_wait,
|
|
Petr Tesarik |
0cbe94 |
+ lnk_fixup->wr_rx_id_compl == lnk->wr_rx_id);
|
|
Petr Tesarik |
0cbe94 |
}
|
|
Petr Tesarik |
0cbe94 |
|
|
Petr Tesarik |
0cbe94 |
static inline void smc_wr_wakeup_tx_wait(struct smc_link *lnk)
|