Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Drivers: hv_vmbus: Fix signal to host condition

Fixes a bug where previously hv_ringbuffer_read would pass in the old
number of bytes available to read instead of the expected old read index
when calculating when to signal to the host that the ringbuffer is empty.
Since the previous write size is already saved, also changes the
hv_need_to_signal_on_read to use the previously read value rather than
recalculating it.

Signed-off-by: Christopher Oo <t-chriso@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Christopher Oo and committed by
Greg Kroah-Hartman
a5cca686 3b71107d

+3 -11
+3 -11
drivers/hv/ring_buffer.c
··· 103 103 * there is room for the producer to send the pending packet. 104 104 */ 105 105 106 - static bool hv_need_to_signal_on_read(u32 old_rd, 107 - struct hv_ring_buffer_info *rbi) 106 + static bool hv_need_to_signal_on_read(u32 prev_write_sz, 107 + struct hv_ring_buffer_info *rbi) 108 108 { 109 - u32 prev_write_sz; 110 109 u32 cur_write_sz; 111 110 u32 r_size; 112 111 u32 write_loc = rbi->ring_buffer->write_index; ··· 121 122 r_size = rbi->ring_datasize; 122 123 cur_write_sz = write_loc >= read_loc ? r_size - (write_loc - read_loc) : 123 124 read_loc - write_loc; 124 - 125 - prev_write_sz = write_loc >= old_rd ? r_size - (write_loc - old_rd) : 126 - old_rd - write_loc; 127 - 128 125 129 126 if ((prev_write_sz < pending_sz) && (cur_write_sz >= pending_sz)) 130 127 return true; ··· 512 517 u32 next_read_location = 0; 513 518 u64 prev_indices = 0; 514 519 unsigned long flags; 515 - u32 old_read; 516 520 517 521 if (buflen <= 0) 518 522 return -EINVAL; ··· 521 527 hv_get_ringbuffer_availbytes(inring_info, 522 528 &bytes_avail_toread, 523 529 &bytes_avail_towrite); 524 - 525 - old_read = bytes_avail_toread; 526 530 527 531 /* Make sure there is something to read */ 528 532 if (bytes_avail_toread < buflen) { ··· 552 560 553 561 spin_unlock_irqrestore(&inring_info->ring_lock, flags); 554 562 555 - *signal = hv_need_to_signal_on_read(old_read, inring_info); 563 + *signal = hv_need_to_signal_on_read(bytes_avail_towrite, inring_info); 556 564 557 565 return 0; 558 566 }