Skip to content

Commit 97dd1ab

Browse files
solbjorndavem330
authored andcommitted
net: qed: fix left elements count calculation
qed_chain_get_element_left{,_u32} returned 0 when the difference between producer and consumer page count was equal to the total page count. Fix this by conditional expanding of producer value (vs unconditional). This allowed to eliminate normalizaton against total page count, which was the cause of this bug. Misc: replace open-coded constants with common defines. Fixes: a91eb52 ("qed: Revisit chain implementation") Signed-off-by: Alexander Lobakin <[email protected]> Signed-off-by: Igor Russkikh <[email protected]> Signed-off-by: Michal Kalderon <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b4730ae commit 97dd1ab

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

include/linux/qed/qed_chain.h

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,28 +207,34 @@ static inline u32 qed_chain_get_cons_idx_u32(struct qed_chain *p_chain)
207207

208208
static inline u16 qed_chain_get_elem_left(struct qed_chain *p_chain)
209209
{
210+
u16 elem_per_page = p_chain->elem_per_page;
211+
u32 prod = p_chain->u.chain16.prod_idx;
212+
u32 cons = p_chain->u.chain16.cons_idx;
210213
u16 used;
211214

212-
used = (u16) (((u32)0x10000 +
213-
(u32)p_chain->u.chain16.prod_idx) -
214-
(u32)p_chain->u.chain16.cons_idx);
215+
if (prod < cons)
216+
prod += (u32)U16_MAX + 1;
217+
218+
used = (u16)(prod - cons);
215219
if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR)
216-
used -= p_chain->u.chain16.prod_idx / p_chain->elem_per_page -
217-
p_chain->u.chain16.cons_idx / p_chain->elem_per_page;
220+
used -= prod / elem_per_page - cons / elem_per_page;
218221

219222
return (u16)(p_chain->capacity - used);
220223
}
221224

222225
static inline u32 qed_chain_get_elem_left_u32(struct qed_chain *p_chain)
223226
{
227+
u16 elem_per_page = p_chain->elem_per_page;
228+
u64 prod = p_chain->u.chain32.prod_idx;
229+
u64 cons = p_chain->u.chain32.cons_idx;
224230
u32 used;
225231

226-
used = (u32) (((u64)0x100000000ULL +
227-
(u64)p_chain->u.chain32.prod_idx) -
228-
(u64)p_chain->u.chain32.cons_idx);
232+
if (prod < cons)
233+
prod += (u64)U32_MAX + 1;
234+
235+
used = (u32)(prod - cons);
229236
if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR)
230-
used -= p_chain->u.chain32.prod_idx / p_chain->elem_per_page -
231-
p_chain->u.chain32.cons_idx / p_chain->elem_per_page;
237+
used -= (u32)(prod / elem_per_page - cons / elem_per_page);
232238

233239
return p_chain->capacity - used;
234240
}

0 commit comments

Comments
 (0)