[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <BY3PR21MB30331D04EE8F21FE84902676D79F9@BY3PR21MB3033.namprd21.prod.outlook.com>
Date: Thu, 4 Aug 2022 04:04:01 +0000
From: "Michael Kelley (LINUX)" <mikelley@...rosoft.com>
To: Saurabh Sengar <ssengar@...ux.microsoft.com>,
KY Srinivasan <kys@...rosoft.com>,
Haiyang Zhang <haiyangz@...rosoft.com>,
Stephen Hemminger <sthemmin@...rosoft.com>,
"wei.liu@...nel.org" <wei.liu@...nel.org>,
Dexuan Cui <decui@...rosoft.com>,
"jejb@...ux.ibm.com" <jejb@...ux.ibm.com>,
"martin.petersen@...cle.com" <martin.petersen@...cle.com>,
"linux-hyperv@...r.kernel.org" <linux-hyperv@...r.kernel.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
"linux-scsi@...r.kernel.org" <linux-scsi@...r.kernel.org>
Subject: RE: [PATCH] Drivers: hv: vmbus: Optimize vmbus_on_event
From: Saurabh Sengar <ssengar@...ux.microsoft.com> Sent: Monday, July 25, 2022 2:37 AM
>
> In the vmbus_on_event loop, 2 jiffies timer will not serve the purpose if
> callback_fn takes longer. For effective use move this check inside of
> callback functions where needed. Out of all the VMbus drivers using
> vmbus_on_event, only storvsc has a high packet volume, thus add this limit
> only in storvsc callback for now.
> There is no apparent benefit of loop itself because this tasklet will be
> scheduled anyway again if there are packets left in ring buffer. This
> patch removes this unnecessary loop as well.
>
> Signed-off-by: Saurabh Sengar <ssengar@...ux.microsoft.com>
> ---
> drivers/hv/connection.c | 33 ++++++++++++++-------------------
> drivers/scsi/storvsc_drv.c | 9 +++++++++
> 2 files changed, 23 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
> index eca7afd..9dc27e5 100644
> --- a/drivers/hv/connection.c
> +++ b/drivers/hv/connection.c
> @@ -431,34 +431,29 @@ struct vmbus_channel *relid2channel(u32 relid)
> void vmbus_on_event(unsigned long data)
> {
> struct vmbus_channel *channel = (void *) data;
> - unsigned long time_limit = jiffies + 2;
> + void (*callback_fn)(void *context);
>
> trace_vmbus_on_event(channel);
>
> hv_debug_delay_test(channel, INTERRUPT_DELAY);
> - do {
> - void (*callback_fn)(void *);
>
> - /* A channel once created is persistent even when
> - * there is no driver handling the device. An
> - * unloading driver sets the onchannel_callback to NULL.
> - */
> - callback_fn = READ_ONCE(channel->onchannel_callback);
> - if (unlikely(callback_fn == NULL))
> - return;
> -
> - (*callback_fn)(channel->channel_callback_context);
> + /* A channel once created is persistent even when
> + * there is no driver handling the device. An
> + * unloading driver sets the onchannel_callback to NULL.
> + */
> + callback_fn = READ_ONCE(channel->onchannel_callback);
> + if (unlikely(!callback_fn))
> + return;
>
> - if (channel->callback_mode != HV_CALL_BATCHED)
> - return;
> + (*callback_fn)(channel->channel_callback_context);
>
> - if (likely(hv_end_read(&channel->inbound) == 0))
> - return;
> + if (channel->callback_mode != HV_CALL_BATCHED)
> + return;
>
> - hv_begin_read(&channel->inbound);
> - } while (likely(time_before(jiffies, time_limit)));
> + if (likely(hv_end_read(&channel->inbound) == 0))
> + return;
>
> - /* The time limit (2 jiffies) has been reached */
> + hv_begin_read(&channel->inbound);
> tasklet_schedule(&channel->callback_event);
> }
>
> diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
> index fe000da..c457e6b 100644
> --- a/drivers/scsi/storvsc_drv.c
> +++ b/drivers/scsi/storvsc_drv.c
> @@ -60,6 +60,9 @@
> #define VMSTOR_PROTO_VERSION_WIN8_1 VMSTOR_PROTO_VERSION(6, 0)
> #define VMSTOR_PROTO_VERSION_WIN10 VMSTOR_PROTO_VERSION(6, 2)
>
> +/* channel callback timeout in ms */
> +#define CALLBACK_TIMEOUT 2
> +
> /* Packet structure describing virtual storage requests. */
> enum vstor_packet_operation {
> VSTOR_OPERATION_COMPLETE_IO = 1,
> @@ -1204,6 +1207,7 @@ static void storvsc_on_channel_callback(void *context)
> struct hv_device *device;
> struct storvsc_device *stor_device;
> struct Scsi_Host *shost;
> + unsigned long time_limit = jiffies + msecs_to_jiffies(CALLBACK_TIMEOUT);
>
> if (channel->primary_channel != NULL)
> device = channel->primary_channel->device_obj;
> @@ -1224,6 +1228,11 @@ static void storvsc_on_channel_callback(void *context)
> u32 minlen = rqst_id ? sizeof(struct vstor_packet) :
> sizeof(enum vstor_packet_operation);
>
> + if (unlikely(time_after(jiffies, time_limit))) {
> + hv_pkt_iter_close(channel);
> + return;
> + }
> +
> if (pktlen < minlen) {
> dev_err(&device->device,
> "Invalid pkt: id=%llu, len=%u, minlen=%u\n",
> --
> 1.8.3.1
Reviewed-by: Michael Kelley <mikelley@...rosoft.com>
Powered by blists - more mailing lists