From: "K. Y. Srinivasan" <kys@microsoft.com>
To: gregkh@suse.de, linux-kernel@vger.kernel.org,
devel@linuxdriverproject.org, virtualization@lists.osdl.org
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Subject: [PATCH 17/46] Staging: hv: netvsc: Get rid of the refcnt field in struct netvsc_device
Date: Sat, 27 Aug 2011 11:31:16 -0700 [thread overview]
Message-ID: <1314469905-7058-17-git-send-email-kys@microsoft.com> (raw)
In-Reply-To: <1314469905-7058-1-git-send-email-kys@microsoft.com>
Get rid of the refcnt field in struct netvsc_device. We implement the following
logic to manage the life cycle of the device: If the device is being destroyed,
we do not allow any outgoing traffic. Furthermore, if the device is being
destroyed, we allow incoming traffic only to drain outgoing traffic. Note that
the driver may send some book keeping messages to the host not known to
upper level Linux code.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
drivers/staging/hv/hyperv_net.h | 1 -
drivers/staging/hv/netvsc.c | 62 ++++++++++++--------------------------
2 files changed, 20 insertions(+), 43 deletions(-)
diff --git a/drivers/staging/hv/hyperv_net.h b/drivers/staging/hv/hyperv_net.h
index 0b347c1..af8a37f 100644
--- a/drivers/staging/hv/hyperv_net.h
+++ b/drivers/staging/hv/hyperv_net.h
@@ -369,7 +369,6 @@ struct nvsp_message {
struct netvsc_device {
struct hv_device *dev;
- atomic_t refcnt;
atomic_t num_outstanding_sends;
bool destroy;
/*
diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index 388f083..9828f0b 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -40,8 +40,6 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device)
if (!net_device)
return NULL;
- /* Set to 2 to allow both inbound and outbound traffic */
- atomic_set(&net_device->refcnt, 2);
net_device->destroy = false;
net_device->dev = device;
@@ -50,43 +48,37 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device)
return net_device;
}
-/* Get the net device object iff exists and its refcount > 1 */
static struct netvsc_device *get_outbound_net_device(struct hv_device *device)
{
struct netvsc_device *net_device;
net_device = device->ext;
- if (net_device && (atomic_read(&net_device->refcnt) > 1) &&
- !net_device->destroy)
- atomic_inc(&net_device->refcnt);
- else
+ if (net_device && net_device->destroy)
net_device = NULL;
return net_device;
}
-/* Get the net device object iff exists and its refcount > 0 */
static struct netvsc_device *get_inbound_net_device(struct hv_device *device)
{
struct netvsc_device *net_device;
+ unsigned long flags;
+ spin_lock_irqsave(&device->channel->inbound_lock, flags);
net_device = device->ext;
- if (net_device && atomic_read(&net_device->refcnt))
- atomic_inc(&net_device->refcnt);
- else
+
+ if (!net_device)
+ goto get_in_err;
+
+ if (net_device->destroy &&
+ atomic_read(&net_device->num_outstanding_sends) == 0)
net_device = NULL;
+get_in_err:
+ spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
return net_device;
}
-static void put_net_device(struct hv_device *device)
-{
- struct netvsc_device *net_device;
-
- net_device = device->ext;
-
- atomic_dec(&net_device->refcnt);
-}
static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
{
@@ -268,7 +260,6 @@ cleanup:
netvsc_destroy_recv_buf(net_device);
exit:
- put_net_device(device);
return ret;
}
@@ -349,7 +340,6 @@ static int netvsc_connect_vsp(struct hv_device *device)
ret = netvsc_init_recv_buf(device);
cleanup:
- put_net_device(device);
return ret;
}
@@ -368,7 +358,6 @@ int netvsc_device_remove(struct hv_device *device)
unsigned long flags;
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);
@@ -383,19 +372,17 @@ int netvsc_device_remove(struct hv_device *device)
netvsc_disconnect_vsp(net_device);
- atomic_dec(&net_device->refcnt);
- device->ext = NULL;
/*
- * 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.
+ * Since we have already drained, we don't need to busy wait
+ * as was done in final_release_stor_device()
+ * Note that we cannot set the ext pointer to NULL until
+ * we have drained - to drain the outgoing packets, we need to
+ * allow incoming packets.
*/
- while (atomic_read(&net_device->refcnt))
- udelay(100);
+
+ spin_lock_irqsave(&device->channel->inbound_lock, flags);
+ device->ext = NULL;
+ spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
/* At this point, no one should be accessing netDevice except in here */
dev_notice(&device->device, "net device safe to remove");
@@ -456,7 +443,6 @@ static void netvsc_send_completion(struct hv_device *device,
"%d received!!", nvsp_packet->hdr.msg_type);
}
- put_net_device(device);
}
int netvsc_send(struct hv_device *device,
@@ -509,7 +495,6 @@ int netvsc_send(struct hv_device *device,
packet, ret);
atomic_inc(&net_device->num_outstanding_sends);
- put_net_device(device);
return ret;
}
@@ -602,7 +587,6 @@ static void netvsc_receive_completion(void *context)
if (fsend_receive_comp)
netvsc_send_recv_completion(device, transaction_id);
- put_net_device(device);
}
static void netvsc_receive(struct hv_device *device,
@@ -636,7 +620,6 @@ static void netvsc_receive(struct hv_device *device,
if (packet->type != VM_PKT_DATA_USING_XFER_PAGES) {
dev_err(&device->device, "Unknown packet type received - %d",
packet->type);
- put_net_device(device);
return;
}
@@ -648,7 +631,6 @@ static void netvsc_receive(struct hv_device *device,
NVSP_MSG1_TYPE_SEND_RNDIS_PKT) {
dev_err(&device->device, "Unknown nvsp packet type received-"
" %d", nvsp_packet->hdr.msg_type);
- put_net_device(device);
return;
}
@@ -658,7 +640,6 @@ static void netvsc_receive(struct hv_device *device,
dev_err(&device->device, "Invalid xfer page set id - "
"expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID,
vmxferpage_packet->xfer_pageset_id);
- put_net_device(device);
return;
}
@@ -698,7 +679,6 @@ static void netvsc_receive(struct hv_device *device,
netvsc_send_recv_completion(device,
vmxferpage_packet->d.trans_id);
- put_net_device(device);
return;
}
@@ -786,7 +766,6 @@ static void netvsc_receive(struct hv_device *device,
completion.recv.recv_completion_ctx);
}
- put_net_device(device);
}
static void netvsc_channel_cb(void *context)
@@ -869,7 +848,6 @@ static void netvsc_channel_cb(void *context)
}
} while (1);
- put_net_device(device);
out:
kfree(buffer);
return;
--
1.7.4.1
next prev parent reply other threads:[~2011-08-27 18:31 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-27 18:31 [PATCH 0000/0046] Staging: hv: Driver cleanup K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 02/46] Staging: hv: storvsc: Do not aquire an unnecessary reference on stor_device K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 03/46] Staging: hv: storvsc: Rename must_get_stor_device() K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 04/46] Staging: hv: storvsc: Rename get_stor_device() K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 05/46] Staging: hv: storvsc: Cleanup alloc_stor_device() K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 06/46] Staging: hv: storvsc: Introduce state to manage the lifecycle of stor device K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 07/46] Staging: hv: storvsc: Prevent outgoing traffic when stor dev is being destroyed K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 08/46] Staging: hv: storvsc: Get rid of release_stor_device() by inlining the code K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 09/46] Staging: hv: storvsc: Get rid of final_release_stor_device() by inlining code K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 10/46] Staging: hv: storvsc: Get rid of the reference counting in struct storvsc_device K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 11/46] Staging: hv: netvsc: Inline the code for free_net_device() K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 12/46] Staging: hv: netvsc: Cleanup alloc_net_device() K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 13/46] Staging: hv: netvsc: Introduce state to manage the lifecycle of net device K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 14/46] Staging: hv: netvsc: Prevent outgoing traffic when netvsc dev is destroyed K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 15/46] Staging: hv: netvsc: Get rid of release_outbound_net_device() by inlining the code K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 16/46] Staging: hv: netvsc: Get rid of release_inbound_net_device() " K. Y. Srinivasan
2011-08-27 18:31 ` K. Y. Srinivasan [this message]
2011-08-27 18:31 ` [PATCH 18/46] Staging: hv: storvsc: Add code to handle IDE devices using the storvsc driver K. Y. Srinivasan
2011-08-30 11:07 ` Dan Carpenter
2011-08-27 18:31 ` [PATCH 19/46] Staging: hv: storvsc: Handle " K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 20/46] Staging: hv: blkvsc: Get rid of blkvsc_drv.c as this code is not used K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 21/46] Staging: hv: storvsc: Optimize bounce buffer handling for the "write" case K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 22/46] Staging: hv: storvsc: Optimize the bounce buffer handling in the "read" case K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 23/46] Staging: hv: storvsc: Include storvsc.c in storvsc_drv.c K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 24/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of storvsc.c K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 25/46] Staging: hv: storvsc: Add the contents of hyperv_storage.h to storvsc_drv.c K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 26/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of hyperv_storage.h K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 27/46] Staging: hv: storvsc: Fixup srb and scsi status for INQUIRY and MODE_SENSE K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 28/46] Staging: hv: storvsc: Fix a typo K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 29/46] Staging: hv: storvsc: In case of scsi errors offline the device K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 30/46] Staging: hv: storvsc: No need to copy from bounce buffer in case of a failure K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 31/46] Staging: hv: util: Forcefully shutdown when shutdown is requested K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 32/46] Staging: hv: util: Adjust guest time in a process context K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 33/46] Staging: hv: vmbus: Check before invoking the channel callback K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 34/46] Staging: hv: vmbus: Properly deal with de-registering " K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 35/46] Staging: hv: Fix a bug in vmbus_match() K. Y. Srinivasan
2011-08-29 18:00 ` Greg KH
2011-08-27 18:31 ` [PATCH 36/46] Staging: hv: vmbus: Get rid of vmbus_on_isr() by inlining the code K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 37/46] Staging: hv: vmbus: Check for events before messages K. Y. Srinivasan
2011-08-29 18:05 ` Greg KH
2011-08-30 17:06 ` KY Srinivasan
2011-08-30 17:38 ` Greg KH
2011-08-31 14:22 ` KY Srinivasan
2011-08-27 18:31 ` [PATCH 38/46] Staging: hv: vmbus: Do not enable auto eoi K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 39/46] Staging: hv: vmbus: Fixup indentation in vmbus_acpi_add() K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 40/46] Staging: hv: vmbus: Get rid of some dated/redundant comments K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init() K. Y. Srinivasan
2011-08-29 18:08 ` Greg KH
2011-08-30 10:29 ` Dan Carpenter
2011-08-30 14:07 ` Greg KH
2011-08-30 17:25 ` KY Srinivasan
2011-08-30 17:07 ` KY Srinivasan
2011-08-27 18:31 ` [PATCH 42/46] Staging: hv: vmbus: Get rid of an unnecessary check in vmbus_connect() K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 43/46] Staging: hv: vmbus: Fix a checkpatch warning in ring_buffer.c K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c K. Y. Srinivasan
2011-08-28 6:56 ` Joe Perches
2011-08-30 17:03 ` KY Srinivasan
2011-08-29 18:09 ` Greg KH
2011-08-30 17:11 ` KY Srinivasan
2011-08-30 17:41 ` Greg KH
2011-08-31 14:21 ` KY Srinivasan
2011-08-27 18:31 ` [PATCH 45/46] Staging: hv: mousevsc: Fix checkpatch errors and warnings K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 46/46] Staging: hv: Update the TODO file K. Y. Srinivasan
2011-08-29 18:12 ` Greg KH
2011-08-30 17:13 ` KY Srinivasan
2011-08-29 18:15 ` [PATCH 0000/0046] Staging: hv: Driver cleanup Greg KH
2011-08-30 17:27 ` KY Srinivasan
2011-08-30 12:48 ` Olaf Hering
2011-08-30 17:22 ` KY Srinivasan
2011-08-30 17:43 ` Greg KH
2011-08-30 18:04 ` Olaf Hering
2011-08-30 18:19 ` Greg KH
2011-08-31 9:11 ` Olaf Hering
2011-09-01 15:43 ` [PATCH RFC] ata_piix: ignore disks in a hyper-v guest Olaf Hering
2011-08-31 14:27 ` [PATCH 0000/0046] Staging: hv: Driver cleanup KY Srinivasan
2011-08-31 14:18 ` KY Srinivasan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1314469905-7058-17-git-send-email-kys@microsoft.com \
--to=kys@microsoft.com \
--cc=devel@linuxdriverproject.org \
--cc=gregkh@suse.de \
--cc=haiyangz@microsoft.com \
--cc=linux-kernel@vger.kernel.org \
--cc=virtualization@lists.osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).