mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
Drivers: hv: vmbus: Optimize vmbus_on_event
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@linux.microsoft.com> Reviewed-by: Michael Kelley <mikelley@microsoft.com> Link: https://lore.kernel.org/r/1658741848-4210-1-git-send-email-ssengar@linux.microsoft.com Signed-off-by: Wei Liu <wei.liu@kernel.org>
This commit is contained in:
parent
521a547ced
commit
78c65f0f3c
@ -431,34 +431,29 @@ struct vmbus_channel *relid2channel(u32 relid)
|
|||||||
void vmbus_on_event(unsigned long data)
|
void vmbus_on_event(unsigned long data)
|
||||||
{
|
{
|
||||||
struct vmbus_channel *channel = (void *) data;
|
struct vmbus_channel *channel = (void *) data;
|
||||||
unsigned long time_limit = jiffies + 2;
|
void (*callback_fn)(void *context);
|
||||||
|
|
||||||
trace_vmbus_on_event(channel);
|
trace_vmbus_on_event(channel);
|
||||||
|
|
||||||
hv_debug_delay_test(channel, INTERRUPT_DELAY);
|
hv_debug_delay_test(channel, INTERRUPT_DELAY);
|
||||||
do {
|
|
||||||
void (*callback_fn)(void *);
|
|
||||||
|
|
||||||
/* A channel once created is persistent even when
|
/* A channel once created is persistent even when
|
||||||
* there is no driver handling the device. An
|
* there is no driver handling the device. An
|
||||||
* unloading driver sets the onchannel_callback to NULL.
|
* unloading driver sets the onchannel_callback to NULL.
|
||||||
*/
|
*/
|
||||||
callback_fn = READ_ONCE(channel->onchannel_callback);
|
callback_fn = READ_ONCE(channel->onchannel_callback);
|
||||||
if (unlikely(callback_fn == NULL))
|
if (unlikely(!callback_fn))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
(*callback_fn)(channel->channel_callback_context);
|
(*callback_fn)(channel->channel_callback_context);
|
||||||
|
|
||||||
if (channel->callback_mode != HV_CALL_BATCHED)
|
if (channel->callback_mode != HV_CALL_BATCHED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (likely(hv_end_read(&channel->inbound) == 0))
|
if (likely(hv_end_read(&channel->inbound) == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hv_begin_read(&channel->inbound);
|
hv_begin_read(&channel->inbound);
|
||||||
} while (likely(time_before(jiffies, time_limit)));
|
|
||||||
|
|
||||||
/* The time limit (2 jiffies) has been reached */
|
|
||||||
tasklet_schedule(&channel->callback_event);
|
tasklet_schedule(&channel->callback_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,9 @@
|
|||||||
#define VMSTOR_PROTO_VERSION_WIN8_1 VMSTOR_PROTO_VERSION(6, 0)
|
#define VMSTOR_PROTO_VERSION_WIN8_1 VMSTOR_PROTO_VERSION(6, 0)
|
||||||
#define VMSTOR_PROTO_VERSION_WIN10 VMSTOR_PROTO_VERSION(6, 2)
|
#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. */
|
/* Packet structure describing virtual storage requests. */
|
||||||
enum vstor_packet_operation {
|
enum vstor_packet_operation {
|
||||||
VSTOR_OPERATION_COMPLETE_IO = 1,
|
VSTOR_OPERATION_COMPLETE_IO = 1,
|
||||||
@ -1204,6 +1207,7 @@ static void storvsc_on_channel_callback(void *context)
|
|||||||
struct hv_device *device;
|
struct hv_device *device;
|
||||||
struct storvsc_device *stor_device;
|
struct storvsc_device *stor_device;
|
||||||
struct Scsi_Host *shost;
|
struct Scsi_Host *shost;
|
||||||
|
unsigned long time_limit = jiffies + msecs_to_jiffies(CALLBACK_TIMEOUT);
|
||||||
|
|
||||||
if (channel->primary_channel != NULL)
|
if (channel->primary_channel != NULL)
|
||||||
device = channel->primary_channel->device_obj;
|
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) :
|
u32 minlen = rqst_id ? sizeof(struct vstor_packet) :
|
||||||
sizeof(enum vstor_packet_operation);
|
sizeof(enum vstor_packet_operation);
|
||||||
|
|
||||||
|
if (unlikely(time_after(jiffies, time_limit))) {
|
||||||
|
hv_pkt_iter_close(channel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (pktlen < minlen) {
|
if (pktlen < minlen) {
|
||||||
dev_err(&device->device,
|
dev_err(&device->device,
|
||||||
"Invalid pkt: id=%llu, len=%u, minlen=%u\n",
|
"Invalid pkt: id=%llu, len=%u, minlen=%u\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user