sbitmap: push per-cpu last_tag into sbitmap_queue
Allocating your own per-cpu allocation hint separately makes for an awkward API. Instead, allocate the per-cpu hint as part of the struct sbitmap_queue. There's no point for a struct sbitmap_queue without the cache, but you can still use a bare struct sbitmap. Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
parent
48e28166a7
commit
40aabb6746
6 changed files with 98 additions and 42 deletions
|
@ -205,11 +205,18 @@ int sbitmap_queue_init_node(struct sbitmap_queue *sbq, unsigned int depth,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
sbq->alloc_hint = alloc_percpu_gfp(unsigned int, flags);
|
||||
if (!sbq->alloc_hint) {
|
||||
sbitmap_free(&sbq->sb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sbq->wake_batch = sbq_calc_wake_batch(depth);
|
||||
atomic_set(&sbq->wake_index, 0);
|
||||
|
||||
sbq->ws = kzalloc_node(SBQ_WAIT_QUEUES * sizeof(*sbq->ws), flags, node);
|
||||
if (!sbq->ws) {
|
||||
free_percpu(sbq->alloc_hint);
|
||||
sbitmap_free(&sbq->sb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -229,6 +236,29 @@ void sbitmap_queue_resize(struct sbitmap_queue *sbq, unsigned int depth)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(sbitmap_queue_resize);
|
||||
|
||||
int __sbitmap_queue_get(struct sbitmap_queue *sbq, bool round_robin)
|
||||
{
|
||||
unsigned int hint;
|
||||
int nr;
|
||||
|
||||
hint = this_cpu_read(*sbq->alloc_hint);
|
||||
nr = sbitmap_get(&sbq->sb, hint, round_robin);
|
||||
|
||||
if (nr == -1) {
|
||||
/* If the map is full, a hint won't do us much good. */
|
||||
this_cpu_write(*sbq->alloc_hint, 0);
|
||||
} else if (nr == hint || unlikely(round_robin)) {
|
||||
/* Only update the hint if we used it. */
|
||||
hint = nr + 1;
|
||||
if (hint >= sbq->sb.depth - 1)
|
||||
hint = 0;
|
||||
this_cpu_write(*sbq->alloc_hint, hint);
|
||||
}
|
||||
|
||||
return nr;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__sbitmap_queue_get);
|
||||
|
||||
static struct sbq_wait_state *sbq_wake_ptr(struct sbitmap_queue *sbq)
|
||||
{
|
||||
int i, wake_index;
|
||||
|
@ -273,10 +303,13 @@ static void sbq_wake_up(struct sbitmap_queue *sbq)
|
|||
}
|
||||
}
|
||||
|
||||
void sbitmap_queue_clear(struct sbitmap_queue *sbq, unsigned int nr)
|
||||
void sbitmap_queue_clear(struct sbitmap_queue *sbq, unsigned int nr,
|
||||
bool round_robin, unsigned int cpu)
|
||||
{
|
||||
sbitmap_clear_bit(&sbq->sb, nr);
|
||||
sbq_wake_up(sbq);
|
||||
if (likely(!round_robin))
|
||||
*per_cpu_ptr(sbq->alloc_hint, cpu) = nr;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sbitmap_queue_clear);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue