Skip to content

Commit 3f1710e

Browse files
Pradeep GopanapalliLinuxMinion
authored andcommitted
uvnic issues
When there is Heartbeat loss because of Link event on EDR fabric, uvnic recovery fails(some times). This is due to the fact that XVE_OPER_UP state would have cleared and xve driver has to check this once multicast group membership is retained While running MAXq test we are running into soft crash around skb_try_coalesce .Since xve driver allocates PAGE_SIZE it has to use full PAGE_SIZE for truesize of skb. xve driver doesn't allocate enough tailroom in skbs, so IP/TCP stacks need to reallocate skb head to pull IP/TCP headers. this . xve allocates some resources which are not needed by uVnic functionality. Fix this by using cm_supported flag. Orabug: 22862488 Reported-by: ye jin <[email protected]> Signed-off-by: Pradeep Gopanapalli <[email protected]> Reviewed-by: sajid zia <[email protected]> Signed-off-by: Qing Huang <[email protected]>
1 parent 157c596 commit 3f1710e

File tree

13 files changed

+144
-104
lines changed

13 files changed

+144
-104
lines changed

drivers/infiniband/ulp/xsigo/xscore/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ obj-$(CONFIG_INFINIBAND_XSCORE) := xscore.o
22
xscore-y := xscore_impl.o xs_ud.o xscore_api.o xsmp.o \
33
xscore_stats.o xscore_uadm.o
44

5-
ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8012\"
5+
ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8014\"
66
ccflags-y += -DRDMA_PORT_LINK_LAYER_CHANGES -DHAS_SKB_ACCESS_FUNCTIONS
77
ccflags-y += -DSCSI_STRUCT_CHANGES -DSCSI_TIMEOUT_CHANGES -DLLE
88
ccflags-y += -DXG_FRAG_SIZE_PRESENT -DXG_FRAG_PAGE_PRESENT

drivers/infiniband/ulp/xsigo/xsvhba/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ xsvhba-y := vhba_main.o vhba_xsmp.o vhba_create.o vhba_init.o vhba_delete.o \
33
vhba_attr.o vhba_wq.o vhba_proc.o vhba_stats.o vhba_ib.o \
44
vhba_scsi_intf.o vhba_align.o
55

6-
ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8008\"
6+
ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8014\"
77
ccflags-y += -DRDMA_PORT_LINK_LAYER_CHANGES -DHAS_SKB_ACCESS_FUNCTIONS
88
ccflags-y += -DSCSI_STRUCT_CHANGES -DSCSI_TIMEOUT_CHANGES -DLLE
99
ccflags-y += -DXG_FRAG_SIZE_PRESENT -DXG_FRAG_PAGE_PRESENT

drivers/infiniband/ulp/xsigo/xsvnic/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
obj-$(CONFIG_INFINIBAND_XSVNIC) := xsvnic.o
22
xsvnic-y := xsvnic_main.o xsvnic_stats.o
33

4-
ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8008\"
4+
ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8014\"
55
ccflags-y += -DRDMA_PORT_LINK_LAYER_CHANGES -DHAS_SKB_ACCESS_FUNCTIONS
66
ccflags-y += -DSCSI_STRUCT_CHANGES -DSCSI_TIMEOUT_CHANGES -DLLE
77
ccflags-y += -DXG_FRAG_SIZE_PRESENT -DXG_FRAG_PAGE_PRESENT

drivers/infiniband/ulp/xsigo/xve/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ obj-$(CONFIG_INFINIBAND_XVE) := xve.o
22
xve-y := xve_main.o xve_verbs.o xve_multicast.o xve_ib.o xve_tables.o \
33
xve_ethtool.o xve_cm.o xve_stats.o
44

5-
ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8008\"
5+
ccflags-y += -DXSIGO_LOCAL_VERSION=\"6.0.r8014\"
66
ccflags-y += -DRDMA_PORT_LINK_LAYER_CHANGES -DHAS_SKB_ACCESS_FUNCTIONS
77
ccflags-y += -DSCSI_STRUCT_CHANGES -DSCSI_TIMEOUT_CHANGES -DLLE
88
ccflags-y += -DXG_FRAG_SIZE_PRESENT -DXG_FRAG_PAGE_PRESENT

