@@ -1098,13 +1098,47 @@ hn_detach(struct hn_data *hv)
10981098 hn_rndis_detach (hv );
10991099}
11001100
1101+ /*
1102+ * Connects EXISTING rx/tx queues to NEW vmbus channel(s), and
1103+ * re-initializes NDIS and RNDIS, including re-sending initial
1104+ * NDIS/RNDIS configuration. To be used after the underlying vmbus
1105+ * has been un- and re-mapped, e.g. as must happen when the device
1106+ * MTU is changed.
1107+ */
11011108static int
1102- hn_dev_mtu_set (struct rte_eth_dev * dev , uint16_t mtu )
1109+ hn_reinit (struct rte_eth_dev * dev , uint16_t mtu )
11031110{
11041111 struct hn_data * hv = dev -> data -> dev_private ;
11051112 struct hn_rx_queue * * rxqs = (struct hn_rx_queue * * )dev -> data -> rx_queues ;
11061113 struct hn_tx_queue * * txqs = (struct hn_tx_queue * * )dev -> data -> tx_queues ;
1107- struct rte_eth_dev * vf_dev ;
1114+ int i , ret = 0 ;
1115+
1116+ /* Point primary queues at new primary channel */
1117+ rxqs [0 ]-> chan = hv -> channels [0 ];
1118+ txqs [0 ]-> chan = hv -> channels [0 ];
1119+
1120+ ret = hn_attach (hv , mtu );
1121+ if (ret )
1122+ return ret ;
1123+
1124+ /* Create vmbus subchannels, additional RNDIS configuration */
1125+ ret = hn_dev_configure (dev );
1126+ if (ret )
1127+ return ret ;
1128+
1129+ /* Point any additional queues at new subchannels */
1130+ for (i = 1 ; i < dev -> data -> nb_rx_queues ; i ++ )
1131+ rxqs [i ]-> chan = hv -> channels [i ];
1132+ for (i = 1 ; i < dev -> data -> nb_tx_queues ; i ++ )
1133+ txqs [i ]-> chan = hv -> channels [i ];
1134+
1135+ return ret ;
1136+ }
1137+
1138+ static int
1139+ hn_dev_mtu_set (struct rte_eth_dev * dev , uint16_t mtu )
1140+ {
1141+ struct hn_data * hv = dev -> data -> dev_private ;
11081142 unsigned int orig_mtu = dev -> data -> mtu ;
11091143 uint32_t rndis_mtu ;
11101144 int ret = 0 ;
@@ -1115,25 +1149,21 @@ hn_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
11151149 return - EIO ;
11161150 }
11171151
1118- /* Change MTU of underlying VF netdev first, if it exists */
1119- rte_rwlock_read_lock (& hv -> vf_lock );
1120- vf_dev = hn_get_vf_dev (hv );
1121- if (hv -> vf_ctx .vf_vsc_switched && vf_dev ) {
1122- ret = vf_dev -> dev_ops -> mtu_set (vf_dev , mtu );
1123- if (ret ) {
1124- rte_rwlock_read_unlock (& hv -> vf_lock );
1125- goto out ;
1126- }
1127- }
1128- rte_rwlock_read_unlock (& hv -> vf_lock );
1152+ /* Change MTU of underlying VF dev first, if it exists */
1153+ ret = hn_vf_mtu_set (dev , mtu );
1154+ if (ret )
1155+ return ret ;
11291156
11301157 /* Release channel resources */
11311158 hn_detach (hv );
11321159
1133- /* Close vmbus channels */
1134- for (i = 0 ; i < hv -> num_queues ; i ++ )
1160+ /* Close any secondary vmbus channels */
1161+ for (i = 1 ; i < hv -> num_queues ; i ++ )
11351162 rte_vmbus_chan_close (hv -> channels [i ]);
11361163
1164+ /* Close primary vmbus channel */
1165+ rte_free (hv -> channels [0 ]);
1166+
11371167 /* Unmap and re-map vmbus device */
11381168 rte_vmbus_unmap_device (hv -> vmbus );
11391169 ret = rte_vmbus_map_device (hv -> vmbus );
@@ -1147,33 +1177,28 @@ hn_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
11471177 hv -> rxbuf_res = hv -> vmbus -> resource [HV_RECV_BUF_MAP ];
11481178 hv -> chim_res = hv -> vmbus -> resource [HV_SEND_BUF_MAP ];
11491179
1150- /* Re-open the vmbus channel */
1180+ /* Re-open the primary vmbus channel */
11511181 ret = rte_vmbus_chan_open (hv -> vmbus , & hv -> channels [0 ]);
11521182 if (ret ) {
11531183 /* This is a catastrophic error - the device is unusable */
11541184 PMD_DRV_LOG (ERR , "Could not re-open vmbus channel!" );
1185+ return ret ;
11551186 }
11561187
11571188 rte_vmbus_set_latency (hv -> vmbus , hv -> channels [0 ], hv -> latency );
11581189
1159- /* Point primary queues at new primary channel */
1160- rxqs [ 0 ] -> chan = hv -> channels [ 0 ];
1161- txqs [ 0 ] -> chan = hv -> channels [ 0 ] ;
1190+ ret = hn_reinit ( dev , mtu );
1191+ if (! ret )
1192+ goto out ;
11621193
1163- ret = hn_attach (hv , mtu );
1194+ /* In case of error, attempt to restore original MTU */
1195+ ret = hn_reinit (dev , orig_mtu );
11641196 if (ret )
1165- goto error ;
1197+ PMD_DRV_LOG ( ERR , "Restoring original MTU failed for netvsc" ) ;
11661198
1167- /* Create vmbus subchannels, additional RNDIS configuration */
1168- ret = hn_dev_configure (dev );
1199+ ret = hn_vf_mtu_set (dev , orig_mtu );
11691200 if (ret )
1170- goto error ;
1171-
1172- /* Point any additional queues at new subchannels */
1173- for (i = 1 ; i < dev -> data -> nb_rx_queues ; i ++ )
1174- rxqs [i ]-> chan = hv -> channels [i ];
1175- for (i = 1 ; i < dev -> data -> nb_tx_queues ; i ++ )
1176- txqs [i ]-> chan = hv -> channels [i ];
1201+ PMD_DRV_LOG (ERR , "Restoring original MTU failed for VF" );
11771202
11781203out :
11791204 if (hn_rndis_get_mtu (hv , & rndis_mtu ))
@@ -1183,19 +1208,6 @@ hn_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
11831208 PMD_DRV_LOG (DEBUG , "RNDIS MTU is %u" , dev -> data -> mtu );
11841209 }
11851210
1186- return ret ;
1187-
1188- error :
1189- /* In case of error, attempt to restore original MTU */
1190- if (hn_attach (hv , orig_mtu ))
1191- PMD_DRV_LOG (ERR , "Restoring original MTU failed" );
1192-
1193- rte_rwlock_read_lock (& hv -> vf_lock );
1194- vf_dev = hn_get_vf_dev (hv );
1195- if (hv -> vf_ctx .vf_vsc_switched && vf_dev )
1196- vf_dev -> dev_ops -> mtu_set (vf_dev , orig_mtu );
1197- rte_rwlock_read_unlock (& hv -> vf_lock );
1198-
11991211 return ret ;
12001212}
12011213
0 commit comments