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.
Showing the changes to include/linux (1 of 1 file). Show all
Unified · Split
| @@ -207,28 +207,34 @@ static inline u32 qed_chain_get_cons_idx_u32(struct qed_chain *p_chain) · 206 unmodified lines | |||
| 207 | 207 | ||
| 208 | static inline u16 qed_chain_get_elem_left(struct qed_chain *p_chain) | 208 | static inline u16 qed_chain_get_elem_left(struct qed_chain *p_chain) |
| 209 | { | 209 | { |
| 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; | ||
| 210 | u16 used; | 213 | u16 used; |
| 211 | 214 | ||
| 212 | used = (u16) (((u32)0x10000 + | 215 | if (prod < cons) |
| 213 | (u32)p_chain->u.chain16.prod_idx) - | 216 | prod += (u32)U16_MAX + 1; |
| 214 | (u32)p_chain->u.chain16.cons_idx); | 217 | |
| 218 | used = (u16)(prod - cons); | ||
| 215 | if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR) | 219 | if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR) |
| 216 | used -= p_chain->u.chain16.prod_idx / p_chain->elem_per_page - | 220 | used -= prod / elem_per_page - cons / elem_per_page; |
| 217 | p_chain->u.chain16.cons_idx / p_chain->elem_per_page; | ||
| 218 | 221 | ||
| 219 | return (u16)(p_chain->capacity - used); | 222 | return (u16)(p_chain->capacity - used); |
| 220 | } | 223 | } |
| 221 | 224 | ||
| 222 | static inline u32 qed_chain_get_elem_left_u32(struct qed_chain *p_chain) | 225 | static inline u32 qed_chain_get_elem_left_u32(struct qed_chain *p_chain) |
| 223 | { | 226 | { |
| 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; | ||
| 224 | u32 used; | 230 | u32 used; |
| 225 | 231 | ||
| 226 | used = (u32) (((u64)0x100000000ULL + | 232 | if (prod < cons) |
| 227 | (u64)p_chain->u.chain32.prod_idx) - | 233 | prod += (u64)U32_MAX + 1; |
| 228 | (u64)p_chain->u.chain32.cons_idx); | 234 | |
| 235 | used = (u32)(prod - cons); | ||
| 229 | if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR) | 236 | if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR) |
| 230 | used -= p_chain->u.chain32.prod_idx / p_chain->elem_per_page - | 237 | used -= (u32)(prod / elem_per_page - cons / elem_per_page); |
| 231 | p_chain->u.chain32.cons_idx / p_chain->elem_per_page; | ||
| 232 | 238 | ||
| 233 | return p_chain->capacity - used; | 239 | return p_chain->capacity - used; |
| 234 | } | 240 | } |