On Wed, 2017-08-30 at 12:50 +0200, Hannes Reinecke wrote: > On 08/29/2017 06:02 PM, Bart Van Assche wrote: > > On Tue, 2017-08-29 at 10:49 +0200, Hannes Reinecke wrote: > > > +} sdev_bflags[] = { > > > +#include "scsi_devinfo_tbl.c" > > > +}; > > > + > > > +static const char *sdev_bflags_name(unsigned int bflags) > > > +{ > > > + int i; > > > + const char *name = NULL; > > > + > > > + for (i = 0; i < ARRAY_SIZE(sdev_bflags); i++) { > > > + if (sdev_bflags[i].value == bflags) { > > > + name = sdev_bflags[i].name; > > > + break; > > > + } > > > + } > > > + return name; > > > +} > > > > How about using ilog2() of the BLIST_* values as index of the table such that > > an array lookup can be used instead of a for-loop over the entire array? > > Not sure if that'll work. The BLIST_* values in fact form a sparse > array, so the lookup array 'sdev_bflags' actually an associative array. > And I dare not convert it to a normal array as then I couldn't to the > automatice table creation anymore. > > So I'm not sure if ilog2 will save me anything here. Hello Hannes, Are you aware that there is already code upstream for converting a bitmask into a list of names of flags that supports sparse bit definitions? From block/blk-mq-debugfs.c: #define HCTX_FLAG_NAME(name) [ilog2(BLK_MQ_F_##name)] = #name static const char *const hctx_flag_name[] = { HCTX_FLAG_NAME(SHOULD_MERGE), HCTX_FLAG_NAME(TAG_SHARED), HCTX_FLAG_NAME(SG_MERGE), HCTX_FLAG_NAME(BLOCKING), HCTX_FLAG_NAME(NO_SCHED), }; #undef HCTX_FLAG_NAME static int blk_flags_show(struct seq_file *m, const unsigned long flags, const char *const *flag_name, int flag_name_count) { bool sep = false; int i; for (i = 0; i < sizeof(flags) * BITS_PER_BYTE; i++) { if (!(flags & BIT(i))) continue; if (sep) seq_puts(m, "|"); sep = true; if (i < flag_name_count && flag_name[i]) seq_puts(m, flag_name[i]); else seq_printf(m, "%d", i); } return 0; } [ ... ] blk_flags_show(m, hctx->flags ^ BLK_ALLOC_POLICY_TO_MQ_FLAG(alloc_policy), hctx_flag_name, ARRAY_SIZE(hctx_flag_name)); [ ... ] Bart.