Commit d09bc836 authored by Dexuan Cui's avatar Dexuan Cui Committed by Sasha Levin
Browse files

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: default avatarDexuan Cui <decui@microsoft.com>
Acked-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 16c75963
Loading
Loading
Loading
Loading
+6 −29
Original line number Diff line number Diff line
@@ -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)
{
	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);
	}
}