Message ID | 20180317075852.11785-1-ipylypiv@silver-peak.com |
---|---|
State | Not Applicable, archived |
Delegated to: | David Miller |
Headers | show |
Series | vmxnet3: fix LRO feature check | expand |
From: Igor Pylypiv <ipylypiv@silver-peak.com> Date: Sat, 17 Mar 2018 00:58:52 -0700 > rxcsum and lro fields were deleted in commit a0d2730c9571 ("net: vmxnet3: > convert to hw_features"). With upgrading to newer version those fields were > resurrected and new code started using uninitialized lro field. > Removing rxcsum and lro fields. > > Fixes: 45dac1d6ea04 ("vmxnet3: Changes for vmxnet3 adapter version 2 (fwd)") > Signed-off-by: Igor Pylypiv <ipylypiv@silver-peak.com> Why are you posting this again? I applied the copy of this patch which was part of a two part series posted earlier.
The 03/17/2018 20:20, David Miller wrote: > From: Igor Pylypiv <ipylypiv@silver-peak.com> > Date: Sat, 17 Mar 2018 00:58:52 -0700 > > > rxcsum and lro fields were deleted in commit a0d2730c9571 ("net: vmxnet3: > > convert to hw_features"). With upgrading to newer version those fields were > > resurrected and new code started using uninitialized lro field. > > Removing rxcsum and lro fields. > > > > Fixes: 45dac1d6ea04 ("vmxnet3: Changes for vmxnet3 adapter version 2 (fwd)") > > Signed-off-by: Igor Pylypiv <ipylypiv@silver-peak.com> > > Why are you posting this again? > > I applied the copy of this patch which was part of a two part series > posted earlier. No way!!! I know it is hard to believe but I found this bug myself. That's really odd. I took linux-next-20180316 and patch wasn't there. Now I see the patch in your tree. Anyway, let me send another one to delete rxcsum at least...
Hi Igor, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on v4.16-rc4] [also build test WARNING on next-20180316] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Igor-Pylypiv/vmxnet3-fix-LRO-feature-check/20180318-140725 config: i386-randconfig-x003-201811 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): drivers/net/vmxnet3/vmxnet3_drv.c: In function 'vmxnet3_rq_rx_complete': >> drivers/net/vmxnet3/vmxnet3_drv.c:1474:8: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses] !adapter->netdev->features & NETIF_F_LRO) { ^~~~~~~~~~~~~~~~~~~~~~~~~~ vim +1474 drivers/net/vmxnet3/vmxnet3_drv.c 1255 1256 static int 1257 vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, 1258 struct vmxnet3_adapter *adapter, int quota) 1259 { 1260 static const u32 rxprod_reg[2] = { 1261 VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2 1262 }; 1263 u32 num_pkts = 0; 1264 bool skip_page_frags = false; 1265 struct Vmxnet3_RxCompDesc *rcd; 1266 struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx; 1267 u16 segCnt = 0, mss = 0; 1268 #ifdef __BIG_ENDIAN_BITFIELD 1269 struct Vmxnet3_RxDesc rxCmdDesc; 1270 struct Vmxnet3_RxCompDesc rxComp; 1271 #endif 1272 vmxnet3_getRxComp(rcd, &rq->comp_ring.base[rq->comp_ring.next2proc].rcd, 1273 &rxComp); 1274 while (rcd->gen == rq->comp_ring.gen) { 1275 struct vmxnet3_rx_buf_info *rbi; 1276 struct sk_buff *skb, *new_skb = NULL; 1277 struct page *new_page = NULL; 1278 dma_addr_t new_dma_addr; 1279 int num_to_alloc; 1280 struct Vmxnet3_RxDesc *rxd; 1281 u32 idx, ring_idx; 1282 struct vmxnet3_cmd_ring *ring = NULL; 1283 if (num_pkts >= quota) { 1284 /* we may stop even before we see the EOP desc of 1285 * the current pkt 1286 */ 1287 break; 1288 } 1289 BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2 && 1290 rcd->rqID != rq->dataRingQid); 1291 idx = rcd->rxdIdx; 1292 ring_idx = VMXNET3_GET_RING_IDX(adapter, rcd->rqID); 1293 ring = rq->rx_ring + ring_idx; 1294 vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd, 1295 &rxCmdDesc); 1296 rbi = rq->buf_info[ring_idx] + idx; 1297 1298 BUG_ON(rxd->addr != rbi->dma_addr || 1299 rxd->len != rbi->len); 1300 1301 if (unlikely(rcd->eop && rcd->err)) { 1302 vmxnet3_rx_error(rq, rcd, ctx, adapter); 1303 goto rcd_done; 1304 } 1305 1306 if (rcd->sop) { /* first buf of the pkt */ 1307 bool rxDataRingUsed; 1308 u16 len; 1309 1310 BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_HEAD || 1311 (rcd->rqID != rq->qid && 1312 rcd->rqID != rq->dataRingQid)); 1313 1314 BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_SKB); 1315 BUG_ON(ctx->skb != NULL || rbi->skb == NULL); 1316 1317 if (unlikely(rcd->len == 0)) { 1318 /* Pretend the rx buffer is skipped. */ 1319 BUG_ON(!(rcd->sop && rcd->eop)); 1320 netdev_dbg(adapter->netdev, 1321 "rxRing[%u][%u] 0 length\n", 1322 ring_idx, idx); 1323 goto rcd_done; 1324 } 1325 1326 skip_page_frags = false; 1327 ctx->skb = rbi->skb; 1328 1329 rxDataRingUsed = 1330 VMXNET3_RX_DATA_RING(adapter, rcd->rqID); 1331 len = rxDataRingUsed ? rcd->len : rbi->len; 1332 new_skb = netdev_alloc_skb_ip_align(adapter->netdev, 1333 len); 1334 if (new_skb == NULL) { 1335 /* Skb allocation failed, do not handover this 1336 * skb to stack. Reuse it. Drop the existing pkt 1337 */ 1338 rq->stats.rx_buf_alloc_failure++; 1339 ctx->skb = NULL; 1340 rq->stats.drop_total++; 1341 skip_page_frags = true; 1342 goto rcd_done; 1343 } 1344 1345 if (rxDataRingUsed) { 1346 size_t sz; 1347 1348 BUG_ON(rcd->len > rq->data_ring.desc_size); 1349 1350 ctx->skb = new_skb; 1351 sz = rcd->rxdIdx * rq->data_ring.desc_size; 1352 memcpy(new_skb->data, 1353 &rq->data_ring.base[sz], rcd->len); 1354 } else { 1355 ctx->skb = rbi->skb; 1356 1357 new_dma_addr = 1358 dma_map_single(&adapter->pdev->dev, 1359 new_skb->data, rbi->len, 1360 PCI_DMA_FROMDEVICE); 1361 if (dma_mapping_error(&adapter->pdev->dev, 1362 new_dma_addr)) { 1363 dev_kfree_skb(new_skb); 1364 /* Skb allocation failed, do not 1365 * handover this skb to stack. Reuse 1366 * it. Drop the existing pkt. 1367 */ 1368 rq->stats.rx_buf_alloc_failure++; 1369 ctx->skb = NULL; 1370 rq->stats.drop_total++; 1371 skip_page_frags = true; 1372 goto rcd_done; 1373 } 1374 1375 dma_unmap_single(&adapter->pdev->dev, 1376 rbi->dma_addr, 1377 rbi->len, 1378 PCI_DMA_FROMDEVICE); 1379 1380 /* Immediate refill */ 1381 rbi->skb = new_skb; 1382 rbi->dma_addr = new_dma_addr; 1383 rxd->addr = cpu_to_le64(rbi->dma_addr); 1384 rxd->len = rbi->len; 1385 } 1386 1387 #ifdef VMXNET3_RSS 1388 if (rcd->rssType != VMXNET3_RCD_RSS_TYPE_NONE && 1389 (adapter->netdev->features & NETIF_F_RXHASH)) 1390 skb_set_hash(ctx->skb, 1391 le32_to_cpu(rcd->rssHash), 1392 PKT_HASH_TYPE_L3); 1393 #endif 1394 skb_put(ctx->skb, rcd->len); 1395 1396 if (VMXNET3_VERSION_GE_2(adapter) && 1397 rcd->type == VMXNET3_CDTYPE_RXCOMP_LRO) { 1398 struct Vmxnet3_RxCompDescExt *rcdlro; 1399 rcdlro = (struct Vmxnet3_RxCompDescExt *)rcd; 1400 1401 segCnt = rcdlro->segCnt; 1402 WARN_ON_ONCE(segCnt == 0); 1403 mss = rcdlro->mss; 1404 if (unlikely(segCnt <= 1)) 1405 segCnt = 0; 1406 } else { 1407 segCnt = 0; 1408 } 1409 } else { 1410 BUG_ON(ctx->skb == NULL && !skip_page_frags); 1411 1412 /* non SOP buffer must be type 1 in most cases */ 1413 BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_PAGE); 1414 BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY); 1415 1416 /* If an sop buffer was dropped, skip all 1417 * following non-sop fragments. They will be reused. 1418 */ 1419 if (skip_page_frags) 1420 goto rcd_done; 1421 1422 if (rcd->len) { 1423 new_page = alloc_page(GFP_ATOMIC); 1424 /* Replacement page frag could not be allocated. 1425 * Reuse this page. Drop the pkt and free the 1426 * skb which contained this page as a frag. Skip 1427 * processing all the following non-sop frags. 1428 */ 1429 if (unlikely(!new_page)) { 1430 rq->stats.rx_buf_alloc_failure++; 1431 dev_kfree_skb(ctx->skb); 1432 ctx->skb = NULL; 1433 skip_page_frags = true; 1434 goto rcd_done; 1435 } 1436 new_dma_addr = dma_map_page(&adapter->pdev->dev, 1437 new_page, 1438 0, PAGE_SIZE, 1439 PCI_DMA_FROMDEVICE); 1440 if (dma_mapping_error(&adapter->pdev->dev, 1441 new_dma_addr)) { 1442 put_page(new_page); 1443 rq->stats.rx_buf_alloc_failure++; 1444 dev_kfree_skb(ctx->skb); 1445 ctx->skb = NULL; 1446 skip_page_frags = true; 1447 goto rcd_done; 1448 } 1449 1450 dma_unmap_page(&adapter->pdev->dev, 1451 rbi->dma_addr, rbi->len, 1452 PCI_DMA_FROMDEVICE); 1453 1454 vmxnet3_append_frag(ctx->skb, rcd, rbi); 1455 1456 /* Immediate refill */ 1457 rbi->page = new_page; 1458 rbi->dma_addr = new_dma_addr; 1459 rxd->addr = cpu_to_le64(rbi->dma_addr); 1460 rxd->len = rbi->len; 1461 } 1462 } 1463 1464 1465 skb = ctx->skb; 1466 if (rcd->eop) { 1467 u32 mtu = adapter->netdev->mtu; 1468 skb->len += skb->data_len; 1469 1470 vmxnet3_rx_csum(adapter, skb, 1471 (union Vmxnet3_GenericDesc *)rcd); 1472 skb->protocol = eth_type_trans(skb, adapter->netdev); 1473 if (!rcd->tcp || > 1474 !adapter->netdev->features & NETIF_F_LRO) { 1475 goto not_lro; 1476 } 1477 1478 if (segCnt != 0 && mss != 0) { 1479 skb_shinfo(skb)->gso_type = rcd->v4 ? 1480 SKB_GSO_TCPV4 : SKB_GSO_TCPV6; 1481 skb_shinfo(skb)->gso_size = mss; 1482 skb_shinfo(skb)->gso_segs = segCnt; 1483 } else if (segCnt != 0 || skb->len > mtu) { 1484 u32 hlen; 1485 1486 hlen = vmxnet3_get_hdr_len(adapter, skb, 1487 (union Vmxnet3_GenericDesc *)rcd); 1488 if (hlen == 0) 1489 goto not_lro; 1490 1491 skb_shinfo(skb)->gso_type = 1492 rcd->v4 ? SKB_GSO_TCPV4 : SKB_GSO_TCPV6; 1493 if (segCnt != 0) { 1494 skb_shinfo(skb)->gso_segs = segCnt; 1495 skb_shinfo(skb)->gso_size = 1496 DIV_ROUND_UP(skb->len - 1497 hlen, segCnt); 1498 } else { 1499 skb_shinfo(skb)->gso_size = mtu - hlen; 1500 } 1501 } 1502 not_lro: 1503 if (unlikely(rcd->ts)) 1504 __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), rcd->tci); 1505 1506 if (adapter->netdev->features & NETIF_F_LRO) 1507 netif_receive_skb(skb); 1508 else 1509 napi_gro_receive(&rq->napi, skb); 1510 1511 ctx->skb = NULL; 1512 num_pkts++; 1513 } 1514 1515 rcd_done: 1516 /* device may have skipped some rx descs */ 1517 ring->next2comp = idx; 1518 num_to_alloc = vmxnet3_cmd_ring_desc_avail(ring); 1519 ring = rq->rx_ring + ring_idx; 1520 while (num_to_alloc) { 1521 vmxnet3_getRxDesc(rxd, &ring->base[ring->next2fill].rxd, 1522 &rxCmdDesc); 1523 BUG_ON(!rxd->addr); 1524 1525 /* Recv desc is ready to be used by the device */ 1526 rxd->gen = ring->gen; 1527 vmxnet3_cmd_ring_adv_next2fill(ring); 1528 num_to_alloc--; 1529 } 1530 1531 /* if needed, update the register */ 1532 if (unlikely(rq->shared->updateRxProd)) { 1533 VMXNET3_WRITE_BAR0_REG(adapter, 1534 rxprod_reg[ring_idx] + rq->qid * 8, 1535 ring->next2fill); 1536 } 1537 1538 vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring); 1539 vmxnet3_getRxComp(rcd, 1540 &rq->comp_ring.base[rq->comp_ring.next2proc].rcd, &rxComp); 1541 } 1542 1543 return num_pkts; 1544 } 1545 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Igor, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on v4.16-rc4] [also build test WARNING on next-20180316] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Igor-Pylypiv/vmxnet3-fix-LRO-feature-check/20180318-140725 config: x86_64-randconfig-s3-03181820 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): In file included from include/linux/kernel.h:10:0, from include/linux/list.h:9, from include/linux/module.h:9, from drivers/net//vmxnet3/vmxnet3_drv.c:27: drivers/net//vmxnet3/vmxnet3_drv.c: In function 'vmxnet3_rq_rx_complete': drivers/net//vmxnet3/vmxnet3_drv.c:1474:8: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses] !adapter->netdev->features & NETIF_F_LRO) { ^~~~~~~~~~~~~~~~~~~ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> drivers/net//vmxnet3/vmxnet3_drv.c:1473:4: note: in expansion of macro 'if' if (!rcd->tcp || ^~ drivers/net//vmxnet3/vmxnet3_drv.c:1474:8: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses] !adapter->netdev->features & NETIF_F_LRO) { ^~~~~~~~~~~~~~~~~~~ include/linux/compiler.h:58:42: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> drivers/net//vmxnet3/vmxnet3_drv.c:1473:4: note: in expansion of macro 'if' if (!rcd->tcp || ^~ drivers/net//vmxnet3/vmxnet3_drv.c:1474:8: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses] !adapter->netdev->features & NETIF_F_LRO) { ^~~~~~~~~~~~~~~~~~~ include/linux/compiler.h:69:16: note: in definition of macro '__trace_if' ______r = !!(cond); \ ^~~~ >> drivers/net//vmxnet3/vmxnet3_drv.c:1473:4: note: in expansion of macro 'if' if (!rcd->tcp || ^~ vim +/if +1473 drivers/net//vmxnet3/vmxnet3_drv.c 1255 1256 static int 1257 vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, 1258 struct vmxnet3_adapter *adapter, int quota) 1259 { 1260 static const u32 rxprod_reg[2] = { 1261 VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2 1262 }; 1263 u32 num_pkts = 0; 1264 bool skip_page_frags = false; 1265 struct Vmxnet3_RxCompDesc *rcd; 1266 struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx; 1267 u16 segCnt = 0, mss = 0; 1268 #ifdef __BIG_ENDIAN_BITFIELD 1269 struct Vmxnet3_RxDesc rxCmdDesc; 1270 struct Vmxnet3_RxCompDesc rxComp; 1271 #endif 1272 vmxnet3_getRxComp(rcd, &rq->comp_ring.base[rq->comp_ring.next2proc].rcd, 1273 &rxComp); 1274 while (rcd->gen == rq->comp_ring.gen) { 1275 struct vmxnet3_rx_buf_info *rbi; 1276 struct sk_buff *skb, *new_skb = NULL; 1277 struct page *new_page = NULL; 1278 dma_addr_t new_dma_addr; 1279 int num_to_alloc; 1280 struct Vmxnet3_RxDesc *rxd; 1281 u32 idx, ring_idx; 1282 struct vmxnet3_cmd_ring *ring = NULL; 1283 if (num_pkts >= quota) { 1284 /* we may stop even before we see the EOP desc of 1285 * the current pkt 1286 */ 1287 break; 1288 } 1289 BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2 && 1290 rcd->rqID != rq->dataRingQid); 1291 idx = rcd->rxdIdx; 1292 ring_idx = VMXNET3_GET_RING_IDX(adapter, rcd->rqID); 1293 ring = rq->rx_ring + ring_idx; 1294 vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd, 1295 &rxCmdDesc); 1296 rbi = rq->buf_info[ring_idx] + idx; 1297 1298 BUG_ON(rxd->addr != rbi->dma_addr || 1299 rxd->len != rbi->len); 1300 1301 if (unlikely(rcd->eop && rcd->err)) { 1302 vmxnet3_rx_error(rq, rcd, ctx, adapter); 1303 goto rcd_done; 1304 } 1305 1306 if (rcd->sop) { /* first buf of the pkt */ 1307 bool rxDataRingUsed; 1308 u16 len; 1309 1310 BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_HEAD || 1311 (rcd->rqID != rq->qid && 1312 rcd->rqID != rq->dataRingQid)); 1313 1314 BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_SKB); 1315 BUG_ON(ctx->skb != NULL || rbi->skb == NULL); 1316 1317 if (unlikely(rcd->len == 0)) { 1318 /* Pretend the rx buffer is skipped. */ 1319 BUG_ON(!(rcd->sop && rcd->eop)); 1320 netdev_dbg(adapter->netdev, 1321 "rxRing[%u][%u] 0 length\n", 1322 ring_idx, idx); 1323 goto rcd_done; 1324 } 1325 1326 skip_page_frags = false; 1327 ctx->skb = rbi->skb; 1328 1329 rxDataRingUsed = 1330 VMXNET3_RX_DATA_RING(adapter, rcd->rqID); 1331 len = rxDataRingUsed ? rcd->len : rbi->len; 1332 new_skb = netdev_alloc_skb_ip_align(adapter->netdev, 1333 len); 1334 if (new_skb == NULL) { 1335 /* Skb allocation failed, do not handover this 1336 * skb to stack. Reuse it. Drop the existing pkt 1337 */ 1338 rq->stats.rx_buf_alloc_failure++; 1339 ctx->skb = NULL; 1340 rq->stats.drop_total++; 1341 skip_page_frags = true; 1342 goto rcd_done; 1343 } 1344 1345 if (rxDataRingUsed) { 1346 size_t sz; 1347 1348 BUG_ON(rcd->len > rq->data_ring.desc_size); 1349 1350 ctx->skb = new_skb; 1351 sz = rcd->rxdIdx * rq->data_ring.desc_size; 1352 memcpy(new_skb->data, 1353 &rq->data_ring.base[sz], rcd->len); 1354 } else { 1355 ctx->skb = rbi->skb; 1356 1357 new_dma_addr = 1358 dma_map_single(&adapter->pdev->dev, 1359 new_skb->data, rbi->len, 1360 PCI_DMA_FROMDEVICE); 1361 if (dma_mapping_error(&adapter->pdev->dev, 1362 new_dma_addr)) { 1363 dev_kfree_skb(new_skb); 1364 /* Skb allocation failed, do not 1365 * handover this skb to stack. Reuse 1366 * it. Drop the existing pkt. 1367 */ 1368 rq->stats.rx_buf_alloc_failure++; 1369 ctx->skb = NULL; 1370 rq->stats.drop_total++; 1371 skip_page_frags = true; 1372 goto rcd_done; 1373 } 1374 1375 dma_unmap_single(&adapter->pdev->dev, 1376 rbi->dma_addr, 1377 rbi->len, 1378 PCI_DMA_FROMDEVICE); 1379 1380 /* Immediate refill */ 1381 rbi->skb = new_skb; 1382 rbi->dma_addr = new_dma_addr; 1383 rxd->addr = cpu_to_le64(rbi->dma_addr); 1384 rxd->len = rbi->len; 1385 } 1386 1387 #ifdef VMXNET3_RSS 1388 if (rcd->rssType != VMXNET3_RCD_RSS_TYPE_NONE && 1389 (adapter->netdev->features & NETIF_F_RXHASH)) 1390 skb_set_hash(ctx->skb, 1391 le32_to_cpu(rcd->rssHash), 1392 PKT_HASH_TYPE_L3); 1393 #endif 1394 skb_put(ctx->skb, rcd->len); 1395 1396 if (VMXNET3_VERSION_GE_2(adapter) && 1397 rcd->type == VMXNET3_CDTYPE_RXCOMP_LRO) { 1398 struct Vmxnet3_RxCompDescExt *rcdlro; 1399 rcdlro = (struct Vmxnet3_RxCompDescExt *)rcd; 1400 1401 segCnt = rcdlro->segCnt; 1402 WARN_ON_ONCE(segCnt == 0); 1403 mss = rcdlro->mss; 1404 if (unlikely(segCnt <= 1)) 1405 segCnt = 0; 1406 } else { 1407 segCnt = 0; 1408 } 1409 } else { 1410 BUG_ON(ctx->skb == NULL && !skip_page_frags); 1411 1412 /* non SOP buffer must be type 1 in most cases */ 1413 BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_PAGE); 1414 BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY); 1415 1416 /* If an sop buffer was dropped, skip all 1417 * following non-sop fragments. They will be reused. 1418 */ 1419 if (skip_page_frags) 1420 goto rcd_done; 1421 1422 if (rcd->len) { 1423 new_page = alloc_page(GFP_ATOMIC); 1424 /* Replacement page frag could not be allocated. 1425 * Reuse this page. Drop the pkt and free the 1426 * skb which contained this page as a frag. Skip 1427 * processing all the following non-sop frags. 1428 */ 1429 if (unlikely(!new_page)) { 1430 rq->stats.rx_buf_alloc_failure++; 1431 dev_kfree_skb(ctx->skb); 1432 ctx->skb = NULL; 1433 skip_page_frags = true; 1434 goto rcd_done; 1435 } 1436 new_dma_addr = dma_map_page(&adapter->pdev->dev, 1437 new_page, 1438 0, PAGE_SIZE, 1439 PCI_DMA_FROMDEVICE); 1440 if (dma_mapping_error(&adapter->pdev->dev, 1441 new_dma_addr)) { 1442 put_page(new_page); 1443 rq->stats.rx_buf_alloc_failure++; 1444 dev_kfree_skb(ctx->skb); 1445 ctx->skb = NULL; 1446 skip_page_frags = true; 1447 goto rcd_done; 1448 } 1449 1450 dma_unmap_page(&adapter->pdev->dev, 1451 rbi->dma_addr, rbi->len, 1452 PCI_DMA_FROMDEVICE); 1453 1454 vmxnet3_append_frag(ctx->skb, rcd, rbi); 1455 1456 /* Immediate refill */ 1457 rbi->page = new_page; 1458 rbi->dma_addr = new_dma_addr; 1459 rxd->addr = cpu_to_le64(rbi->dma_addr); 1460 rxd->len = rbi->len; 1461 } 1462 } 1463 1464 1465 skb = ctx->skb; 1466 if (rcd->eop) { 1467 u32 mtu = adapter->netdev->mtu; 1468 skb->len += skb->data_len; 1469 1470 vmxnet3_rx_csum(adapter, skb, 1471 (union Vmxnet3_GenericDesc *)rcd); 1472 skb->protocol = eth_type_trans(skb, adapter->netdev); > 1473 if (!rcd->tcp || 1474 !adapter->netdev->features & NETIF_F_LRO) { 1475 goto not_lro; 1476 } 1477 1478 if (segCnt != 0 && mss != 0) { 1479 skb_shinfo(skb)->gso_type = rcd->v4 ? 1480 SKB_GSO_TCPV4 : SKB_GSO_TCPV6; 1481 skb_shinfo(skb)->gso_size = mss; 1482 skb_shinfo(skb)->gso_segs = segCnt; 1483 } else if (segCnt != 0 || skb->len > mtu) { 1484 u32 hlen; 1485 1486 hlen = vmxnet3_get_hdr_len(adapter, skb, 1487 (union Vmxnet3_GenericDesc *)rcd); 1488 if (hlen == 0) 1489 goto not_lro; 1490 1491 skb_shinfo(skb)->gso_type = 1492 rcd->v4 ? SKB_GSO_TCPV4 : SKB_GSO_TCPV6; 1493 if (segCnt != 0) { 1494 skb_shinfo(skb)->gso_segs = segCnt; 1495 skb_shinfo(skb)->gso_size = 1496 DIV_ROUND_UP(skb->len - 1497 hlen, segCnt); 1498 } else { 1499 skb_shinfo(skb)->gso_size = mtu - hlen; 1500 } 1501 } 1502 not_lro: 1503 if (unlikely(rcd->ts)) 1504 __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), rcd->tci); 1505 1506 if (adapter->netdev->features & NETIF_F_LRO) 1507 netif_receive_skb(skb); 1508 else 1509 napi_gro_receive(&rq->napi, skb); 1510 1511 ctx->skb = NULL; 1512 num_pkts++; 1513 } 1514 1515 rcd_done: 1516 /* device may have skipped some rx descs */ 1517 ring->next2comp = idx; 1518 num_to_alloc = vmxnet3_cmd_ring_desc_avail(ring); 1519 ring = rq->rx_ring + ring_idx; 1520 while (num_to_alloc) { 1521 vmxnet3_getRxDesc(rxd, &ring->base[ring->next2fill].rxd, 1522 &rxCmdDesc); 1523 BUG_ON(!rxd->addr); 1524 1525 /* Recv desc is ready to be used by the device */ 1526 rxd->gen = ring->gen; 1527 vmxnet3_cmd_ring_adv_next2fill(ring); 1528 num_to_alloc--; 1529 } 1530 1531 /* if needed, update the register */ 1532 if (unlikely(rq->shared->updateRxProd)) { 1533 VMXNET3_WRITE_BAR0_REG(adapter, 1534 rxprod_reg[ring_idx] + rq->qid * 8, 1535 ring->next2fill); 1536 } 1537 1538 vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring); 1539 vmxnet3_getRxComp(rcd, 1540 &rq->comp_ring.base[rq->comp_ring.next2proc].rcd, &rxComp); 1541 } 1542 1543 return num_pkts; 1544 } 1545 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
From: kbuild test robot <lkp@intel.com> Date: Sun, 18 Mar 2018 14:37:35 +0800 > All warnings (new ones prefixed by >>): > > drivers/net/vmxnet3/vmxnet3_drv.c: In function 'vmxnet3_rq_rx_complete': >>> drivers/net/vmxnet3/vmxnet3_drv.c:1474:8: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses] > !adapter->netdev->features & NETIF_F_LRO) { > ^~~~~~~~~~~~~~~~~~~~~~~~~~ Igor, I will fix this up for you. But it is clear that this patch wasn't tested very well. Because !adapter->netdev->features evaluates wholly before the "& NETIF_F_LRO", the flags aren't being tested properly at all.
The 03/20/2018 10:57, David Miller wrote: > From: kbuild test robot <lkp@intel.com> > Date: Sun, 18 Mar 2018 14:37:35 +0800 > > > All warnings (new ones prefixed by >>): > > > > drivers/net/vmxnet3/vmxnet3_drv.c: In function 'vmxnet3_rq_rx_complete': > >>> drivers/net/vmxnet3/vmxnet3_drv.c:1474:8: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses] > > !adapter->netdev->features & NETIF_F_LRO) { > > ^~~~~~~~~~~~~~~~~~~~~~~~~~ > > Igor, I will fix this up for you. But it is clear that this patch wasn't tested > very well. > > Because !adapter->netdev->features evaluates wholly before the "& NETIF_F_LRO", > the flags aren't being tested properly at all. My bad. I have even been looking at C operator precedence table: ---------------------------- | Operator | Associativity | |--------------------------| | ++ -- | right-to-left | | + - | | | ! ~ | | | (type) | | | * | | | & | | | sizeof | | ---------------------------- According to this table '&' will be evaluated first, because it is on the right side. But yeah, that was "Address of", not "Bitwise AND".
On Tue, 20 Mar 2018, David Miller wrote: > From: kbuild test robot <lkp@intel.com> > Date: Sun, 18 Mar 2018 14:37:35 +0800 > > > All warnings (new ones prefixed by >>): > > > > drivers/net/vmxnet3/vmxnet3_drv.c: In function 'vmxnet3_rq_rx_complete': > >>> drivers/net/vmxnet3/vmxnet3_drv.c:1474:8: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses] > > !adapter->netdev->features & NETIF_F_LRO) { > > ^~~~~~~~~~~~~~~~~~~~~~~~~~ > > Igor, I will fix this up for you. But it is clear that this patch wasn't tested > very well. > > Because !adapter->netdev->features evaluates wholly before the "& NETIF_F_LRO", > the flags aren't being tested properly at all. Ronak's patch that fixes this issue has the right code, and is already accepted in net tree (Commit: 034f405793897a3c8f642935f5494b86c340cde7). We no longer need Igor's patch. Thanks, Shri
From: Shrikrishna Khare <skhare@shri-linux.eng.vmware.com> Date: Tue, 20 Mar 2018 11:42:47 -0700 > Ronak's patch that fixes this issue has the right code, and is already > accepted in net tree (Commit: 034f405793897a3c8f642935f5494b86c340cde7). > We no longer need Igor's patch. That explains why things in my actual tree are fine. Thanks.
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 8b39c160743d..60776c86aaaf 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1470,8 +1470,10 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, vmxnet3_rx_csum(adapter, skb, (union Vmxnet3_GenericDesc *)rcd); skb->protocol = eth_type_trans(skb, adapter->netdev); - if (!rcd->tcp || !adapter->lro) + if (!rcd->tcp || + !adapter->netdev->features & NETIF_F_LRO) { goto not_lro; + } if (segCnt != 0 && mss != 0) { skb_shinfo(skb)->gso_type = rcd->v4 ? diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 5ba222920e80..3de4cecda35a 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -342,9 +342,6 @@ struct vmxnet3_adapter { u8 __iomem *hw_addr1; /* for BAR 1 */ u8 version; - bool rxcsum; - bool lro; - #ifdef VMXNET3_RSS struct UPT1_RSSConf *rss_conf; bool rss;
rxcsum and lro fields were deleted in commit a0d2730c9571 ("net: vmxnet3: convert to hw_features"). With upgrading to newer version those fields were resurrected and new code started using uninitialized lro field. Removing rxcsum and lro fields. Fixes: 45dac1d6ea04 ("vmxnet3: Changes for vmxnet3 adapter version 2 (fwd)") Signed-off-by: Igor Pylypiv <ipylypiv@silver-peak.com> --- drivers/net/vmxnet3/vmxnet3_drv.c | 4 +++- drivers/net/vmxnet3/vmxnet3_int.h | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-)