@@ -154,13 +154,14 @@ enum {
154
154
*/
155
155
RX_COPY_THRES = 256 ,
156
156
RX_PULL_LEN = 128 ,
157
- };
158
157
159
- /*
160
- * Can't define this in the above enum because PKTSHIFT isn't a constant in
161
- * the VF Driver ...
162
- */
163
- #define RX_PKT_PULL_LEN (RX_PULL_LEN + PKTSHIFT)
158
+ /*
159
+ * Main body length for sk_buffs used for RX Ethernet packets with
160
+ * fragments. Should be >= RX_PULL_LEN but possibly bigger to give
161
+ * pskb_may_pull() some room.
162
+ */
163
+ RX_SKB_LEN = 512 ,
164
+ };
164
165
165
166
/*
166
167
* Software state per TX descriptor.
@@ -1354,6 +1355,67 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev)
1354
1355
return NETDEV_TX_OK ;
1355
1356
}
1356
1357
1358
+ /**
1359
+ * t4vf_pktgl_to_skb - build an sk_buff from a packet gather list
1360
+ * @gl: the gather list
1361
+ * @skb_len: size of sk_buff main body if it carries fragments
1362
+ * @pull_len: amount of data to move to the sk_buff's main body
1363
+ *
1364
+ * Builds an sk_buff from the given packet gather list. Returns the
1365
+ * sk_buff or %NULL if sk_buff allocation failed.
1366
+ */
1367
+ struct sk_buff * t4vf_pktgl_to_skb (const struct pkt_gl * gl ,
1368
+ unsigned int skb_len , unsigned int pull_len )
1369
+ {
1370
+ struct sk_buff * skb ;
1371
+ struct skb_shared_info * ssi ;
1372
+
1373
+ /*
1374
+ * If the ingress packet is small enough, allocate an skb large enough
1375
+ * for all of the data and copy it inline. Otherwise, allocate an skb
1376
+ * with enough room to pull in the header and reference the rest of
1377
+ * the data via the skb fragment list.
1378
+ *
1379
+ * Below we rely on RX_COPY_THRES being less than the smallest Rx
1380
+ * buff! size, which is expected since buffers are at least
1381
+ * PAGE_SIZEd. In this case packets up to RX_COPY_THRES have only one
1382
+ * fragment.
1383
+ */
1384
+ if (gl -> tot_len <= RX_COPY_THRES ) {
1385
+ /* small packets have only one fragment */
1386
+ skb = alloc_skb (gl -> tot_len , GFP_ATOMIC );
1387
+ if (unlikely (!skb ))
1388
+ goto out ;
1389
+ __skb_put (skb , gl -> tot_len );
1390
+ skb_copy_to_linear_data (skb , gl -> va , gl -> tot_len );
1391
+ } else {
1392
+ skb = alloc_skb (skb_len , GFP_ATOMIC );
1393
+ if (unlikely (!skb ))
1394
+ goto out ;
1395
+ __skb_put (skb , pull_len );
1396
+ skb_copy_to_linear_data (skb , gl -> va , pull_len );
1397
+
1398
+ ssi = skb_shinfo (skb );
1399
+ ssi -> frags [0 ].page = gl -> frags [0 ].page ;
1400
+ ssi -> frags [0 ].page_offset = gl -> frags [0 ].page_offset + pull_len ;
1401
+ ssi -> frags [0 ].size = gl -> frags [0 ].size - pull_len ;
1402
+ if (gl -> nfrags > 1 )
1403
+ memcpy (& ssi -> frags [1 ], & gl -> frags [1 ],
1404
+ (gl -> nfrags - 1 ) * sizeof (skb_frag_t ));
1405
+ ssi -> nr_frags = gl -> nfrags ;
1406
+
1407
+ skb -> len = gl -> tot_len ;
1408
+ skb -> data_len = skb -> len - pull_len ;
1409
+ skb -> truesize += skb -> data_len ;
1410
+
1411
+ /* Get a reference for the last page, we don't own it */
1412
+ get_page (gl -> frags [gl -> nfrags - 1 ].page );
1413
+ }
1414
+
1415
+ out :
1416
+ return skb ;
1417
+ }
1418
+
1357
1419
/**
1358
1420
* t4vf_pktgl_free - free a packet gather list
1359
1421
* @gl: the gather list
@@ -1463,10 +1525,8 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
1463
1525
{
1464
1526
struct sk_buff * skb ;
1465
1527
struct port_info * pi ;
1466
- struct skb_shared_info * ssi ;
1467
1528
const struct cpl_rx_pkt * pkt = (void * )& rsp [1 ];
1468
1529
bool csum_ok = pkt -> csum_calc && !pkt -> err_vec ;
1469
- unsigned int len = be16_to_cpu (pkt -> len );
1470
1530
struct sge_eth_rxq * rxq = container_of (rspq , struct sge_eth_rxq , rspq );
1471
1531
1472
1532
/*
@@ -1481,42 +1541,14 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
1481
1541
}
1482
1542
1483
1543
/*
1484
- * If the ingress packet is small enough, allocate an skb large enough
1485
- * for all of the data and copy it inline. Otherwise, allocate an skb
1486
- * with enough room to pull in the header and reference the rest of
1487
- * the data via the skb fragment list.
1544
+ * Convert the Packet Gather List into an skb.
1488
1545
*/
1489
- if (len <= RX_COPY_THRES ) {
1490
- /* small packets have only one fragment */
1491
- skb = alloc_skb (gl -> frags [0 ].size , GFP_ATOMIC );
1492
- if (!skb )
1493
- goto nomem ;
1494
- __skb_put (skb , gl -> frags [0 ].size );
1495
- skb_copy_to_linear_data (skb , gl -> va , gl -> frags [0 ].size );
1496
- } else {
1497
- skb = alloc_skb (RX_PKT_PULL_LEN , GFP_ATOMIC );
1498
- if (!skb )
1499
- goto nomem ;
1500
- __skb_put (skb , RX_PKT_PULL_LEN );
1501
- skb_copy_to_linear_data (skb , gl -> va , RX_PKT_PULL_LEN );
1502
-
1503
- ssi = skb_shinfo (skb );
1504
- ssi -> frags [0 ].page = gl -> frags [0 ].page ;
1505
- ssi -> frags [0 ].page_offset = (gl -> frags [0 ].page_offset +
1506
- RX_PKT_PULL_LEN );
1507
- ssi -> frags [0 ].size = gl -> frags [0 ].size - RX_PKT_PULL_LEN ;
1508
- if (gl -> nfrags > 1 )
1509
- memcpy (& ssi -> frags [1 ], & gl -> frags [1 ],
1510
- (gl -> nfrags - 1 ) * sizeof (skb_frag_t ));
1511
- ssi -> nr_frags = gl -> nfrags ;
1512
- skb -> len = len + PKTSHIFT ;
1513
- skb -> data_len = skb -> len - RX_PKT_PULL_LEN ;
1514
- skb -> truesize += skb -> data_len ;
1515
-
1516
- /* Get a reference for the last page, we don't own it */
1517
- get_page (gl -> frags [gl -> nfrags - 1 ].page );
1546
+ skb = t4vf_pktgl_to_skb (gl , RX_SKB_LEN , RX_PULL_LEN );
1547
+ if (unlikely (!skb )) {
1548
+ t4vf_pktgl_free (gl );
1549
+ rxq -> stats .rx_drops ++ ;
1550
+ return 0 ;
1518
1551
}
1519
-
1520
1552
__skb_pull (skb , PKTSHIFT );
1521
1553
skb -> protocol = eth_type_trans (skb , rspq -> netdev );
1522
1554
skb_record_rx_queue (skb , rspq -> idx );
@@ -1549,11 +1581,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
1549
1581
netif_receive_skb (skb );
1550
1582
1551
1583
return 0 ;
1552
-
1553
- nomem :
1554
- t4vf_pktgl_free (gl );
1555
- rxq -> stats .rx_drops ++ ;
1556
- return 0 ;
1557
1584
}
1558
1585
1559
1586
/**
0 commit comments