Input: hyperv-keyboard: Use in-place iterator API in the channel callback [Linux 4.19.72]

This Linux kernel change "Input: hyperv-keyboard: Use in-place iterator API in the channel callback" is included in the Linux 4.19.72 release. This change is authored by Dexuan Cui <decui [at] microsoft.com> on Tue Aug 20 03:01:23 2019 +0000. The commit for this change in Linux stable tree is 1d42e40 (patch) which is from upstream commit d09bc83. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream d09bc83.

Input: hyperv-keyboard: Use in-place iterator API in the channel callback

[ Upstream commit d09bc83640d524b8467a660db7b1d15e6562a1de ]

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: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>

There are 35 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/input/serio/hyperv-keyboard.c | 35 ++++++-----------------------------
 1 file changed, 6 insertions(+), 29 deletions(-)

diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c
index a8b9be3..7d0a5cc 100644
--- a/drivers/input/serio/hyperv-keyboard.c
+++ b/drivers/input/serio/hyperv-keyboard.c
@@ -245,40 +245,17 @@ static void hv_kbd_handle_received_packet(struct hv_device *hv_dev,

 static void hv_kbd_on_channel_callback(void *context)
 {
+   struct vmpacket_descriptor *desc;
    struct hv_device *hv_dev = context;
-   void *buffer;
-   int bufferlen = 0x100; /* Start with sensible size */
    u32 bytes_recvd;
    u64 req_id;
-   int error;

-   buffer = kmalloc(bufferlen, GFP_ATOMIC);
-   if (!buffer)
-       return;
-
-   while (1) {
-       error = vmbus_recvpacket_raw(hv_dev->channel, buffer, bufferlen,
-                        &bytes_recvd, &req_id);
-       switch (error) {
-       case 0:
-           if (bytes_recvd == 0) {
-               kfree(buffer);
-               return;
-           }
-
-           hv_kbd_handle_received_packet(hv_dev, buffer,
-                             bytes_recvd, req_id);
-           break;
+   foreach_vmbus_pkt(desc, hv_dev->channel) {
+       bytes_recvd = desc->len8 * 8;
+       req_id = desc->trans_id;

-       case -ENOBUFS:
-           kfree(buffer);
-           /* Handle large packet */
-           bufferlen = bytes_recvd;
-           buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
-           if (!buffer)
-               return;
-           break;
-       }
+       hv_kbd_handle_received_packet(hv_dev, desc, bytes_recvd,
+                         req_id);
    }
 }

Leave a Reply

Your email address will not be published. Required fields are marked *