On 1/18/22 03:02, yangx.jy@xxxxxxxxxxx wrote: > CC: linux-rdma mail list > > On 2022/1/14 4:51, Bob Pearson wrote: >> The way these queues work they can only hold 2^n - 1 entries. The reason for this is >> to distinguish empty and full. If you let the last entry be written then producer would advance to equal consumer which is the initial empty condition. So a queue which can hold 1 entry has to have two slots (n=1) but can only hold one entry. It begins with > Hi Bob, > > Thanks for your detailed example. >> prod = cons = 0 and is empty and is*not* full full = (cons == ((prod + 1) % 2)) = (0 == 1) = false empty = (prod == cons) == (0 == 0) = true >> >> Adding one entry gives >> >> slot[0] = value, prod = 1, cons = 0 and is full and not empty full = (cons == ((prod + 1) % 2)) = (0 == 0) = true empty = (prod == cons) == (0 == 1) = false >> >> After reading this value >> >> slot[0] = old value, prod = cons = 1 and queue is empty again. full = (cons == ((prod + 1) % 2)) = (1 == 0) = false empty = (prod == cons) = (1 == 1) = true >> >> Writing a new value >> >> slot[1] = new value, slot[0] = old value, prod = 0 and cons = 1 and queue is full again. full = (cons == ((prod + 1) % 2)) = (1 == (0 + 1) % 2) = true empty = (prod == cons) = (0 == 1) = false and x % 2^N is the same as x & (2^N - 1) or x & index_mask. >> >> The expression full = (cons == ((qp->cur_index + 1) % q->index_mask)) is correct. Actually you are correct. If you look at queue_full() it uses full = (cons == (prod + 1) & q->index_mask) and queue_empty() uses empty = (prod == cons) *but* check_qp_queue_full() uses full = (cons == ((qp->cur_index + 1) % q->index_mask)) with % instead of &. I was so used to looking at the first two I missed the error in the last one. % should be & like the others. Bob