percpu_ida: add percpu_ida_for_each_free
Add a new API to iterate free ids. blk-mq-tag will use it. Note, this doesn't guarantee to iterate all free ids restrictly. Caller should be aware of this. blk-mq uses it to do sanity check for request timedout, so can tolerate the limitation. Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Shaohua Li <shli@fusionio.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
e26b53d0b2
commit
7fc2ba17e8
|
@ -73,4 +73,8 @@ static inline int percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags
|
|||
IDA_DEFAULT_PCPU_BATCH_MOVE);
|
||||
}
|
||||
|
||||
typedef int (*percpu_ida_cb)(unsigned, void *);
|
||||
int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn,
|
||||
void *data);
|
||||
|
||||
#endif /* __PERCPU_IDA_H__ */
|
||||
|
|
|
@ -327,3 +327,47 @@ err:
|
|||
return -ENOMEM;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__percpu_ida_init);
|
||||
|
||||
/**
|
||||
* percpu_ida_for_each_free - iterate free ids of a pool
|
||||
* @pool: pool to iterate
|
||||
* @fn: interate callback function
|
||||
* @data: parameter for @fn
|
||||
*
|
||||
* Note, this doesn't guarantee to iterate all free ids restrictly. Some free
|
||||
* ids might be missed, some might be iterated duplicated, and some might
|
||||
* be iterated and not free soon.
|
||||
*/
|
||||
int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn,
|
||||
void *data)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct percpu_ida_cpu *remote;
|
||||
unsigned cpu, i, err = 0;
|
||||
|
||||
local_irq_save(flags);
|
||||
for_each_possible_cpu(cpu) {
|
||||
remote = per_cpu_ptr(pool->tag_cpu, cpu);
|
||||
spin_lock(&remote->lock);
|
||||
for (i = 0; i < remote->nr_free; i++) {
|
||||
err = fn(remote->freelist[i], data);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
spin_unlock(&remote->lock);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock(&pool->lock);
|
||||
for (i = 0; i < pool->nr_free; i++) {
|
||||
err = fn(pool->freelist[i], data);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
spin_unlock(&pool->lock);
|
||||
out:
|
||||
local_irq_restore(flags);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(percpu_ida_for_each_free);
|
||||
|
|
Loading…
Reference in New Issue