]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
vsprintf: rework bitmap_list_string
authorYury Norov <yury.norov@gmail.com>
Mon, 23 Aug 2021 23:59:58 +0000 (09:59 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 25 Aug 2021 23:34:52 +0000 (09:34 +1000)
bitmap_list_string() is very ineffective when printing bitmaps with long
ranges of set bits because it calls find_next_bit for each bit in the
bitmap.  We can do better by detecting ranges of set bits.

In my environment, before/after is 943008/31008 ns.

Link: https://lkml.kernel.org/r/20210814211713.180533-18-yury.norov@gmail.com
Signed-off-by: Yury Norov <yury.norov@gmail.com>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Cc: Alexander Lobakin <alobakin@pm.me>
Cc: Alexey Klimov <aklimov@redhat.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
lib/vsprintf.c

index cc7bdd3ac2ee87a1597c3b0a65f9b1adead4265e..cd9f359c5bf9e41c82c9fe470cdfd90db5c84b2b 100644 (file)
@@ -1241,20 +1241,13 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap,
                         struct printf_spec spec, const char *fmt)
 {
        int nr_bits = max_t(int, spec.field_width, 0);
-       /* current bit is 'cur', most recently seen range is [rbot, rtop] */
-       int cur, rbot, rtop;
        bool first = true;
+       int rbot, rtop;
 
        if (check_pointer(&buf, end, bitmap, spec))
                return buf;
 
-       rbot = cur = find_first_bit(bitmap, nr_bits);
-       while (cur < nr_bits) {
-               rtop = cur;
-               cur = find_next_bit(bitmap, nr_bits, cur + 1);
-               if (cur < nr_bits && cur <= rtop + 1)
-                       continue;
-
+       for_each_set_bitrange(rbot, rtop, bitmap, nr_bits) {
                if (!first) {
                        if (buf < end)
                                *buf = ',';
@@ -1263,15 +1256,12 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap,
                first = false;
 
                buf = number(buf, end, rbot, default_dec_spec);
-               if (rbot < rtop) {
-                       if (buf < end)
-                               *buf = '-';
-                       buf++;
-
-                       buf = number(buf, end, rtop, default_dec_spec);
-               }
+               if (rtop == rbot + 1)
+                       continue;
 
-               rbot = cur;
+               if (buf < end)
+                       *buf = '-';
+               buf = number(++buf, end, rtop - 1, default_dec_spec);
        }
        return buf;
 }