Skip to content

Commit dfbfe8d

Browse files
author
Ubuntu
committed
Refactor re-initialization after un/re-mapping vmbus channels into separate function. Move VF MTU change into separate function. Ensure that subchannels are reconnected if rolling back to original MTU.
1 parent 96c5772 commit dfbfe8d

File tree

3 files changed

+71
-43
lines changed

3 files changed

+71
-43
lines changed

drivers/net/netvsc/hn_ethdev.c

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
*/
11011108
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)
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

11781203
out:
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

drivers/net/netvsc/hn_var.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ int hn_vf_rss_hash_update(struct rte_eth_dev *dev,
287287
int hn_vf_reta_hash_update(struct rte_eth_dev *dev,
288288
struct rte_eth_rss_reta_entry64 *reta_conf,
289289
uint16_t reta_size);
290+
int hn_vf_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
290291
int hn_eth_rmv_event_callback(uint16_t port_id,
291292
enum rte_eth_event_type event __rte_unused,
292293
void *cb_arg, void *out __rte_unused);

drivers/net/netvsc/hn_vf.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,3 +778,18 @@ int hn_vf_reta_hash_update(struct rte_eth_dev *dev,
778778

779779
return ret;
780780
}
781+
782+
int hn_vf_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
783+
{
784+
struct hn_data *hv = dev->data->dev_private;
785+
struct rte_eth_dev *vf_dev;
786+
int ret = 0;
787+
788+
rte_rwlock_read_lock(&hv->vf_lock);
789+
vf_dev = hn_get_vf_dev(hv);
790+
if (hv->vf_ctx.vf_vsc_switched && vf_dev)
791+
ret = vf_dev->dev_ops->mtu_set(vf_dev, mtu);
792+
rte_rwlock_read_unlock(&hv->vf_lock);
793+
794+
return ret;
795+
}

0 commit comments

Comments
 (0)