@@ -1098,13 +1098,47 @@ hn_detach(struct hn_data *hv)
1098
1098
hn_rndis_detach (hv );
1099
1099
}
1100
1100
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
+ */
1101
1108
static 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 )
1103
1110
{
1104
1111
struct hn_data * hv = dev -> data -> dev_private ;
1105
1112
struct hn_rx_queue * * rxqs = (struct hn_rx_queue * * )dev -> data -> rx_queues ;
1106
1113
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 ;
1108
1142
unsigned int orig_mtu = dev -> data -> mtu ;
1109
1143
uint32_t rndis_mtu ;
1110
1144
int ret = 0 ;
@@ -1115,25 +1149,21 @@ hn_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
1115
1149
return - EIO ;
1116
1150
}
1117
1151
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 ;
1129
1156
1130
1157
/* Release channel resources */
1131
1158
hn_detach (hv );
1132
1159
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 ++ )
1135
1162
rte_vmbus_chan_close (hv -> channels [i ]);
1136
1163
1164
+ /* Close primary vmbus channel */
1165
+ rte_free (hv -> channels [0 ]);
1166
+
1137
1167
/* Unmap and re-map vmbus device */
1138
1168
rte_vmbus_unmap_device (hv -> vmbus );
1139
1169
ret = rte_vmbus_map_device (hv -> vmbus );
@@ -1147,33 +1177,28 @@ hn_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
1147
1177
hv -> rxbuf_res = hv -> vmbus -> resource [HV_RECV_BUF_MAP ];
1148
1178
hv -> chim_res = hv -> vmbus -> resource [HV_SEND_BUF_MAP ];
1149
1179
1150
- /* Re-open the vmbus channel */
1180
+ /* Re-open the primary vmbus channel */
1151
1181
ret = rte_vmbus_chan_open (hv -> vmbus , & hv -> channels [0 ]);
1152
1182
if (ret ) {
1153
1183
/* This is a catastrophic error - the device is unusable */
1154
1184
PMD_DRV_LOG (ERR , "Could not re-open vmbus channel!" );
1185
+ return ret ;
1155
1186
}
1156
1187
1157
1188
rte_vmbus_set_latency (hv -> vmbus , hv -> channels [0 ], hv -> latency );
1158
1189
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 ;
1162
1193
1163
- ret = hn_attach (hv , mtu );
1194
+ /* In case of error, attempt to restore original MTU */
1195
+ ret = hn_reinit (dev , orig_mtu );
1164
1196
if (ret )
1165
- goto error ;
1197
+ PMD_DRV_LOG ( ERR , "Restoring original MTU failed for netvsc" ) ;
1166
1198
1167
- /* Create vmbus subchannels, additional RNDIS configuration */
1168
- ret = hn_dev_configure (dev );
1199
+ ret = hn_vf_mtu_set (dev , orig_mtu );
1169
1200
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" );
1177
1202
1178
1203
out :
1179
1204
if (hn_rndis_get_mtu (hv , & rndis_mtu ))
@@ -1183,19 +1208,6 @@ hn_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
1183
1208
PMD_DRV_LOG (DEBUG , "RNDIS MTU is %u" , dev -> data -> mtu );
1184
1209
}
1185
1210
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
-
1199
1211
return ret ;
1200
1212
}
1201
1213
0 commit comments