| From 775a63b666a7c82704fde781929a2fb3575b86e9 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 20 Aug 2019 02:56:34 +0000 |
| Subject: HID: hyperv: Use in-place iterator API in the channel callback |
| |
| From: Dexuan Cui <decui@microsoft.com> |
| |
| [ Upstream commit 6a297c90efa68b2864483193b8bfb0d19478600c ] |
| |
| Simplify the ring buffer handling with the in-place API. |
| |
| Also avoid the dynamic allocation and the memory leak in the channel |
| callback function. |
| |
| Signed-off-by: Dexuan Cui <decui@microsoft.com> |
| Acked-by: Jiri Kosina <jkosina@suse.cz> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/hid/hid-hyperv.c | 56 +++++++--------------------------------- |
| 1 file changed, 10 insertions(+), 46 deletions(-) |
| |
| diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c |
| index 7795831d37c21..f363163200759 100644 |
| --- a/drivers/hid/hid-hyperv.c |
| +++ b/drivers/hid/hid-hyperv.c |
| @@ -314,60 +314,24 @@ static void mousevsc_on_receive(struct hv_device *device, |
| |
| static void mousevsc_on_channel_callback(void *context) |
| { |
| - const int packet_size = 0x100; |
| - int ret; |
| struct hv_device *device = context; |
| - u32 bytes_recvd; |
| - u64 req_id; |
| struct vmpacket_descriptor *desc; |
| - unsigned char *buffer; |
| - int bufferlen = packet_size; |
| - |
| - buffer = kmalloc(bufferlen, GFP_ATOMIC); |
| - if (!buffer) |
| - return; |
| - |
| - do { |
| - ret = vmbus_recvpacket_raw(device->channel, buffer, |
| - bufferlen, &bytes_recvd, &req_id); |
| - |
| - switch (ret) { |
| - case 0: |
| - if (bytes_recvd <= 0) { |
| - kfree(buffer); |
| - return; |
| - } |
| - desc = (struct vmpacket_descriptor *)buffer; |
| - |
| - switch (desc->type) { |
| - case VM_PKT_COMP: |
| - break; |
| - |
| - case VM_PKT_DATA_INBAND: |
| - mousevsc_on_receive(device, desc); |
| - break; |
| - |
| - default: |
| - pr_err("unhandled packet type %d, tid %llx len %d\n", |
| - desc->type, req_id, bytes_recvd); |
| - break; |
| - } |
| |
| + foreach_vmbus_pkt(desc, device->channel) { |
| + switch (desc->type) { |
| + case VM_PKT_COMP: |
| break; |
| |
| - case -ENOBUFS: |
| - kfree(buffer); |
| - /* Handle large packet */ |
| - bufferlen = bytes_recvd; |
| - buffer = kmalloc(bytes_recvd, GFP_ATOMIC); |
| - |
| - if (!buffer) |
| - return; |
| + case VM_PKT_DATA_INBAND: |
| + mousevsc_on_receive(device, desc); |
| + break; |
| |
| + default: |
| + pr_err("Unhandled packet type %d, tid %llx len %d\n", |
| + desc->type, desc->trans_id, desc->len8 * 8); |
| break; |
| } |
| - } while (1); |
| - |
| + } |
| } |
| |
| static int mousevsc_connect_to_vsp(struct hv_device *device) |
| -- |
| 2.20.1 |
| |