@@ -1430,6 +1430,15 @@ static int __ibmvnic_open(struct net_device *netdev)
14301430 return rc ;
14311431 }
14321432
1433+ adapter -> tx_queues_active = true;
1434+
1435+ /* Since queues were stopped until now, there shouldn't be any
1436+ * one in ibmvnic_complete_tx() or ibmvnic_xmit() so maybe we
1437+ * don't need the synchronize_rcu()? Leaving it for consistency
1438+ * with setting ->tx_queues_active = false.
1439+ */
1440+ synchronize_rcu ();
1441+
14331442 netif_tx_start_all_queues (netdev );
14341443
14351444 if (prev_state == VNIC_CLOSED ) {
@@ -1604,6 +1613,14 @@ static void ibmvnic_cleanup(struct net_device *netdev)
16041613 struct ibmvnic_adapter * adapter = netdev_priv (netdev );
16051614
16061615 /* ensure that transmissions are stopped if called by do_reset */
1616+
1617+ adapter -> tx_queues_active = false;
1618+
1619+ /* Ensure complete_tx() and ibmvnic_xmit() see ->tx_queues_active
1620+ * update so they don't restart a queue after we stop it below.
1621+ */
1622+ synchronize_rcu ();
1623+
16071624 if (test_bit (0 , & adapter -> resetting ))
16081625 netif_tx_disable (netdev );
16091626 else
@@ -1843,14 +1860,21 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter,
18431860 tx_buff -> skb = NULL ;
18441861 adapter -> netdev -> stats .tx_dropped ++ ;
18451862 }
1863+
18461864 ind_bufp -> index = 0 ;
1865+
18471866 if (atomic_sub_return (entries , & tx_scrq -> used ) <=
18481867 (adapter -> req_tx_entries_per_subcrq / 2 ) &&
1849- __netif_subqueue_stopped (adapter -> netdev , queue_num ) &&
1850- !test_bit (0 , & adapter -> resetting )) {
1851- netif_wake_subqueue (adapter -> netdev , queue_num );
1852- netdev_dbg (adapter -> netdev , "Started queue %d\n" ,
1853- queue_num );
1868+ __netif_subqueue_stopped (adapter -> netdev , queue_num )) {
1869+ rcu_read_lock ();
1870+
1871+ if (adapter -> tx_queues_active ) {
1872+ netif_wake_subqueue (adapter -> netdev , queue_num );
1873+ netdev_dbg (adapter -> netdev , "Started queue %d\n" ,
1874+ queue_num );
1875+ }
1876+
1877+ rcu_read_unlock ();
18541878 }
18551879}
18561880
@@ -1905,11 +1929,12 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
19051929 int index = 0 ;
19061930 u8 proto = 0 ;
19071931
1908- tx_scrq = adapter -> tx_scrq [queue_num ];
1909- txq = netdev_get_tx_queue (netdev , queue_num );
1910- ind_bufp = & tx_scrq -> ind_buf ;
1911-
1912- if (test_bit (0 , & adapter -> resetting )) {
1932+ /* If a reset is in progress, drop the packet since
1933+ * the scrqs may get torn down. Otherwise use the
1934+ * rcu to ensure reset waits for us to complete.
1935+ */
1936+ rcu_read_lock ();
1937+ if (!adapter -> tx_queues_active ) {
19131938 dev_kfree_skb_any (skb );
19141939
19151940 tx_send_failed ++ ;
@@ -1918,13 +1943,18 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
19181943 goto out ;
19191944 }
19201945
1946+ tx_scrq = adapter -> tx_scrq [queue_num ];
1947+ txq = netdev_get_tx_queue (netdev , queue_num );
1948+ ind_bufp = & tx_scrq -> ind_buf ;
1949+
19211950 if (ibmvnic_xmit_workarounds (skb , netdev )) {
19221951 tx_dropped ++ ;
19231952 tx_send_failed ++ ;
19241953 ret = NETDEV_TX_OK ;
19251954 ibmvnic_tx_scrq_flush (adapter , tx_scrq );
19261955 goto out ;
19271956 }
1957+
19281958 if (skb_is_gso (skb ))
19291959 tx_pool = & adapter -> tso_pool [queue_num ];
19301960 else
@@ -2079,6 +2109,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
20792109 netif_carrier_off (netdev );
20802110 }
20812111out :
2112+ rcu_read_unlock ();
20822113 netdev -> stats .tx_dropped += tx_dropped ;
20832114 netdev -> stats .tx_bytes += tx_bytes ;
20842115 netdev -> stats .tx_packets += tx_packets ;
@@ -3749,9 +3780,15 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
37493780 (adapter -> req_tx_entries_per_subcrq / 2 ) &&
37503781 __netif_subqueue_stopped (adapter -> netdev ,
37513782 scrq -> pool_index )) {
3752- netif_wake_subqueue (adapter -> netdev , scrq -> pool_index );
3753- netdev_dbg (adapter -> netdev , "Started queue %d\n" ,
3754- scrq -> pool_index );
3783+ rcu_read_lock ();
3784+ if (adapter -> tx_queues_active ) {
3785+ netif_wake_subqueue (adapter -> netdev ,
3786+ scrq -> pool_index );
3787+ netdev_dbg (adapter -> netdev ,
3788+ "Started queue %d\n" ,
3789+ scrq -> pool_index );
3790+ }
3791+ rcu_read_unlock ();
37553792 }
37563793 }
37573794
0 commit comments