Skip to content

Commit a116f4e

Browse files
committed
Merge branch 'hns3-fixes'
Huazhong Tan says: ==================== net: hns3: fixes for -net This patchset includes misc fixes for the HNS3 ethernet driver. [patch 1/3] fixes a TX queue not restarted problem. [patch 2/3] fixes a use-after-free issue. [patch 3/3] fixes a VF ID issue for setting VF VLAN. change log: V1->V2: keeps 'ring' as parameter in hns3_nic_maybe_stop_tx() in [patch 1/3], suggestted by David. rewrites [patch 2/3]'s commit log to make it be easier to understand, suggestted by David. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents aacf657 + 1c98550 commit a116f4e

File tree

2 files changed

+32
-36
lines changed

2 files changed

+32
-36
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3_enet.c

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,30 +1287,25 @@ static bool hns3_skb_need_linearized(struct sk_buff *skb, unsigned int *bd_size,
12871287
}
12881288

12891289
static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
1290-
struct sk_buff **out_skb)
1290+
struct net_device *netdev,
1291+
struct sk_buff *skb)
12911292
{
1293+
struct hns3_nic_priv *priv = netdev_priv(netdev);
12921294
unsigned int bd_size[HNS3_MAX_TSO_BD_NUM + 1U];
1293-
struct sk_buff *skb = *out_skb;
12941295
unsigned int bd_num;
12951296

12961297
bd_num = hns3_tx_bd_num(skb, bd_size);
12971298
if (unlikely(bd_num > HNS3_MAX_NON_TSO_BD_NUM)) {
1298-
struct sk_buff *new_skb;
1299-
13001299
if (bd_num <= HNS3_MAX_TSO_BD_NUM && skb_is_gso(skb) &&
13011300
!hns3_skb_need_linearized(skb, bd_size, bd_num))
13021301
goto out;
13031302

1304-
/* manual split the send packet */
1305-
new_skb = skb_copy(skb, GFP_ATOMIC);
1306-
if (!new_skb)
1303+
if (__skb_linearize(skb))
13071304
return -ENOMEM;
1308-
dev_kfree_skb_any(skb);
1309-
*out_skb = new_skb;
13101305

1311-
bd_num = hns3_tx_bd_count(new_skb->len);
1312-
if ((skb_is_gso(new_skb) && bd_num > HNS3_MAX_TSO_BD_NUM) ||
1313-
(!skb_is_gso(new_skb) &&
1306+
bd_num = hns3_tx_bd_count(skb->len);
1307+
if ((skb_is_gso(skb) && bd_num > HNS3_MAX_TSO_BD_NUM) ||
1308+
(!skb_is_gso(skb) &&
13141309
bd_num > HNS3_MAX_NON_TSO_BD_NUM))
13151310
return -ENOMEM;
13161311

@@ -1320,10 +1315,23 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
13201315
}
13211316

13221317
out:
1323-
if (unlikely(ring_space(ring) < bd_num))
1324-
return -EBUSY;
1318+
if (likely(ring_space(ring) >= bd_num))
1319+
return bd_num;
13251320

1326-
return bd_num;
1321+
netif_stop_subqueue(netdev, ring->queue_index);
1322+
smp_mb(); /* Memory barrier before checking ring_space */
1323+
1324+
/* Start queue in case hns3_clean_tx_ring has just made room
1325+
* available and has not seen the queue stopped state performed
1326+
* by netif_stop_subqueue above.
1327+
*/
1328+
if (ring_space(ring) >= bd_num && netif_carrier_ok(netdev) &&
1329+
!test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) {
1330+
netif_start_subqueue(netdev, ring->queue_index);
1331+
return bd_num;
1332+
}
1333+
1334+
return -EBUSY;
13271335
}
13281336

13291337
static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
@@ -1400,13 +1408,13 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
14001408
/* Prefetch the data used later */
14011409
prefetch(skb->data);
14021410

1403-
ret = hns3_nic_maybe_stop_tx(ring, &skb);
1411+
ret = hns3_nic_maybe_stop_tx(ring, netdev, skb);
14041412
if (unlikely(ret <= 0)) {
14051413
if (ret == -EBUSY) {
14061414
u64_stats_update_begin(&ring->syncp);
14071415
ring->stats.tx_busy++;
14081416
u64_stats_update_end(&ring->syncp);
1409-
goto out_net_tx_busy;
1417+
return NETDEV_TX_BUSY;
14101418
} else if (ret == -ENOMEM) {
14111419
u64_stats_update_begin(&ring->syncp);
14121420
ring->stats.sw_err_cnt++;
@@ -1457,12 +1465,6 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
14571465
out_err_tx_ok:
14581466
dev_kfree_skb_any(skb);
14591467
return NETDEV_TX_OK;
1460-
1461-
out_net_tx_busy:
1462-
netif_stop_subqueue(netdev, ring->queue_index);
1463-
smp_mb(); /* Commit all data before submit */
1464-
1465-
return NETDEV_TX_BUSY;
14661468
}
14671469

14681470
static int hns3_nic_net_set_mac_address(struct net_device *netdev, void *p)
@@ -2519,7 +2521,7 @@ void hns3_clean_tx_ring(struct hns3_enet_ring *ring)
25192521
dev_queue = netdev_get_tx_queue(netdev, ring->tqp->tqp_index);
25202522
netdev_tx_completed_queue(dev_queue, pkts, bytes);
25212523

2522-
if (unlikely(pkts && netif_carrier_ok(netdev) &&
2524+
if (unlikely(netif_carrier_ok(netdev) &&
25232525
ring_space(ring) > HNS3_MAX_TSO_BD_NUM)) {
25242526
/* Make sure that anybody stopping the queue after this
25252527
* sees the new next_to_clean.

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8438,13 +8438,16 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
84388438
if (hdev->pdev->revision == 0x20)
84398439
return -EOPNOTSUPP;
84408440

8441+
vport = hclge_get_vf_vport(hdev, vfid);
8442+
if (!vport)
8443+
return -EINVAL;
8444+
84418445
/* qos is a 3 bits value, so can not be bigger than 7 */
8442-
if (vfid >= hdev->num_alloc_vfs || vlan > VLAN_N_VID - 1 || qos > 7)
8446+
if (vlan > VLAN_N_VID - 1 || qos > 7)
84438447
return -EINVAL;
84448448
if (proto != htons(ETH_P_8021Q))
84458449
return -EPROTONOSUPPORT;
84468450

8447-
vport = &hdev->vport[vfid];
84488451
state = hclge_get_port_base_vlan_state(vport,
84498452
vport->port_base_vlan_cfg.state,
84508453
vlan);
@@ -8455,21 +8458,12 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
84558458
vlan_info.qos = qos;
84568459
vlan_info.vlan_proto = ntohs(proto);
84578460

8458-
/* update port based VLAN for PF */
8459-
if (!vfid) {
8460-
hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
8461-
ret = hclge_update_port_base_vlan_cfg(vport, state, &vlan_info);
8462-
hclge_notify_client(hdev, HNAE3_UP_CLIENT);
8463-
8464-
return ret;
8465-
}
8466-
84678461
if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) {
84688462
return hclge_update_port_base_vlan_cfg(vport, state,
84698463
&vlan_info);
84708464
} else {
84718465
ret = hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
8472-
(u8)vfid, state,
8466+
vport->vport_id, state,
84738467
vlan, qos,
84748468
ntohs(proto));
84758469
return ret;

0 commit comments

Comments
 (0)