Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 268045
b: refs/heads/master
c: 3852409
h: refs/heads/master
i:
  268043: 0d9ef1d
v: v3
  • Loading branch information
K. Y. Srinivasan authored and Greg Kroah-Hartman committed Aug 29, 2011
1 parent 714a4c6 commit 8847494
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 25 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2ef7714397cd49dc378e20afa6dd19306e5f2b5e
refs/heads/master: 3852409b88e8ec2a8abb28db5be25a7503297208
38 changes: 14 additions & 24 deletions trunk/drivers/staging/hv/netvsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,6 @@ static void put_net_device(struct hv_device *device)
atomic_dec(&net_device->refcnt);
}

static struct netvsc_device *release_outbound_net_device(
struct hv_device *device)
{
struct netvsc_device *net_device;

net_device = device->ext;
if (net_device == NULL)
return NULL;

/* Busy wait until the ref drop to 2, then set it to 1 */
while (atomic_cmpxchg(&net_device->refcnt, 2, 1) != 2)
udelay(100);

return net_device;
}

static struct netvsc_device *release_inbound_net_device(
struct hv_device *device)
{
Expand Down Expand Up @@ -400,13 +384,8 @@ int netvsc_device_remove(struct hv_device *device)
struct hv_netvsc_packet *netvsc_packet, *pos;
unsigned long flags;

/* Stop outbound traffic ie sends and receives completions */
net_device = release_outbound_net_device(device);
if (!net_device) {
dev_err(&device->device, "No net device present!!");
return -ENODEV;
}

net_device = (struct netvsc_device *)device->ext;
atomic_dec(&net_device->refcnt);
spin_lock_irqsave(&device->channel->inbound_lock, flags);
net_device->destroy = true;
spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
Expand All @@ -424,6 +403,18 @@ int netvsc_device_remove(struct hv_device *device)
/* Stop inbound traffic ie receives and sends completions */
net_device = release_inbound_net_device(device);

/*
* Wait until the ref cnt falls to 0.
* We have already stopped any new references
* for outgoing traffic. Also, at this point we don't have any
* incoming traffic as well. So this must be outgoing refrences
* established prior to marking the device as being destroyed.
* Since the send path is non-blocking, it is reasonable to busy
* wait here.
*/
while (atomic_read(&net_device->refcnt))
udelay(100);

/* At this point, no one should be accessing netDevice except in here */
dev_notice(&device->device, "net device safe to remove");

Expand Down Expand Up @@ -976,7 +967,6 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
kfree(packet);
}

release_outbound_net_device(device);
release_inbound_net_device(device);

kfree(net_device);
Expand Down

0 comments on commit 8847494

Please sign in to comment.