drivers/infiniband/ulp/xsigo/xve/xve.h

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ enum xve_flush_level {
151151
};
152152

153153
enum {
154-
XVE_UD_HEAD_SIZE = IB_GRH_BYTES + VLAN_ETH_HLEN + XVE_EOIB_LEN + 2048,
154+
XVE_UD_HEAD_SIZE = IB_GRH_BYTES + VLAN_ETH_HLEN + XVE_EOIB_LEN,
155155
XVE_UD_RX_OVN_SG = 2, /* max buffer needed for 4K mtu */
156156
XVE_UD_RX_EDR_SG = 3, /* max buffer needed for 10K mtu */
157157
XVE_CM_MTU = 0x10000 - 0x20, /* padding to align header to 16 */
@@ -223,6 +223,7 @@ enum {
223223
XVE_STATE_MACHINE,
224224
XVE_STATE_MACHINE_UP,
225225
XVE_STATE_MACHINE_DOWN,
226+
XVE_STATE_MACHINE_IBCLEAR,
226227
XVE_NAPI_POLL_COUNTER,
227228
XVE_SHORT_PKT_COUNTER,
228229
XVE_TX_COUNTER,
@@ -279,9 +280,12 @@ enum {
279280
XVE_MAC_STILL_INUSE,
280281
XVE_MAC_MOVED_COUNTER,
281282

283+
XVE_MCAST_NOTREADY,
282284
XVE_MCAST_JOIN_TASK,
283285
XVE_MCAST_LEAVE_TASK,
284286
XVE_MCAST_CARRIER_TASK,
287+
XVE_MCAST_ATTACH,
288+
XVE_MCAST_DETACH,
285289

286290
XVE_TX_UD_COUNTER,
287291
XVE_TX_RC_COUNTER,
@@ -886,6 +890,8 @@ struct icmp6_ndp {
886890
printk(level "%s: " fmt, MODULE_NAME, ##arg)
887891
#define XSMP_ERROR(fmt, arg...) \
888892
PRINT(KERN_ERR, "XSMP", fmt, ##arg)
893+
#define DRV_PRINT(fmt, arg...) \
894+
PRINT(KERN_INFO, "DRV", fmt, ##arg)
889895
#define xve_printk(level, priv, format, arg...) \
890896
printk(level "%s: " format, \
891897
((struct xve_dev_priv *) priv)->netdev->name, \
@@ -1091,42 +1097,6 @@ static inline void xve_put_ctx(struct xve_dev_priv *priv)
10911097
atomic_dec(&priv->ref_cnt);
10921098
}
10931099

1094-
/* Adjust length of skb with fragments to match received data */
1095-
static inline void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
1096-
unsigned int length, struct sk_buff *toskb)
1097-
{
1098-
int i, num_frags;
1099-
unsigned int size;
1100-
1101-
/* put header into skb */
1102-
size = min(length, hdr_space);
1103-
skb->tail += size;
1104-
skb->len += size;
1105-
length -= size;
1106-
1107-
num_frags = skb_shinfo(skb)->nr_frags;
1108-
for (i = 0; i < num_frags; i++) {
1109-
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1110-
1111-
if (length == 0) {
1112-
/* don't need this page */
1113-
if (toskb)
1114-
skb_fill_page_desc(toskb, i, skb_frag_page(frag)
1115-
, 0, PAGE_SIZE);
1116-
else
1117-
__free_page(skb_shinfo(skb)->frags[i].page.p);
1118-
--skb_shinfo(skb)->nr_frags;
1119-
} else {
1120-
size = min_t(unsigned, length, (unsigned)PAGE_SIZE);
1121-
1122-
frag->size = size;
1123-
skb->data_len += size;
1124-
skb->truesize += size;
1125-
skb->len += size;
1126-
length -= size;
1127-
}
1128-
}
1129-
}
11301100

11311101
/* functions */
11321102
int xve_poll(struct napi_struct *napi, int budget);

drivers/infiniband/ulp/xsigo/xve/xve_cm.c

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,44 @@ static void xve_cm_free_rx_reap_list(struct net_device *dev)
448448
}
449449
}
450450

451+
452+
/* Adjust length of skb with fragments to match received data */
453+
static inline void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
454+
unsigned int length, struct sk_buff *toskb)
455+
{
456+
int i, num_frags;
457+
unsigned int size;
458+
459+
/* put header into skb */
460+
size = min(length, hdr_space);
461+
skb->tail += size;
462+
skb->len += size;
463+
length -= size;
464+
465+
num_frags = skb_shinfo(skb)->nr_frags;
466+
for (i = 0; i < num_frags; i++) {
467+
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
468+
469+
if (length == 0) {
470+
/* don't need this page */
471+
if (toskb)
472+
skb_fill_page_desc(toskb, i, skb_frag_page(frag)
473+
, 0, PAGE_SIZE);
474+
else
475+
__free_page(skb_shinfo(skb)->frags[i].page.p);
476+
--skb_shinfo(skb)->nr_frags;
477+
} else {
478+
size = min_t(unsigned, length, (unsigned)PAGE_SIZE);
479+
480+
frag->size = size;
481+
skb->data_len += size;
482+
skb->truesize += size;
483+
skb->len += size;
484+
length -= size;
485+
}
486+
}
487+
}
488+
451489
void xve_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
452490
{
453491
struct xve_dev_priv *priv = netdev_priv(dev);
@@ -982,7 +1020,7 @@ static int xve_cm_tx_init(struct xve_cm_ctx *p, struct ib_sa_path_rec *pathrec)
9821020
int ret;
9831021

9841022
p->tx_ring = vmalloc(priv->xve_sendq_size * sizeof(*p->tx_ring));
985-
if (!p->tx_ring) {
1023+
if (IS_ERR(p->tx_ring)) {
9861024
xve_warn(priv, "failed to allocate tx ring\n");
9871025
ret = -ENOMEM;
9881026
goto err_tx;
@@ -1310,8 +1348,7 @@ static void xve_cm_create_srq(struct net_device *dev, int max_sge)
13101348

13111349
priv->cm.srq = ib_create_srq(priv->pd, &srq_init_attr);
13121350
if (IS_ERR(priv->cm.srq)) {
1313-
if (PTR_ERR(priv->cm.srq) != -ENOSYS)
1314-
pr_warn("%s: failed to allocate SRQ, error %ld\n",
1351+
pr_warn("%s: failed to allocate SRQ, error %ld\n",
13151352
priv->ca->name, PTR_ERR(priv->cm.srq));
13161353
priv->cm.srq = NULL;
13171354
return;
@@ -1337,6 +1374,9 @@ int xve_cm_dev_init(struct net_device *dev)
13371374
int i, ret;
13381375
struct ib_device_attr attr;
13391376

1377+
if (!priv->cm_supported)
1378+
return 0;
1379+
13401380
INIT_LIST_HEAD(&priv->cm.passive_ids);
13411381
INIT_LIST_HEAD(&priv->cm.reap_list);
13421382
INIT_LIST_HEAD(&priv->cm.start_list);
@@ -1351,8 +1391,6 @@ int xve_cm_dev_init(struct net_device *dev)
13511391
return ret;
13521392
}
13531393

1354-
priv->dev_attr = attr;
1355-
13561394
/* Based on the admin mtu from the chassis */
13571395
attr.max_srq_sge =
13581396
min_t(int,
@@ -1407,7 +1445,7 @@ void xve_cm_dev_cleanup(struct net_device *dev)
14071445
struct xve_dev_priv *priv = netdev_priv(dev);
14081446
int ret;
14091447

1410-
if (!priv->cm.srq)
1448+
if (!priv->cm_supported || !priv->cm.srq)
14111449
return;
14121450

14131451
xve_debug(DEBUG_CM_INFO, priv, "%s Cleanup xve CM\n", __func__);

drivers/infiniband/ulp/xsigo/xve/xve_ethtool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static int xve_set_coalesce(struct net_device *dev,
8080
ret = ib_modify_cq(priv->recv_cq, coal->rx_max_coalesced_frames,
8181
coal->rx_coalesce_usecs);
8282

83-
if (ret && ret != -ENOSYS) {
83+
if (ret) {
8484
xve_warn(priv, "failed modifying CQ (%d)\n", ret);
8585
return ret;
8686
}

drivers/infiniband/ulp/xsigo/xve/xve_ib.c

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,30 @@ static void xve_ud_dma_unmap_rx(struct xve_dev_priv *priv,
8787
}
8888
}
8989

90+
91+
static void xve_ud_skb_put_frags(struct xve_dev_priv *priv,
92+
struct sk_buff *skb,
93+
unsigned int length)
94+
{
95+
if (xve_ud_need_sg(priv->max_ib_mtu)) {
96+
skb_frag_t *frag = &skb_shinfo(skb)->frags[0];
97+
unsigned int size;
98+
/*
99+
* There is only two buffers needed for max_payload = 4K,
100+
* first buf size is XVE_UD_HEAD_SIZE
101+
*/
102+
skb->tail += XVE_UD_HEAD_SIZE;
103+
skb->len += length;
104+
105+
size = length - XVE_UD_HEAD_SIZE;
106+
107+
skb_frag_size_set(frag, size);
108+
skb->data_len += size;
109+
skb->truesize += PAGE_SIZE;
110+
} else
111+
skb_put(skb, length);
112+
}
113+
90114
static int xve_ib_post_receive(struct net_device *dev, int id)
91115
{
92116
struct xve_dev_priv *priv = netdev_priv(dev);
@@ -114,11 +138,16 @@ static struct sk_buff *xve_alloc_rx_skb(struct net_device *dev, int id)
114138
struct sk_buff *skb;
115139
int buf_size, align;
116140
u64 *mapping;
141+
int tailroom;
117142

118-
if (xve_ud_need_sg(priv->max_ib_mtu))
143+
if (xve_ud_need_sg(priv->max_ib_mtu)) {
144+
/* reserve some tailroom for IP/TCP headers */
119145
buf_size = XVE_UD_HEAD_SIZE;
120-
else
146+
tailroom = 128;
147+
} else {
121148
buf_size = XVE_UD_BUF_SIZE(priv->max_ib_mtu);
149+
tailroom = 0;
150+
}
122151

123152
/*
124153
* Eth header is 14 bytes, IB will leave a 40 byte gap for a GRH
@@ -127,7 +156,7 @@ static struct sk_buff *xve_alloc_rx_skb(struct net_device *dev, int id)
127156
* 4-byte EoIB header.
128157
*/
129158
align = xve_is_ovn(priv) ? 10 : 6;
130-
skb = xve_dev_alloc_skb(priv, buf_size + align);
159+
skb = xve_dev_alloc_skb(priv, buf_size + tailroom + align);
131160
if (unlikely(!skb))
132161
return NULL;
133162

@@ -207,7 +236,8 @@ void xve_process_link_state(struct xve_dev_priv *priv,
207236
set_bit(XVE_GW_STATE_UP, &priv->state);
208237
priv->hb_interval = 30*HZ;
209238

210-
if (!netif_carrier_ok(priv->netdev))
239+
if ((!netif_carrier_ok(priv->netdev)) ||
240+
(!test_bit(XVE_OPER_UP, &priv->flags)))
211241
xve_link_up(priv);
212242
} else {
213243
clear_bit(XVE_GW_STATE_UP, &priv->state);
@@ -323,7 +353,7 @@ xve_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
323353
wc->byte_len, wc->slid);
324354

325355
xve_ud_dma_unmap_rx(priv, mapping);
326-
skb_put_frags(skb, XVE_UD_HEAD_SIZE, wc->byte_len, NULL);
356+
xve_ud_skb_put_frags(priv, skb, wc->byte_len);
327357
grhhdr = (struct ib_packed_grh *)(skb->data);
328358
/* This will print packet when driver is in Debug Mode */
329359
dumppkt(skb->data, skb->len, "UD Packet Dump");
@@ -507,18 +537,14 @@ int poll_tx(struct xve_dev_priv *priv)
507537
do {
508538
n = ib_poll_cq(priv->send_cq, MAX_SEND_CQE, priv->send_wc);
509539
/* handle multiple WC's in one call */
510-
if (likely(n > 0)) {
511-
for (i = 0; i < n; ++i)
512-
xve_ib_handle_tx_wc(priv->netdev,
513-
priv->send_wc + i);
514-
tot += n;
515-
} else if (n == 0) {
516-
break;
517-
} else {
540+
for (i = 0; i < n; ++i)
541+
xve_ib_handle_tx_wc(priv->netdev,
542+
priv->send_wc + i);
543+
if (n < 0) {
518544
xve_warn(priv, "%s ib_poll_cq() failed, rc %d\n",
519-
__func__, n);
545+
__func__, n);
520546
}
521-
547+
tot += n;
522548
} while (n == MAX_SEND_CQE);
523549

524550
return tot;

drivers/infiniband/ulp/xsigo/xve/xve_main.c

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,14 +1077,14 @@ int xve_dev_init(struct net_device *dev, struct ib_device *ca, int port)
10771077
priv->rx_ring = kcalloc(priv->xve_recvq_size, sizeof(*priv->rx_ring),
10781078
GFP_KERNEL);
10791079
if (!priv->rx_ring) {
1080-
pr_warn("%s: failed to allocate RX ring (%d entries)\n",
1080+
DRV_PRINT("%s:failed to allocate RX ring (%d entries)\n",
10811081
ca->name, priv->xve_recvq_size);
10821082
goto out;
10831083
}
10841084

10851085
priv->tx_ring = vmalloc(priv->xve_sendq_size * sizeof(*priv->tx_ring));
10861086
if (!priv->tx_ring) {
1087-
pr_warn("%s: failed to allocate TX ring (%d entries)\n",
1087+
DRV_PRINT("%s:failed to allocate TX ring (%d entries)\n",
10881088
ca->name, priv->xve_sendq_size);
10891089
goto out_rx_ring_cleanup;
10901090
}
@@ -1761,7 +1761,7 @@ xve_set_edr_features(struct xve_dev_priv *priv)
17611761

17621762
int xve_set_dev_features(struct xve_dev_priv *priv, struct ib_device *hca)
17631763
{
1764-
struct ib_device_attr *device_attr;
1764+
struct ib_device_attr device_attr;
17651765
int result = -ENOMEM;
17661766

17671767
priv->netdev->watchdog_timeo = 1000 * HZ;
@@ -1796,23 +1796,15 @@ int xve_set_dev_features(struct xve_dev_priv *priv, struct ib_device *hca)
17961796

17971797
xve_set_netdev(priv->netdev);
17981798

1799-
device_attr = kmalloc(sizeof(*device_attr), GFP_KERNEL);
1800-
1801-
if (!device_attr) {
1802-
pr_warn("%s: allocation of %zu bytes failed\n",
1803-
hca->name, sizeof(*device_attr));
1804-
return result;
1805-
}
1806-
1807-
result = ib_query_device(hca, device_attr);
1799+
result = ib_query_device(hca, &device_attr);
18081800
if (result) {
18091801
pr_warn("%s: ib_query_device failed (ret = %d)\n",
18101802
hca->name, result);
1811-
kfree(device_attr);
18121803
return result;
18131804
}
1814-
priv->hca_caps = device_attr->device_cap_flags;
1815-
kfree(device_attr);
1805+
1806+
priv->dev_attr = device_attr;
1807+
priv->hca_caps = device_attr.device_cap_flags;
18161808

18171809
xve_lro_setup(priv);
18181810
if (xve_is_ovn(priv))
@@ -1969,8 +1961,8 @@ int xve_xsmp_send_oper_state(struct xve_dev_priv *priv, u64 vid, int state)
19691961
int ret;
19701962
char *str = state == XSMP_XVE_OPER_UP ? "UP" : "DOWN";
19711963

1972-
pr_info("XVE: %s Sending OPER state [%d] to %s\n",
1973-
__func__, state, priv->xve_name);
1964+
pr_info("XVE: %s Sending OPER state [%d:%s] to %s\n",
1965+
__func__, state, str, priv->xve_name);
19741966
if (state == XSMP_XVE_OPER_UP) {
19751967
set_bit(XVE_OPER_REP_SENT, &priv->state);
19761968
set_bit(XVE_PORT_LINK_UP, &priv->state);

0 commit comments

Comments
 (0)