at803x: double check SGMII side autoneg
[cascardo/linux.git] / lib / sbitmap.c
index 928b82a..2cecf05 100644 (file)
@@ -169,7 +169,7 @@ EXPORT_SYMBOL_GPL(sbitmap_any_bit_clear);
 
 unsigned int sbitmap_weight(const struct sbitmap *sb)
 {
-       unsigned int i, weight;
+       unsigned int i, weight = 0;
 
        for (i = 0; i < sb->map_nr; i++) {
                const struct sbitmap_word *word = &sb->map[i];
@@ -246,10 +246,15 @@ EXPORT_SYMBOL_GPL(sbitmap_queue_resize);
 
 int __sbitmap_queue_get(struct sbitmap_queue *sbq)
 {
-       unsigned int hint;
+       unsigned int hint, depth;
        int nr;
 
        hint = this_cpu_read(*sbq->alloc_hint);
+       depth = READ_ONCE(sbq->sb.depth);
+       if (unlikely(hint >= depth)) {
+               hint = depth ? prandom_u32() % depth : 0;
+               this_cpu_write(*sbq->alloc_hint, hint);
+       }
        nr = sbitmap_get(&sbq->sb, hint, sbq->round_robin);
 
        if (nr == -1) {
@@ -258,7 +263,7 @@ int __sbitmap_queue_get(struct sbitmap_queue *sbq)
        } else if (nr == hint || unlikely(sbq->round_robin)) {
                /* Only update the hint if we used it. */
                hint = nr + 1;
-               if (hint >= sbq->sb.depth - 1)
+               if (hint >= depth - 1)
                        hint = 0;
                this_cpu_write(*sbq->alloc_hint, hint);
        }
@@ -316,7 +321,7 @@ void sbitmap_queue_clear(struct sbitmap_queue *sbq, unsigned int nr,
 {
        sbitmap_clear_bit(&sbq->sb, nr);
        sbq_wake_up(sbq);
-       if (likely(!sbq->round_robin))
+       if (likely(!sbq->round_robin && nr < sbq->sb.depth))
                *per_cpu_ptr(sbq->alloc_hint, cpu) = nr;
 }
 EXPORT_SYMBOL_GPL(sbitmap_queue_clear);