@@ -1039,21 +1039,95 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
1039
1039
1040
1040
/* Set the channel before opening.*/
1041
1041
nvchan -> channel = new_sc ;
1042
- netif_napi_add (ndev , & nvchan -> napi ,
1043
- netvsc_poll , NAPI_POLL_WEIGHT );
1044
1042
1045
1043
ret = vmbus_open (new_sc , nvscdev -> ring_size * PAGE_SIZE ,
1046
1044
nvscdev -> ring_size * PAGE_SIZE , NULL , 0 ,
1047
1045
netvsc_channel_cb , nvchan );
1048
1046
if (ret == 0 )
1049
1047
napi_enable (& nvchan -> napi );
1050
1048
else
1051
- netif_napi_del ( & nvchan -> napi );
1049
+ netdev_notice ( ndev , "sub channel open failed: %d\n" , ret );
1052
1050
1053
1051
atomic_inc (& nvscdev -> open_chn );
1054
1052
wake_up (& nvscdev -> subchan_open );
1055
1053
}
1056
1054
1055
+ /* Open sub-channels after completing the handling of the device probe.
1056
+ * This breaks overlap of processing the host message for the
1057
+ * new primary channel with the initialization of sub-channels.
1058
+ */
1059
+ void rndis_set_subchannel (struct work_struct * w )
1060
+ {
1061
+ struct netvsc_device * nvdev
1062
+ = container_of (w , struct netvsc_device , subchan_work );
1063
+ struct nvsp_message * init_packet = & nvdev -> channel_init_pkt ;
1064
+ struct net_device_context * ndev_ctx ;
1065
+ struct rndis_device * rdev ;
1066
+ struct net_device * ndev ;
1067
+ struct hv_device * hv_dev ;
1068
+ int i , ret ;
1069
+
1070
+ if (!rtnl_trylock ()) {
1071
+ schedule_work (w );
1072
+ return ;
1073
+ }
1074
+
1075
+ rdev = nvdev -> extension ;
1076
+ if (!rdev )
1077
+ goto unlock ; /* device was removed */
1078
+
1079
+ ndev = rdev -> ndev ;
1080
+ ndev_ctx = netdev_priv (ndev );
1081
+ hv_dev = ndev_ctx -> device_ctx ;
1082
+
1083
+ memset (init_packet , 0 , sizeof (struct nvsp_message ));
1084
+ init_packet -> hdr .msg_type = NVSP_MSG5_TYPE_SUBCHANNEL ;
1085
+ init_packet -> msg .v5_msg .subchn_req .op = NVSP_SUBCHANNEL_ALLOCATE ;
1086
+ init_packet -> msg .v5_msg .subchn_req .num_subchannels =
1087
+ nvdev -> num_chn - 1 ;
1088
+ ret = vmbus_sendpacket (hv_dev -> channel , init_packet ,
1089
+ sizeof (struct nvsp_message ),
1090
+ (unsigned long )init_packet ,
1091
+ VM_PKT_DATA_INBAND ,
1092
+ VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED );
1093
+ if (ret ) {
1094
+ netdev_err (ndev , "sub channel allocate send failed: %d\n" , ret );
1095
+ goto failed ;
1096
+ }
1097
+
1098
+ wait_for_completion (& nvdev -> channel_init_wait );
1099
+ if (init_packet -> msg .v5_msg .subchn_comp .status != NVSP_STAT_SUCCESS ) {
1100
+ netdev_err (ndev , "sub channel request failed\n" );
1101
+ goto failed ;
1102
+ }
1103
+
1104
+ nvdev -> num_chn = 1 +
1105
+ init_packet -> msg .v5_msg .subchn_comp .num_subchannels ;
1106
+
1107
+ /* wait for all sub channels to open */
1108
+ wait_event (nvdev -> subchan_open ,
1109
+ atomic_read (& nvdev -> open_chn ) == nvdev -> num_chn );
1110
+
1111
+ /* ignore failues from setting rss parameters, still have channels */
1112
+ rndis_filter_set_rss_param (rdev , netvsc_hash_key );
1113
+
1114
+ netif_set_real_num_tx_queues (ndev , nvdev -> num_chn );
1115
+ netif_set_real_num_rx_queues (ndev , nvdev -> num_chn );
1116
+
1117
+ rtnl_unlock ();
1118
+ return ;
1119
+
1120
+ failed :
1121
+ /* fallback to only primary channel */
1122
+ for (i = 1 ; i < nvdev -> num_chn ; i ++ )
1123
+ netif_napi_del (& nvdev -> chan_table [i ].napi );
1124
+
1125
+ nvdev -> max_chn = 1 ;
1126
+ nvdev -> num_chn = 1 ;
1127
+ unlock :
1128
+ rtnl_unlock ();
1129
+ }
1130
+
1057
1131
struct netvsc_device * rndis_filter_device_add (struct hv_device * dev ,
1058
1132
struct netvsc_device_info * device_info )
1059
1133
{
@@ -1063,7 +1137,6 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
1063
1137
struct rndis_device * rndis_device ;
1064
1138
struct ndis_offload hwcaps ;
1065
1139
struct ndis_offload_params offloads ;
1066
- struct nvsp_message * init_packet ;
1067
1140
struct ndis_recv_scale_cap rsscap ;
1068
1141
u32 rsscap_size = sizeof (struct ndis_recv_scale_cap );
1069
1142
unsigned int gso_max_size = GSO_MAX_SIZE ;
@@ -1215,9 +1288,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
1215
1288
net_device -> num_chn );
1216
1289
1217
1290
atomic_set (& net_device -> open_chn , 1 );
1218
-
1219
- if (net_device -> num_chn == 1 )
1220
- return net_device ;
1291
+ vmbus_set_sc_create_callback (dev -> channel , netvsc_sc_open );
1221
1292
1222
1293
for (i = 1 ; i < net_device -> num_chn ; i ++ ) {
1223
1294
ret = netvsc_alloc_recv_comp_ring (net_device , i );
@@ -1228,38 +1299,15 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
1228
1299
}
1229
1300
}
1230
1301
1231
- vmbus_set_sc_create_callback (dev -> channel , netvsc_sc_open );
1302
+ for (i = 1 ; i < net_device -> num_chn ; i ++ )
1303
+ netif_napi_add (net , & net_device -> chan_table [i ].napi ,
1304
+ netvsc_poll , NAPI_POLL_WEIGHT );
1232
1305
1233
- init_packet = & net_device -> channel_init_pkt ;
1234
- memset (init_packet , 0 , sizeof (struct nvsp_message ));
1235
- init_packet -> hdr .msg_type = NVSP_MSG5_TYPE_SUBCHANNEL ;
1236
- init_packet -> msg .v5_msg .subchn_req .op = NVSP_SUBCHANNEL_ALLOCATE ;
1237
- init_packet -> msg .v5_msg .subchn_req .num_subchannels =
1238
- net_device -> num_chn - 1 ;
1239
- ret = vmbus_sendpacket (dev -> channel , init_packet ,
1240
- sizeof (struct nvsp_message ),
1241
- (unsigned long )init_packet ,
1242
- VM_PKT_DATA_INBAND ,
1243
- VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED );
1244
- if (ret )
1245
- goto out ;
1246
-
1247
- wait_for_completion (& net_device -> channel_init_wait );
1248
- if (init_packet -> msg .v5_msg .subchn_comp .status != NVSP_STAT_SUCCESS ) {
1249
- ret = - ENODEV ;
1250
- goto out ;
1251
- }
1306
+ if (net_device -> num_chn > 1 )
1307
+ schedule_work (& net_device -> subchan_work );
1252
1308
1253
- net_device -> num_chn = 1 +
1254
- init_packet -> msg .v5_msg .subchn_comp .num_subchannels ;
1255
-
1256
- /* wait for all sub channels to open */
1257
- wait_event (net_device -> subchan_open ,
1258
- atomic_read (& net_device -> open_chn ) == net_device -> num_chn );
1259
-
1260
- /* ignore failues from setting rss parameters, still have channels */
1261
- rndis_filter_set_rss_param (rndis_device , netvsc_hash_key );
1262
1309
out :
1310
+ /* if unavailable, just proceed with one queue */
1263
1311
if (ret ) {
1264
1312
net_device -> max_chn = 1 ;
1265
1313
net_device -> num_chn = 1 ;
@@ -1280,10 +1328,10 @@ void rndis_filter_device_remove(struct hv_device *dev,
1280
1328
/* Halt and release the rndis device */
1281
1329
rndis_filter_halt_device (rndis_dev );
1282
1330
1283
- kfree (rndis_dev );
1284
1331
net_dev -> extension = NULL ;
1285
1332
1286
1333
netvsc_device_remove (dev );
1334
+ kfree (rndis_dev );
1287
1335
}
1288
1336
1289
1337
int rndis_filter_open (struct netvsc_device * nvdev )
0 commit comments