mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-24 17:23:25 -05:00
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
2 changed files with 48 additions and 0 deletions
|
@ -73,4 +73,8 @@ static inline int percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags
|
||||||
IDA_DEFAULT_PCPU_BATCH_MOVE);
|
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__ */
|
#endif /* __PERCPU_IDA_H__ */
|
||||||
|
|
|
@ -327,3 +327,47 @@ err:
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__percpu_ida_init);
|
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…
Add table
Reference in a new issue