Messages in this thread Patch in this message | | | Subject | Re: 4.5.0+ panic when setup loop device | From | Jens Axboe <> | Date | Thu, 17 Mar 2016 11:26:20 -0700 |
| |
On 03/17/2016 09:42 AM, Jens Axboe wrote: > On 03/17/2016 05:01 AM, Thomas Gleixner wrote: >> On Thu, 17 Mar 2016, Peter Zijlstra wrote: >>> On Thu, Mar 17, 2016 at 12:39:46PM +0100, Thomas Gleixner wrote: >>>> But we have to clarify and document whether holes in >>>> cpu_possible_mask are not >>>> allowed at all or if code like the above is simply broken. >>> >>> So the general rule is that cpumasks can have holes, and exempting one >>> just muddles the water. >>> >>> Therefore I'd call the code just plain broken. >> >> Agreed. >> >> That macro is not really helping the readability of the code at all. So a >> simple for_each_possible_cpu() loop would have avoided that wreckage. > > Does the attached work? The rest of blk-mq should deal with holes just > fine, we found some of those issues on sparc. Not sure why this one > slipped through the cracks.
This might be better, we need to start at -1 to not miss the first one... Still untested.
-- Jens Axboe
diff --git a/block/blk-mq.h b/block/blk-mq.h index eaede8e45c9c..ce68ceda652c 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h @@ -118,4 +118,22 @@ static inline bool blk_mq_hw_queue_mapped(struct blk_mq_hw_ctx *hctx) return hctx->nr_ctx && hctx->tags; } +static inline struct blk_mq_ctx *next_ctx(struct request_queue *q, int *i) +{ + do { + (*i)++; + if (*i < q->nr_queues) { + if (cpu_possible(*i)) + return per_cpu_ptr(q->queue_ctx, *i); + continue; + } + break; + } while (1); + + return NULL; +} + +#define queue_for_each_ctx(q, ctx, i) \ + for ((i) = -1; (ctx = next_ctx((q), &(i))) != NULL;) + #endif diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 7fc9296b5742..a8756cd00767 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -261,22 +261,8 @@ static inline void *blk_mq_rq_to_pdu(struct request *rq) for ((i) = 0; (i) < (q)->nr_hw_queues && \ ({ hctx = (q)->queue_hw_ctx[i]; 1; }); (i)++) -#define queue_for_each_ctx(q, ctx, i) \ - for ((i) = 0; (i) < (q)->nr_queues && \ - ({ ctx = per_cpu_ptr((q)->queue_ctx, (i)); 1; }); (i)++) - #define hctx_for_each_ctx(hctx, ctx, i) \ for ((i) = 0; (i) < (hctx)->nr_ctx && \ ({ ctx = (hctx)->ctxs[(i)]; 1; }); (i)++) -#define blk_ctx_sum(q, sum) \ -({ \ - struct blk_mq_ctx *__x; \ - unsigned int __ret = 0, __i; \ - \ - queue_for_each_ctx((q), __x, __i) \ - __ret += sum; \ - __ret; \ -}) - #endif | |