> -----Original Message----- > From: Stephen Hemminger [mailto:stephen@xxxxxxxxxxxxxxxxxx] > Sent: Monday, November 7, 2016 8:50 AM > To: Haiyang Zhang <haiyangz@xxxxxxxxxxxxx>; KY Srinivasan > <kys@xxxxxxxxxxxxx> > Cc: devel@xxxxxxxxxxxxxxxxxxxxxx; devel@xxxxxxxxxxxxxxxxxxxxxx > Subject: [PATCH] vmbus: fix lockup if ring fills up > > From: Stephen Hemminger <sthemmin@xxxxxxxxxxxxx > > This fixes a day one bug in circular ring buffer. The ring buffer > will get stuck if the number of bytes written exactly fills the > ring buffer size. The root cause is an off by one bug. > > Ring empty state is when read_index == write_loc. > The very last slot in the circular buffer must never be filled > otherwise there is no way to tell the difference between completely > full and empty! Stephen, I maybe missing something; but we do have code to prevent this very situation. all ring buffer writes are done via this API: hv_ringbuffer_write() and the first thing we do here is to check the very condition you bring up here: /* * If there is only room for the packet, assume it is full. * Otherwise, the next time around, we think the ring buffer * is empty since the read index == write index. */ if (bytes_avail_towrite <= totalbytes_towrite) { if (lock) spin_unlock_irqrestore(&outring_info->ring_lock, flags); return -EAGAIN; } Regards, K. Y > > Signed-off-by: Stephen Hemminger <stephen@xxxxxxxxxxxxxxxxxx> > --- > Please queue for stable as well > > include/linux/hyperv.h | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h > index cd184bd..28f88de 100644 > --- a/include/linux/hyperv.h > +++ b/include/linux/hyperv.h > @@ -150,6 +150,7 @@ hv_get_ringbuffer_availbytes(struct > hv_ring_buffer_info *rbi, > > *write = write_loc >= read_loc ? dsize - (write_loc - read_loc) : > read_loc - write_loc; > + *write -= 1; > *read = dsize - *write; > } > > @@ -177,7 +178,8 @@ static inline u32 hv_get_bytes_to_write(struct > hv_ring_buffer_info *rbi) > > write = write_loc >= read_loc ? dsize - (write_loc - read_loc) : > read_loc - write_loc; > - return write; > + /* make sure ring never gets completely full */ > + return write - 1; > } > > /* > -- > 2.7.4 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel