Input: hyperv-keyboard: Use in-place iterator API in the channel callback
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>
This commit is contained in:
parent
16c7596372
commit
d09bc83640
|
@ -237,40 +237,17 @@ static void hv_kbd_handle_received_packet(struct hv_device *hv_dev,
|
||||||
|
|
||||||
static void hv_kbd_on_channel_callback(void *context)
|
static void hv_kbd_on_channel_callback(void *context)
|
||||||
{
|
{
|
||||||
|
struct vmpacket_descriptor *desc;
|
||||||
struct hv_device *hv_dev = context;
|
struct hv_device *hv_dev = context;
|
||||||
void *buffer;
|
|
||||||
int bufferlen = 0x100; /* Start with sensible size */
|
|
||||||
u32 bytes_recvd;
|
u32 bytes_recvd;
|
||||||
u64 req_id;
|
u64 req_id;
|
||||||
int error;
|
|
||||||
|
|
||||||
buffer = kmalloc(bufferlen, GFP_ATOMIC);
|
foreach_vmbus_pkt(desc, hv_dev->channel) {
|
||||||
if (!buffer)
|
bytes_recvd = desc->len8 * 8;
|
||||||
return;
|
req_id = desc->trans_id;
|
||||||
|
|
||||||
while (1) {
|
hv_kbd_handle_received_packet(hv_dev, desc, bytes_recvd,
|
||||||
error = vmbus_recvpacket_raw(hv_dev->channel, buffer, bufferlen,
|
req_id);
|
||||||
&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;
|
|
||||||
|
|
||||||
case -ENOBUFS:
|
|
||||||
kfree(buffer);
|
|
||||||
/* Handle large packet */
|
|
||||||
bufferlen = bytes_recvd;
|
|
||||||
buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
|
|
||||||
if (!buffer)
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue