Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
forked fromtorvalds/linux

Commit02400fc

Browse files
shemmingerdavem330
authored andcommitted
hv_netvsc: use RCU to fix concurrent rx and queue changes
The receive processing may continue to happen while theinternal network device state is in RCU grace period.The internal RNDIS structure is associated with theinternal netvsc_device structure; both have the sameRCU lifetime.Defer freeing all associated parts until after graceperiod.Fixes:0cf7378 ("hv_netvsc: netvsc_teardown_gpadl() split")Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent8348e04 commit02400fc

File tree

2 files changed

+21
-35
lines changed

2 files changed

+21
-35
lines changed

‎drivers/net/hyperv/netvsc.c‎

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ static void free_netvsc_device(struct rcu_head *head)
9090
=container_of(head,structnetvsc_device,rcu);
9191
inti;
9292

93+
kfree(nvdev->extension);
94+
vfree(nvdev->recv_buf);
95+
vfree(nvdev->send_buf);
96+
kfree(nvdev->send_section_map);
97+
9398
for (i=0;i<VRSS_CHANNEL_MAX;i++)
9499
vfree(nvdev->chan_table[i].mrc.slots);
95100

@@ -211,12 +216,6 @@ static void netvsc_teardown_gpadl(struct hv_device *device,
211216
net_device->recv_buf_gpadl_handle=0;
212217
}
213218

214-
if (net_device->recv_buf) {
215-
/* Free up the receive buffer */
216-
vfree(net_device->recv_buf);
217-
net_device->recv_buf=NULL;
218-
}
219-
220219
if (net_device->send_buf_gpadl_handle) {
221220
ret=vmbus_teardown_gpadl(device->channel,
222221
net_device->send_buf_gpadl_handle);
@@ -231,12 +230,6 @@ static void netvsc_teardown_gpadl(struct hv_device *device,
231230
}
232231
net_device->send_buf_gpadl_handle=0;
233232
}
234-
if (net_device->send_buf) {
235-
/* Free up the send buffer */
236-
vfree(net_device->send_buf);
237-
net_device->send_buf=NULL;
238-
}
239-
kfree(net_device->send_section_map);
240233
}
241234

242235
intnetvsc_alloc_recv_comp_ring(structnetvsc_device*net_device,u32q_idx)

‎drivers/net/hyperv/rndis_filter.c‎

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,23 @@ static void rndis_set_link_state(struct rndis_device *rdev,
264264
}
265265
}
266266

267-
staticvoidrndis_filter_receive_response(structrndis_device*dev,
268-
structrndis_message*resp)
267+
staticvoidrndis_filter_receive_response(structnet_device*ndev,
268+
structnetvsc_device*nvdev,
269+
conststructrndis_message*resp)
269270
{
271+
structrndis_device*dev=nvdev->extension;
270272
structrndis_request*request=NULL;
271273
boolfound= false;
272274
unsigned longflags;
273-
structnet_device*ndev=dev->ndev;
275+
276+
/* This should never happen, it means control message
277+
* response received after device removed.
278+
*/
279+
if (dev->state==RNDIS_DEV_UNINITIALIZED) {
280+
netdev_err(ndev,
281+
"got rndis message uninitialized\n");
282+
return;
283+
}
274284

275285
spin_lock_irqsave(&dev->request_lock,flags);
276286
list_for_each_entry(request,&dev->req_list,list_ent) {
@@ -352,7 +362,6 @@ static inline void *rndis_get_ppi(struct rndis_packet *rpkt, u32 type)
352362

353363
staticintrndis_filter_receive_data(structnet_device*ndev,
354364
structnetvsc_device*nvdev,
355-
structrndis_device*dev,
356365
structrndis_message*msg,
357366
structvmbus_channel*channel,
358367
void*data,u32data_buflen)
@@ -372,7 +381,7 @@ static int rndis_filter_receive_data(struct net_device *ndev,
372381
* should be the data packet size plus the trailer padding size
373382
*/
374383
if (unlikely(data_buflen<rndis_pkt->data_len)) {
375-
netdev_err(dev->ndev,"rndis message buffer "
384+
netdev_err(ndev,"rndis message buffer "
376385
"overflow detected (got %u, min %u)"
377386
"...dropping this message!\n",
378387
data_buflen,rndis_pkt->data_len);
@@ -400,35 +409,20 @@ int rndis_filter_receive(struct net_device *ndev,
400409
void*data,u32buflen)
401410
{
402411
structnet_device_context*net_device_ctx=netdev_priv(ndev);
403-
structrndis_device*rndis_dev=net_dev->extension;
404412
structrndis_message*rndis_msg=data;
405413

406-
/* Make sure the rndis device state is initialized */
407-
if (unlikely(!rndis_dev)) {
408-
netif_dbg(net_device_ctx,rx_err,ndev,
409-
"got rndis message but no rndis device!\n");
410-
returnNVSP_STAT_FAIL;
411-
}
412-
413-
if (unlikely(rndis_dev->state==RNDIS_DEV_UNINITIALIZED)) {
414-
netif_dbg(net_device_ctx,rx_err,ndev,
415-
"got rndis message uninitialized\n");
416-
returnNVSP_STAT_FAIL;
417-
}
418-
419414
if (netif_msg_rx_status(net_device_ctx))
420415
dump_rndis_message(ndev,rndis_msg);
421416

422417
switch (rndis_msg->ndis_msg_type) {
423418
caseRNDIS_MSG_PACKET:
424-
returnrndis_filter_receive_data(ndev,net_dev,
425-
rndis_dev,rndis_msg,
419+
returnrndis_filter_receive_data(ndev,net_dev,rndis_msg,
426420
channel,data,buflen);
427421
caseRNDIS_MSG_INIT_C:
428422
caseRNDIS_MSG_QUERY_C:
429423
caseRNDIS_MSG_SET_C:
430424
/* completion msgs */
431-
rndis_filter_receive_response(rndis_dev,rndis_msg);
425+
rndis_filter_receive_response(ndev,net_dev,rndis_msg);
432426
break;
433427

434428
caseRNDIS_MSG_INDICATE:
@@ -1357,7 +1351,6 @@ void rndis_filter_device_remove(struct hv_device *dev,
13571351
net_dev->extension=NULL;
13581352

13591353
netvsc_device_remove(dev);
1360-
kfree(rndis_dev);
13611354
}
13621355

13631356
intrndis_filter_open(structnetvsc_device*nvdev)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp