LCOV - code coverage report
Current view: top level - lib - sbitmap.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 328 0.0 %
Date: 2023-03-27 20:00:47 Functions: 0 34 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  * Copyright (C) 2016 Facebook
       4             :  * Copyright (C) 2013-2014 Jens Axboe
       5             :  */
       6             : 
       7             : #include <linux/sched.h>
       8             : #include <linux/random.h>
       9             : #include <linux/sbitmap.h>
      10             : #include <linux/seq_file.h>
      11             : 
      12           0 : static int init_alloc_hint(struct sbitmap *sb, gfp_t flags)
      13             : {
      14           0 :         unsigned depth = sb->depth;
      15             : 
      16           0 :         sb->alloc_hint = alloc_percpu_gfp(unsigned int, flags);
      17           0 :         if (!sb->alloc_hint)
      18             :                 return -ENOMEM;
      19             : 
      20           0 :         if (depth && !sb->round_robin) {
      21             :                 int i;
      22             : 
      23           0 :                 for_each_possible_cpu(i)
      24           0 :                         *per_cpu_ptr(sb->alloc_hint, i) = get_random_u32_below(depth);
      25             :         }
      26             :         return 0;
      27             : }
      28             : 
      29           0 : static inline unsigned update_alloc_hint_before_get(struct sbitmap *sb,
      30             :                                                     unsigned int depth)
      31             : {
      32             :         unsigned hint;
      33             : 
      34           0 :         hint = this_cpu_read(*sb->alloc_hint);
      35           0 :         if (unlikely(hint >= depth)) {
      36           0 :                 hint = depth ? get_random_u32_below(depth) : 0;
      37           0 :                 this_cpu_write(*sb->alloc_hint, hint);
      38             :         }
      39             : 
      40           0 :         return hint;
      41             : }
      42             : 
      43           0 : static inline void update_alloc_hint_after_get(struct sbitmap *sb,
      44             :                                                unsigned int depth,
      45             :                                                unsigned int hint,
      46             :                                                unsigned int nr)
      47             : {
      48           0 :         if (nr == -1) {
      49             :                 /* If the map is full, a hint won't do us much good. */
      50           0 :                 this_cpu_write(*sb->alloc_hint, 0);
      51           0 :         } else if (nr == hint || unlikely(sb->round_robin)) {
      52             :                 /* Only update the hint if we used it. */
      53           0 :                 hint = nr + 1;
      54           0 :                 if (hint >= depth - 1)
      55           0 :                         hint = 0;
      56           0 :                 this_cpu_write(*sb->alloc_hint, hint);
      57             :         }
      58           0 : }
      59             : 
      60             : /*
      61             :  * See if we have deferred clears that we can batch move
      62             :  */
      63             : static inline bool sbitmap_deferred_clear(struct sbitmap_word *map)
      64             : {
      65             :         unsigned long mask;
      66             : 
      67           0 :         if (!READ_ONCE(map->cleared))
      68             :                 return false;
      69             : 
      70             :         /*
      71             :          * First get a stable cleared mask, setting the old mask to 0.
      72             :          */
      73           0 :         mask = xchg(&map->cleared, 0);
      74             : 
      75             :         /*
      76             :          * Now clear the masked bits in our free word
      77             :          */
      78           0 :         atomic_long_andnot(mask, (atomic_long_t *)&map->word);
      79             :         BUILD_BUG_ON(sizeof(atomic_long_t) != sizeof(map->word));
      80             :         return true;
      81             : }
      82             : 
      83           0 : int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift,
      84             :                       gfp_t flags, int node, bool round_robin,
      85             :                       bool alloc_hint)
      86             : {
      87             :         unsigned int bits_per_word;
      88             : 
      89           0 :         if (shift < 0)
      90             :                 shift = sbitmap_calculate_shift(depth);
      91             : 
      92           0 :         bits_per_word = 1U << shift;
      93           0 :         if (bits_per_word > BITS_PER_LONG)
      94             :                 return -EINVAL;
      95             : 
      96           0 :         sb->shift = shift;
      97           0 :         sb->depth = depth;
      98           0 :         sb->map_nr = DIV_ROUND_UP(sb->depth, bits_per_word);
      99           0 :         sb->round_robin = round_robin;
     100             : 
     101           0 :         if (depth == 0) {
     102           0 :                 sb->map = NULL;
     103           0 :                 return 0;
     104             :         }
     105             : 
     106           0 :         if (alloc_hint) {
     107           0 :                 if (init_alloc_hint(sb, flags))
     108             :                         return -ENOMEM;
     109             :         } else {
     110           0 :                 sb->alloc_hint = NULL;
     111             :         }
     112             : 
     113           0 :         sb->map = kvzalloc_node(sb->map_nr * sizeof(*sb->map), flags, node);
     114           0 :         if (!sb->map) {
     115           0 :                 free_percpu(sb->alloc_hint);
     116           0 :                 return -ENOMEM;
     117             :         }
     118             : 
     119             :         return 0;
     120             : }
     121             : EXPORT_SYMBOL_GPL(sbitmap_init_node);
     122             : 
     123           0 : void sbitmap_resize(struct sbitmap *sb, unsigned int depth)
     124             : {
     125           0 :         unsigned int bits_per_word = 1U << sb->shift;
     126             :         unsigned int i;
     127             : 
     128           0 :         for (i = 0; i < sb->map_nr; i++)
     129           0 :                 sbitmap_deferred_clear(&sb->map[i]);
     130             : 
     131           0 :         sb->depth = depth;
     132           0 :         sb->map_nr = DIV_ROUND_UP(sb->depth, bits_per_word);
     133           0 : }
     134             : EXPORT_SYMBOL_GPL(sbitmap_resize);
     135             : 
     136           0 : static int __sbitmap_get_word(unsigned long *word, unsigned long depth,
     137             :                               unsigned int hint, bool wrap)
     138             : {
     139             :         int nr;
     140             : 
     141             :         /* don't wrap if starting from 0 */
     142           0 :         wrap = wrap && hint;
     143             : 
     144             :         while (1) {
     145           0 :                 nr = find_next_zero_bit(word, depth, hint);
     146           0 :                 if (unlikely(nr >= depth)) {
     147             :                         /*
     148             :                          * We started with an offset, and we didn't reset the
     149             :                          * offset to 0 in a failure case, so start from 0 to
     150             :                          * exhaust the map.
     151             :                          */
     152           0 :                         if (hint && wrap) {
     153           0 :                                 hint = 0;
     154           0 :                                 continue;
     155             :                         }
     156             :                         return -1;
     157             :                 }
     158             : 
     159           0 :                 if (!test_and_set_bit_lock(nr, word))
     160             :                         break;
     161             : 
     162           0 :                 hint = nr + 1;
     163           0 :                 if (hint >= depth - 1)
     164           0 :                         hint = 0;
     165             :         }
     166             : 
     167             :         return nr;
     168             : }
     169             : 
     170           0 : static int sbitmap_find_bit_in_word(struct sbitmap_word *map,
     171             :                                     unsigned int depth,
     172             :                                     unsigned int alloc_hint,
     173             :                                     bool wrap)
     174             : {
     175             :         int nr;
     176             : 
     177             :         do {
     178           0 :                 nr = __sbitmap_get_word(&map->word, depth,
     179             :                                         alloc_hint, wrap);
     180           0 :                 if (nr != -1)
     181             :                         break;
     182           0 :                 if (!sbitmap_deferred_clear(map))
     183             :                         break;
     184             :         } while (1);
     185             : 
     186           0 :         return nr;
     187             : }
     188             : 
     189           0 : static int sbitmap_find_bit(struct sbitmap *sb,
     190             :                             unsigned int depth,
     191             :                             unsigned int index,
     192             :                             unsigned int alloc_hint,
     193             :                             bool wrap)
     194             : {
     195             :         unsigned int i;
     196           0 :         int nr = -1;
     197             : 
     198           0 :         for (i = 0; i < sb->map_nr; i++) {
     199           0 :                 nr = sbitmap_find_bit_in_word(&sb->map[index],
     200           0 :                                               min_t(unsigned int,
     201             :                                                     __map_depth(sb, index),
     202             :                                                     depth),
     203             :                                               alloc_hint, wrap);
     204             : 
     205           0 :                 if (nr != -1) {
     206           0 :                         nr += index << sb->shift;
     207           0 :                         break;
     208             :                 }
     209             : 
     210             :                 /* Jump to next index. */
     211           0 :                 alloc_hint = 0;
     212           0 :                 if (++index >= sb->map_nr)
     213           0 :                         index = 0;
     214             :         }
     215             : 
     216           0 :         return nr;
     217             : }
     218             : 
     219           0 : static int __sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint)
     220             : {
     221             :         unsigned int index;
     222             : 
     223           0 :         index = SB_NR_TO_INDEX(sb, alloc_hint);
     224             : 
     225             :         /*
     226             :          * Unless we're doing round robin tag allocation, just use the
     227             :          * alloc_hint to find the right word index. No point in looping
     228             :          * twice in find_next_zero_bit() for that case.
     229             :          */
     230           0 :         if (sb->round_robin)
     231           0 :                 alloc_hint = SB_NR_TO_BIT(sb, alloc_hint);
     232             :         else
     233             :                 alloc_hint = 0;
     234             : 
     235           0 :         return sbitmap_find_bit(sb, UINT_MAX, index, alloc_hint,
     236           0 :                                 !sb->round_robin);
     237             : }
     238             : 
     239           0 : int sbitmap_get(struct sbitmap *sb)
     240             : {
     241             :         int nr;
     242             :         unsigned int hint, depth;
     243             : 
     244           0 :         if (WARN_ON_ONCE(unlikely(!sb->alloc_hint)))
     245             :                 return -1;
     246             : 
     247           0 :         depth = READ_ONCE(sb->depth);
     248           0 :         hint = update_alloc_hint_before_get(sb, depth);
     249           0 :         nr = __sbitmap_get(sb, hint);
     250           0 :         update_alloc_hint_after_get(sb, depth, hint, nr);
     251             : 
     252           0 :         return nr;
     253             : }
     254             : EXPORT_SYMBOL_GPL(sbitmap_get);
     255             : 
     256             : static int __sbitmap_get_shallow(struct sbitmap *sb,
     257             :                                  unsigned int alloc_hint,
     258             :                                  unsigned long shallow_depth)
     259             : {
     260             :         unsigned int index;
     261             : 
     262           0 :         index = SB_NR_TO_INDEX(sb, alloc_hint);
     263           0 :         alloc_hint = SB_NR_TO_BIT(sb, alloc_hint);
     264             : 
     265           0 :         return sbitmap_find_bit(sb, shallow_depth, index, alloc_hint, true);
     266             : }
     267             : 
     268           0 : int sbitmap_get_shallow(struct sbitmap *sb, unsigned long shallow_depth)
     269             : {
     270             :         int nr;
     271             :         unsigned int hint, depth;
     272             : 
     273           0 :         if (WARN_ON_ONCE(unlikely(!sb->alloc_hint)))
     274             :                 return -1;
     275             : 
     276           0 :         depth = READ_ONCE(sb->depth);
     277           0 :         hint = update_alloc_hint_before_get(sb, depth);
     278           0 :         nr = __sbitmap_get_shallow(sb, hint, shallow_depth);
     279           0 :         update_alloc_hint_after_get(sb, depth, hint, nr);
     280             : 
     281           0 :         return nr;
     282             : }
     283             : EXPORT_SYMBOL_GPL(sbitmap_get_shallow);
     284             : 
     285           0 : bool sbitmap_any_bit_set(const struct sbitmap *sb)
     286             : {
     287             :         unsigned int i;
     288             : 
     289           0 :         for (i = 0; i < sb->map_nr; i++) {
     290           0 :                 if (sb->map[i].word & ~sb->map[i].cleared)
     291             :                         return true;
     292             :         }
     293             :         return false;
     294             : }
     295             : EXPORT_SYMBOL_GPL(sbitmap_any_bit_set);
     296             : 
     297           0 : static unsigned int __sbitmap_weight(const struct sbitmap *sb, bool set)
     298             : {
     299           0 :         unsigned int i, weight = 0;
     300             : 
     301           0 :         for (i = 0; i < sb->map_nr; i++) {
     302           0 :                 const struct sbitmap_word *word = &sb->map[i];
     303           0 :                 unsigned int word_depth = __map_depth(sb, i);
     304             : 
     305           0 :                 if (set)
     306           0 :                         weight += bitmap_weight(&word->word, word_depth);
     307             :                 else
     308           0 :                         weight += bitmap_weight(&word->cleared, word_depth);
     309             :         }
     310           0 :         return weight;
     311             : }
     312             : 
     313             : static unsigned int sbitmap_cleared(const struct sbitmap *sb)
     314             : {
     315           0 :         return __sbitmap_weight(sb, false);
     316             : }
     317             : 
     318           0 : unsigned int sbitmap_weight(const struct sbitmap *sb)
     319             : {
     320           0 :         return __sbitmap_weight(sb, true) - sbitmap_cleared(sb);
     321             : }
     322             : EXPORT_SYMBOL_GPL(sbitmap_weight);
     323             : 
     324           0 : void sbitmap_show(struct sbitmap *sb, struct seq_file *m)
     325             : {
     326           0 :         seq_printf(m, "depth=%u\n", sb->depth);
     327           0 :         seq_printf(m, "busy=%u\n", sbitmap_weight(sb));
     328           0 :         seq_printf(m, "cleared=%u\n", sbitmap_cleared(sb));
     329           0 :         seq_printf(m, "bits_per_word=%u\n", 1U << sb->shift);
     330           0 :         seq_printf(m, "map_nr=%u\n", sb->map_nr);
     331           0 : }
     332             : EXPORT_SYMBOL_GPL(sbitmap_show);
     333             : 
     334           0 : static inline void emit_byte(struct seq_file *m, unsigned int offset, u8 byte)
     335             : {
     336           0 :         if ((offset & 0xf) == 0) {
     337           0 :                 if (offset != 0)
     338           0 :                         seq_putc(m, '\n');
     339           0 :                 seq_printf(m, "%08x:", offset);
     340             :         }
     341           0 :         if ((offset & 0x1) == 0)
     342           0 :                 seq_putc(m, ' ');
     343           0 :         seq_printf(m, "%02x", byte);
     344           0 : }
     345             : 
     346           0 : void sbitmap_bitmap_show(struct sbitmap *sb, struct seq_file *m)
     347             : {
     348           0 :         u8 byte = 0;
     349           0 :         unsigned int byte_bits = 0;
     350           0 :         unsigned int offset = 0;
     351             :         int i;
     352             : 
     353           0 :         for (i = 0; i < sb->map_nr; i++) {
     354           0 :                 unsigned long word = READ_ONCE(sb->map[i].word);
     355           0 :                 unsigned long cleared = READ_ONCE(sb->map[i].cleared);
     356           0 :                 unsigned int word_bits = __map_depth(sb, i);
     357             : 
     358           0 :                 word &= ~cleared;
     359             : 
     360           0 :                 while (word_bits > 0) {
     361           0 :                         unsigned int bits = min(8 - byte_bits, word_bits);
     362             : 
     363           0 :                         byte |= (word & (BIT(bits) - 1)) << byte_bits;
     364           0 :                         byte_bits += bits;
     365           0 :                         if (byte_bits == 8) {
     366           0 :                                 emit_byte(m, offset, byte);
     367           0 :                                 byte = 0;
     368           0 :                                 byte_bits = 0;
     369           0 :                                 offset++;
     370             :                         }
     371           0 :                         word >>= bits;
     372           0 :                         word_bits -= bits;
     373             :                 }
     374             :         }
     375           0 :         if (byte_bits) {
     376           0 :                 emit_byte(m, offset, byte);
     377           0 :                 offset++;
     378             :         }
     379           0 :         if (offset)
     380           0 :                 seq_putc(m, '\n');
     381           0 : }
     382             : EXPORT_SYMBOL_GPL(sbitmap_bitmap_show);
     383             : 
     384             : static unsigned int sbq_calc_wake_batch(struct sbitmap_queue *sbq,
     385             :                                         unsigned int depth)
     386             : {
     387             :         unsigned int wake_batch;
     388             :         unsigned int shallow_depth;
     389             : 
     390             :         /*
     391             :          * For each batch, we wake up one queue. We need to make sure that our
     392             :          * batch size is small enough that the full depth of the bitmap,
     393             :          * potentially limited by a shallow depth, is enough to wake up all of
     394             :          * the queues.
     395             :          *
     396             :          * Each full word of the bitmap has bits_per_word bits, and there might
     397             :          * be a partial word. There are depth / bits_per_word full words and
     398             :          * depth % bits_per_word bits left over. In bitwise arithmetic:
     399             :          *
     400             :          * bits_per_word = 1 << shift
     401             :          * depth / bits_per_word = depth >> shift
     402             :          * depth % bits_per_word = depth & ((1 << shift) - 1)
     403             :          *
     404             :          * Each word can be limited to sbq->min_shallow_depth bits.
     405             :          */
     406           0 :         shallow_depth = min(1U << sbq->sb.shift, sbq->min_shallow_depth);
     407           0 :         depth = ((depth >> sbq->sb.shift) * shallow_depth +
     408           0 :                  min(depth & ((1U << sbq->sb.shift) - 1), shallow_depth));
     409           0 :         wake_batch = clamp_t(unsigned int, depth / SBQ_WAIT_QUEUES, 1,
     410             :                              SBQ_WAKE_BATCH);
     411             : 
     412             :         return wake_batch;
     413             : }
     414             : 
     415           0 : int sbitmap_queue_init_node(struct sbitmap_queue *sbq, unsigned int depth,
     416             :                             int shift, bool round_robin, gfp_t flags, int node)
     417             : {
     418             :         int ret;
     419             :         int i;
     420             : 
     421           0 :         ret = sbitmap_init_node(&sbq->sb, depth, shift, flags, node,
     422             :                                 round_robin, true);
     423           0 :         if (ret)
     424             :                 return ret;
     425             : 
     426           0 :         sbq->min_shallow_depth = UINT_MAX;
     427           0 :         sbq->wake_batch = sbq_calc_wake_batch(sbq, depth);
     428           0 :         atomic_set(&sbq->wake_index, 0);
     429           0 :         atomic_set(&sbq->ws_active, 0);
     430           0 :         atomic_set(&sbq->completion_cnt, 0);
     431           0 :         atomic_set(&sbq->wakeup_cnt, 0);
     432             : 
     433           0 :         sbq->ws = kzalloc_node(SBQ_WAIT_QUEUES * sizeof(*sbq->ws), flags, node);
     434           0 :         if (!sbq->ws) {
     435           0 :                 sbitmap_free(&sbq->sb);
     436           0 :                 return -ENOMEM;
     437             :         }
     438             : 
     439           0 :         for (i = 0; i < SBQ_WAIT_QUEUES; i++)
     440           0 :                 init_waitqueue_head(&sbq->ws[i].wait);
     441             : 
     442             :         return 0;
     443             : }
     444             : EXPORT_SYMBOL_GPL(sbitmap_queue_init_node);
     445             : 
     446             : static void sbitmap_queue_update_wake_batch(struct sbitmap_queue *sbq,
     447             :                                             unsigned int depth)
     448             : {
     449             :         unsigned int wake_batch;
     450             : 
     451           0 :         wake_batch = sbq_calc_wake_batch(sbq, depth);
     452           0 :         if (sbq->wake_batch != wake_batch)
     453           0 :                 WRITE_ONCE(sbq->wake_batch, wake_batch);
     454             : }
     455             : 
     456           0 : void sbitmap_queue_recalculate_wake_batch(struct sbitmap_queue *sbq,
     457             :                                             unsigned int users)
     458             : {
     459             :         unsigned int wake_batch;
     460           0 :         unsigned int depth = (sbq->sb.depth + users - 1) / users;
     461             : 
     462           0 :         wake_batch = clamp_val(depth / SBQ_WAIT_QUEUES,
     463             :                         1, SBQ_WAKE_BATCH);
     464             : 
     465           0 :         WRITE_ONCE(sbq->wake_batch, wake_batch);
     466           0 : }
     467             : EXPORT_SYMBOL_GPL(sbitmap_queue_recalculate_wake_batch);
     468             : 
     469           0 : void sbitmap_queue_resize(struct sbitmap_queue *sbq, unsigned int depth)
     470             : {
     471           0 :         sbitmap_queue_update_wake_batch(sbq, depth);
     472           0 :         sbitmap_resize(&sbq->sb, depth);
     473           0 : }
     474             : EXPORT_SYMBOL_GPL(sbitmap_queue_resize);
     475             : 
     476           0 : int __sbitmap_queue_get(struct sbitmap_queue *sbq)
     477             : {
     478           0 :         return sbitmap_get(&sbq->sb);
     479             : }
     480             : EXPORT_SYMBOL_GPL(__sbitmap_queue_get);
     481             : 
     482           0 : unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags,
     483             :                                         unsigned int *offset)
     484             : {
     485           0 :         struct sbitmap *sb = &sbq->sb;
     486             :         unsigned int hint, depth;
     487             :         unsigned long index, nr;
     488             :         int i;
     489             : 
     490           0 :         if (unlikely(sb->round_robin))
     491             :                 return 0;
     492             : 
     493           0 :         depth = READ_ONCE(sb->depth);
     494           0 :         hint = update_alloc_hint_before_get(sb, depth);
     495             : 
     496           0 :         index = SB_NR_TO_INDEX(sb, hint);
     497             : 
     498           0 :         for (i = 0; i < sb->map_nr; i++) {
     499           0 :                 struct sbitmap_word *map = &sb->map[index];
     500             :                 unsigned long get_mask;
     501           0 :                 unsigned int map_depth = __map_depth(sb, index);
     502             : 
     503           0 :                 sbitmap_deferred_clear(map);
     504           0 :                 if (map->word == (1UL << (map_depth - 1)) - 1)
     505             :                         goto next;
     506             : 
     507           0 :                 nr = find_first_zero_bit(&map->word, map_depth);
     508           0 :                 if (nr + nr_tags <= map_depth) {
     509           0 :                         atomic_long_t *ptr = (atomic_long_t *) &map->word;
     510             :                         unsigned long val;
     511             : 
     512           0 :                         get_mask = ((1UL << nr_tags) - 1) << nr;
     513           0 :                         val = READ_ONCE(map->word);
     514           0 :                         while (!atomic_long_try_cmpxchg(ptr, &val,
     515           0 :                                                           get_mask | val))
     516             :                                 ;
     517           0 :                         get_mask = (get_mask & ~val) >> nr;
     518           0 :                         if (get_mask) {
     519           0 :                                 *offset = nr + (index << sb->shift);
     520           0 :                                 update_alloc_hint_after_get(sb, depth, hint,
     521           0 :                                                         *offset + nr_tags - 1);
     522           0 :                                 return get_mask;
     523             :                         }
     524             :                 }
     525             : next:
     526             :                 /* Jump to next index. */
     527           0 :                 if (++index >= sb->map_nr)
     528           0 :                         index = 0;
     529             :         }
     530             : 
     531             :         return 0;
     532             : }
     533             : 
     534           0 : int sbitmap_queue_get_shallow(struct sbitmap_queue *sbq,
     535             :                               unsigned int shallow_depth)
     536             : {
     537           0 :         WARN_ON_ONCE(shallow_depth < sbq->min_shallow_depth);
     538             : 
     539           0 :         return sbitmap_get_shallow(&sbq->sb, shallow_depth);
     540             : }
     541             : EXPORT_SYMBOL_GPL(sbitmap_queue_get_shallow);
     542             : 
     543           0 : void sbitmap_queue_min_shallow_depth(struct sbitmap_queue *sbq,
     544             :                                      unsigned int min_shallow_depth)
     545             : {
     546           0 :         sbq->min_shallow_depth = min_shallow_depth;
     547           0 :         sbitmap_queue_update_wake_batch(sbq, sbq->sb.depth);
     548           0 : }
     549             : EXPORT_SYMBOL_GPL(sbitmap_queue_min_shallow_depth);
     550             : 
     551           0 : static void __sbitmap_queue_wake_up(struct sbitmap_queue *sbq, int nr)
     552             : {
     553             :         int i, wake_index;
     554             : 
     555           0 :         if (!atomic_read(&sbq->ws_active))
     556             :                 return;
     557             : 
     558           0 :         wake_index = atomic_read(&sbq->wake_index);
     559           0 :         for (i = 0; i < SBQ_WAIT_QUEUES; i++) {
     560           0 :                 struct sbq_wait_state *ws = &sbq->ws[wake_index];
     561             : 
     562             :                 /*
     563             :                  * Advance the index before checking the current queue.
     564             :                  * It improves fairness, by ensuring the queue doesn't
     565             :                  * need to be fully emptied before trying to wake up
     566             :                  * from the next one.
     567             :                  */
     568           0 :                 wake_index = sbq_index_inc(wake_index);
     569             : 
     570             :                 /*
     571             :                  * It is sufficient to wake up at least one waiter to
     572             :                  * guarantee forward progress.
     573             :                  */
     574           0 :                 if (waitqueue_active(&ws->wait) &&
     575           0 :                     wake_up_nr(&ws->wait, nr))
     576             :                         break;
     577             :         }
     578             : 
     579           0 :         if (wake_index != atomic_read(&sbq->wake_index))
     580           0 :                 atomic_set(&sbq->wake_index, wake_index);
     581             : }
     582             : 
     583           0 : void sbitmap_queue_wake_up(struct sbitmap_queue *sbq, int nr)
     584             : {
     585           0 :         unsigned int wake_batch = READ_ONCE(sbq->wake_batch);
     586             :         unsigned int wakeups;
     587             : 
     588           0 :         if (!atomic_read(&sbq->ws_active))
     589             :                 return;
     590             : 
     591           0 :         atomic_add(nr, &sbq->completion_cnt);
     592           0 :         wakeups = atomic_read(&sbq->wakeup_cnt);
     593             : 
     594             :         do {
     595           0 :                 if (atomic_read(&sbq->completion_cnt) - wakeups < wake_batch)
     596             :                         return;
     597           0 :         } while (!atomic_try_cmpxchg(&sbq->wakeup_cnt,
     598           0 :                                      &wakeups, wakeups + wake_batch));
     599             : 
     600           0 :         __sbitmap_queue_wake_up(sbq, wake_batch);
     601             : }
     602             : EXPORT_SYMBOL_GPL(sbitmap_queue_wake_up);
     603             : 
     604             : static inline void sbitmap_update_cpu_hint(struct sbitmap *sb, int cpu, int tag)
     605             : {
     606           0 :         if (likely(!sb->round_robin && tag < sb->depth))
     607           0 :                 data_race(*per_cpu_ptr(sb->alloc_hint, cpu) = tag);
     608             : }
     609             : 
     610           0 : void sbitmap_queue_clear_batch(struct sbitmap_queue *sbq, int offset,
     611             :                                 int *tags, int nr_tags)
     612             : {
     613           0 :         struct sbitmap *sb = &sbq->sb;
     614           0 :         unsigned long *addr = NULL;
     615           0 :         unsigned long mask = 0;
     616             :         int i;
     617             : 
     618           0 :         smp_mb__before_atomic();
     619           0 :         for (i = 0; i < nr_tags; i++) {
     620           0 :                 const int tag = tags[i] - offset;
     621             :                 unsigned long *this_addr;
     622             : 
     623             :                 /* since we're clearing a batch, skip the deferred map */
     624           0 :                 this_addr = &sb->map[SB_NR_TO_INDEX(sb, tag)].word;
     625           0 :                 if (!addr) {
     626             :                         addr = this_addr;
     627           0 :                 } else if (addr != this_addr) {
     628           0 :                         atomic_long_andnot(mask, (atomic_long_t *) addr);
     629           0 :                         mask = 0;
     630           0 :                         addr = this_addr;
     631             :                 }
     632           0 :                 mask |= (1UL << SB_NR_TO_BIT(sb, tag));
     633             :         }
     634             : 
     635           0 :         if (mask)
     636           0 :                 atomic_long_andnot(mask, (atomic_long_t *) addr);
     637             : 
     638           0 :         smp_mb__after_atomic();
     639           0 :         sbitmap_queue_wake_up(sbq, nr_tags);
     640           0 :         sbitmap_update_cpu_hint(&sbq->sb, raw_smp_processor_id(),
     641           0 :                                         tags[nr_tags - 1] - offset);
     642           0 : }
     643             : 
     644           0 : void sbitmap_queue_clear(struct sbitmap_queue *sbq, unsigned int nr,
     645             :                          unsigned int cpu)
     646             : {
     647             :         /*
     648             :          * Once the clear bit is set, the bit may be allocated out.
     649             :          *
     650             :          * Orders READ/WRITE on the associated instance(such as request
     651             :          * of blk_mq) by this bit for avoiding race with re-allocation,
     652             :          * and its pair is the memory barrier implied in __sbitmap_get_word.
     653             :          *
     654             :          * One invariant is that the clear bit has to be zero when the bit
     655             :          * is in use.
     656             :          */
     657           0 :         smp_mb__before_atomic();
     658           0 :         sbitmap_deferred_clear_bit(&sbq->sb, nr);
     659             : 
     660             :         /*
     661             :          * Pairs with the memory barrier in set_current_state() to ensure the
     662             :          * proper ordering of clear_bit_unlock()/waitqueue_active() in the waker
     663             :          * and test_and_set_bit_lock()/prepare_to_wait()/finish_wait() in the
     664             :          * waiter. See the comment on waitqueue_active().
     665             :          */
     666           0 :         smp_mb__after_atomic();
     667           0 :         sbitmap_queue_wake_up(sbq, 1);
     668           0 :         sbitmap_update_cpu_hint(&sbq->sb, cpu, nr);
     669           0 : }
     670             : EXPORT_SYMBOL_GPL(sbitmap_queue_clear);
     671             : 
     672           0 : void sbitmap_queue_wake_all(struct sbitmap_queue *sbq)
     673             : {
     674             :         int i, wake_index;
     675             : 
     676             :         /*
     677             :          * Pairs with the memory barrier in set_current_state() like in
     678             :          * sbitmap_queue_wake_up().
     679             :          */
     680           0 :         smp_mb();
     681           0 :         wake_index = atomic_read(&sbq->wake_index);
     682           0 :         for (i = 0; i < SBQ_WAIT_QUEUES; i++) {
     683           0 :                 struct sbq_wait_state *ws = &sbq->ws[wake_index];
     684             : 
     685           0 :                 if (waitqueue_active(&ws->wait))
     686           0 :                         wake_up(&ws->wait);
     687             : 
     688           0 :                 wake_index = sbq_index_inc(wake_index);
     689             :         }
     690           0 : }
     691             : EXPORT_SYMBOL_GPL(sbitmap_queue_wake_all);
     692             : 
     693           0 : void sbitmap_queue_show(struct sbitmap_queue *sbq, struct seq_file *m)
     694             : {
     695             :         bool first;
     696             :         int i;
     697             : 
     698           0 :         sbitmap_show(&sbq->sb, m);
     699             : 
     700           0 :         seq_puts(m, "alloc_hint={");
     701           0 :         first = true;
     702           0 :         for_each_possible_cpu(i) {
     703           0 :                 if (!first)
     704           0 :                         seq_puts(m, ", ");
     705           0 :                 first = false;
     706           0 :                 seq_printf(m, "%u", *per_cpu_ptr(sbq->sb.alloc_hint, i));
     707             :         }
     708           0 :         seq_puts(m, "}\n");
     709             : 
     710           0 :         seq_printf(m, "wake_batch=%u\n", sbq->wake_batch);
     711           0 :         seq_printf(m, "wake_index=%d\n", atomic_read(&sbq->wake_index));
     712           0 :         seq_printf(m, "ws_active=%d\n", atomic_read(&sbq->ws_active));
     713             : 
     714           0 :         seq_puts(m, "ws={\n");
     715           0 :         for (i = 0; i < SBQ_WAIT_QUEUES; i++) {
     716           0 :                 struct sbq_wait_state *ws = &sbq->ws[i];
     717           0 :                 seq_printf(m, "\t{.wait=%s},\n",
     718           0 :                            waitqueue_active(&ws->wait) ? "active" : "inactive");
     719             :         }
     720           0 :         seq_puts(m, "}\n");
     721             : 
     722           0 :         seq_printf(m, "round_robin=%d\n", sbq->sb.round_robin);
     723           0 :         seq_printf(m, "min_shallow_depth=%u\n", sbq->min_shallow_depth);
     724           0 : }
     725             : EXPORT_SYMBOL_GPL(sbitmap_queue_show);
     726             : 
     727           0 : void sbitmap_add_wait_queue(struct sbitmap_queue *sbq,
     728             :                             struct sbq_wait_state *ws,
     729             :                             struct sbq_wait *sbq_wait)
     730             : {
     731           0 :         if (!sbq_wait->sbq) {
     732           0 :                 sbq_wait->sbq = sbq;
     733           0 :                 atomic_inc(&sbq->ws_active);
     734           0 :                 add_wait_queue(&ws->wait, &sbq_wait->wait);
     735             :         }
     736           0 : }
     737             : EXPORT_SYMBOL_GPL(sbitmap_add_wait_queue);
     738             : 
     739           0 : void sbitmap_del_wait_queue(struct sbq_wait *sbq_wait)
     740             : {
     741           0 :         list_del_init(&sbq_wait->wait.entry);
     742           0 :         if (sbq_wait->sbq) {
     743           0 :                 atomic_dec(&sbq_wait->sbq->ws_active);
     744           0 :                 sbq_wait->sbq = NULL;
     745             :         }
     746           0 : }
     747             : EXPORT_SYMBOL_GPL(sbitmap_del_wait_queue);
     748             : 
     749           0 : void sbitmap_prepare_to_wait(struct sbitmap_queue *sbq,
     750             :                              struct sbq_wait_state *ws,
     751             :                              struct sbq_wait *sbq_wait, int state)
     752             : {
     753           0 :         if (!sbq_wait->sbq) {
     754           0 :                 atomic_inc(&sbq->ws_active);
     755           0 :                 sbq_wait->sbq = sbq;
     756             :         }
     757           0 :         prepare_to_wait_exclusive(&ws->wait, &sbq_wait->wait, state);
     758           0 : }
     759             : EXPORT_SYMBOL_GPL(sbitmap_prepare_to_wait);
     760             : 
     761           0 : void sbitmap_finish_wait(struct sbitmap_queue *sbq, struct sbq_wait_state *ws,
     762             :                          struct sbq_wait *sbq_wait)
     763             : {
     764           0 :         finish_wait(&ws->wait, &sbq_wait->wait);
     765           0 :         if (sbq_wait->sbq) {
     766           0 :                 atomic_dec(&sbq->ws_active);
     767           0 :                 sbq_wait->sbq = NULL;
     768             :         }
     769           0 : }
     770             : EXPORT_SYMBOL_GPL(sbitmap_finish_wait);

Generated by: LCOV version 1.14