* [PATCH] lib/vsprintf.c: increase the size of the field_width variable @ 2015-09-09 10:13 Maurizio Lombardi 2015-09-09 13:39 ` Tejun Heo 2015-09-09 16:33 ` Joe Perches 0 siblings, 2 replies; 17+ messages in thread From: Maurizio Lombardi @ 2015-09-09 10:13 UTC (permalink / raw) To: akpm; +Cc: linux, tj, linux-kernel When printing a bitmap using the "%*pb[l]" printk format a 16 bit variable (field_width) is used to store the size of the bitmap. In some cases 16 bits are not sufficient, the variable overflows and printk does not work as expected. This patch fixes the problem by changing the type of field_width to s32. How to reproduce the bug: 1.load scsi_debug # modprobe scsi-debug dev_size_mb=256 lbpu=1 lbpws10=1 2.create VG # vgcreate tsvg /dev/sdb Physical volume "/dev/sdb" successfully created Volume group "tsvg" successfully created 3. Bitmap should be set, but still empty # cat /sys/bus/pseudo/drivers/scsi_debug/map Expected results: # cat /sys/bus/pseudo/drivers/scsi_debug/map 0-15 Signed-off-by: Maurizio Lombardi <mlombard@redhat.com> --- lib/vsprintf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 95cd63b..20f91c4 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -384,8 +384,8 @@ struct printf_spec { u8 flags; /* flags to number() */ u8 base; /* number base, 8, 10 or 16 only */ u8 qualifier; /* number qualifier, one of 'hHlLtzZ' */ - s16 field_width; /* width of output field */ s16 precision; /* # of digits/chars */ + s32 field_width; /* width of output field */ }; static noinline_for_stack -- Maurizio Lombardi ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-09 10:13 [PATCH] lib/vsprintf.c: increase the size of the field_width variable Maurizio Lombardi @ 2015-09-09 13:39 ` Tejun Heo 2015-09-09 16:33 ` Joe Perches 1 sibling, 0 replies; 17+ messages in thread From: Tejun Heo @ 2015-09-09 13:39 UTC (permalink / raw) To: Maurizio Lombardi; +Cc: akpm, linux, linux-kernel On Wed, Sep 09, 2015 at 12:13:10PM +0200, Maurizio Lombardi wrote: > When printing a bitmap using the "%*pb[l]" printk format > a 16 bit variable (field_width) is used to store the size of the bitmap. > In some cases 16 bits are not sufficient, the variable overflows and > printk does not work as expected. > > This patch fixes the problem by changing the type of field_width to s32. > > How to reproduce the bug: > > 1.load scsi_debug > # modprobe scsi-debug dev_size_mb=256 lbpu=1 lbpws10=1 > > 2.create VG > # vgcreate tsvg /dev/sdb > Physical volume "/dev/sdb" successfully created > Volume group "tsvg" successfully created > > 3. Bitmap should be set, but still empty > # cat /sys/bus/pseudo/drivers/scsi_debug/map > > Expected results: > # cat /sys/bus/pseudo/drivers/scsi_debug/map > 0-15 > > Signed-off-by: Maurizio Lombardi <mlombard@redhat.com> Acked-by: Tejun Heo <tj@kernel.org> Thanks. -- tejun ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-09 10:13 [PATCH] lib/vsprintf.c: increase the size of the field_width variable Maurizio Lombardi 2015-09-09 13:39 ` Tejun Heo @ 2015-09-09 16:33 ` Joe Perches 2015-09-09 16:36 ` Tejun Heo 2015-09-09 18:51 ` Rasmus Villemoes 1 sibling, 2 replies; 17+ messages in thread From: Joe Perches @ 2015-09-09 16:33 UTC (permalink / raw) To: Maurizio Lombardi; +Cc: akpm, linux, tj, linux-kernel On Wed, 2015-09-09 at 12:13 +0200, Maurizio Lombardi wrote: > When printing a bitmap using the "%*pb[l]" printk format > a 16 bit variable (field_width) is used to store the size of the bitmap. > In some cases 16 bits are not sufficient, the variable overflows and > printk does not work as expected. If more than 16 bits are necessary, it couldn't work as a single printk is limited to 1024 bytes. > 3. Bitmap should be set, but still empty > # cat /sys/bus/pseudo/drivers/scsi_debug/map [] > diff --git a/lib/vsprintf.c b/lib/vsprintf.c [] > @@ -384,8 +384,8 @@ struct printf_spec { > u8 flags; /* flags to number() */ > u8 base; /* number base, 8, 10 or 16 only */ > u8 qualifier; /* number qualifier, one of 'hHlLtzZ' */ > - s16 field_width; /* width of output field */ > s16 precision; /* # of digits/chars */ > + s32 field_width; /* width of output field */ > }; > > static noinline_for_stack And this makes the sizeof struct printf_spec more than 8 bytes which isn't desireable on x86-32. %*pb is meant for smallish bitmaps, not big ones. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-09 16:33 ` Joe Perches @ 2015-09-09 16:36 ` Tejun Heo 2015-09-09 16:55 ` Joe Perches 2015-09-09 18:51 ` Rasmus Villemoes 1 sibling, 1 reply; 17+ messages in thread From: Tejun Heo @ 2015-09-09 16:36 UTC (permalink / raw) To: Joe Perches; +Cc: Maurizio Lombardi, akpm, linux, linux-kernel Hello, On Wed, Sep 09, 2015 at 09:33:52AM -0700, Joe Perches wrote: > On Wed, 2015-09-09 at 12:13 +0200, Maurizio Lombardi wrote: > > When printing a bitmap using the "%*pb[l]" printk format > > a 16 bit variable (field_width) is used to store the size of the bitmap. > > In some cases 16 bits are not sufficient, the variable overflows and > > printk does not work as expected. > > If more than 16 bits are necessary, it couldn't work > as a single printk is limited to 1024 bytes. It's weird to fail silently tho. What we can do is just capping it at 16bit max and append something to indicate that the bitmap has been truncated if truncation actually happened. > > 3. Bitmap should be set, but still empty > > # cat /sys/bus/pseudo/drivers/scsi_debug/map > [] > > diff --git a/lib/vsprintf.c b/lib/vsprintf.c > [] > > @@ -384,8 +384,8 @@ struct printf_spec { > > u8 flags; /* flags to number() */ > > u8 base; /* number base, 8, 10 or 16 only */ > > u8 qualifier; /* number qualifier, one of 'hHlLtzZ' */ > > - s16 field_width; /* width of output field */ > > s16 precision; /* # of digits/chars */ > > + s32 field_width; /* width of output field */ > > }; > > > > static noinline_for_stack > > And this makes the sizeof struct printf_spec more than > 8 bytes which isn't desireable on x86-32. Ah, right, we pass this around on stack. Thanks. -- tejun ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-09 16:36 ` Tejun Heo @ 2015-09-09 16:55 ` Joe Perches 0 siblings, 0 replies; 17+ messages in thread From: Joe Perches @ 2015-09-09 16:55 UTC (permalink / raw) To: Tejun Heo; +Cc: Maurizio Lombardi, akpm, linux, linux-kernel On Wed, 2015-09-09 at 12:36 -0400, Tejun Heo wrote: > On Wed, Sep 09, 2015 at 09:33:52AM -0700, Joe Perches wrote: > > On Wed, 2015-09-09 at 12:13 +0200, Maurizio Lombardi wrote: > > > When printing a bitmap using the "%*pb[l]" printk format > > > a 16 bit variable (field_width) is used to store the size of the bitmap. > > > In some cases 16 bits are not sufficient, the variable overflows and > > > printk does not work as expected. > > > > If more than 16 bits are necessary, it couldn't work > > as a single printk is limited to 1024 bytes. > > It's weird to fail silently tho. What we can do is just capping it at > 16bit max and append something to indicate that the bitmap has been > truncated if truncation actually happened. It might be reasonable to output ... after the last comma or dash of the bitmap output when buf >= end. It also might be better to not reuse spec in bitmap_string and bitmap_list_string. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-09 16:33 ` Joe Perches 2015-09-09 16:36 ` Tejun Heo @ 2015-09-09 18:51 ` Rasmus Villemoes 2015-09-09 19:26 ` Joe Perches 2015-09-10 7:04 ` Maurizio Lombardi 1 sibling, 2 replies; 17+ messages in thread From: Rasmus Villemoes @ 2015-09-09 18:51 UTC (permalink / raw) To: Joe Perches; +Cc: Maurizio Lombardi, akpm, tj, linux-kernel On Wed, Sep 09 2015, Joe Perches <joe@perches.com> wrote: > On Wed, 2015-09-09 at 12:13 +0200, Maurizio Lombardi wrote: >> When printing a bitmap using the "%*pb[l]" printk format >> a 16 bit variable (field_width) is used to store the size of the bitmap. >> In some cases 16 bits are not sufficient, the variable overflows and >> printk does not work as expected. > > If more than 16 bits are necessary, it couldn't work > as a single printk is limited to 1024 bytes. I'm also a little confused; I don't see what printk has to do with the reported problem (I'd expect the /sys/... file to be generated by something like seq_printf). >> 3. Bitmap should be set, but still empty >> # cat /sys/bus/pseudo/drivers/scsi_debug/map > [] >> diff --git a/lib/vsprintf.c b/lib/vsprintf.c > [] >> @@ -384,8 +384,8 @@ struct printf_spec { >> u8 flags; /* flags to number() */ >> u8 base; /* number base, 8, 10 or 16 only */ >> u8 qualifier; /* number qualifier, one of 'hHlLtzZ' */ >> - s16 field_width; /* width of output field */ >> s16 precision; /* # of digits/chars */ >> + s32 field_width; /* width of output field */ >> }; >> >> static noinline_for_stack > > And this makes the sizeof struct printf_spec more than > 8 bytes which isn't desireable on x86-32. Or other architectures, I imagine. I'm pretty sure struct printf_spec purposely has sizeof==8 to allow it to be (relatively cheaply) passed around by value. > %*pb is meant for smallish bitmaps, not big ones. Yup. And that leads to my other confusion: Given that the expected output is given as "0-15", does the bitmap really consist of > S16_MAX bits with only the first 16 set? Rasmus ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-09 18:51 ` Rasmus Villemoes @ 2015-09-09 19:26 ` Joe Perches 2015-09-10 14:36 ` Tejun Heo 2015-09-10 7:04 ` Maurizio Lombardi 1 sibling, 1 reply; 17+ messages in thread From: Joe Perches @ 2015-09-09 19:26 UTC (permalink / raw) To: Rasmus Villemoes; +Cc: Maurizio Lombardi, akpm, tj, linux-kernel On Wed, 2015-09-09 at 20:51 +0200, Rasmus Villemoes wrote: > On Wed, Sep 09 2015, Joe Perches <joe@perches.com> wrote: > > this makes the sizeof struct printf_spec more than > > 8 bytes which isn't desireable on x86-32. > > I'm pretty sure struct printf_spec > purposely has sizeof==8 to allow it to be (relatively cheaply) passed > around by value. True. https://lkml.org/lkml/2010/3/6/141 > > %*pb is meant for smallish bitmaps, not big ones. > > Yup. And that leads to my other confusion: Given that the expected > output is given as "0-15", does the bitmap really consist of > S16_MAX > bits with only the first 16 set? No idea. Tejun? Perhaps the code in lib/vsprintf.c that sets spec.field_width and spec.precision from format argument input should be changed to use a temporary int and clamped to S16_MIN -> S16_MAX. Something like: --- lib/vsprintf.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 7f0cdd2..2782129 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1913,13 +1913,21 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) break; } - case FORMAT_TYPE_WIDTH: - spec.field_width = va_arg(args, int); + case FORMAT_TYPE_WIDTH: { + int tmp = va_arg(args, int); + + spec.field_width = (s16)clamp_t(int, tmp, + S16_MIN, S16_MAX); break; + } - case FORMAT_TYPE_PRECISION: - spec.precision = va_arg(args, int); + case FORMAT_TYPE_PRECISION: { + int tmp = va_arg(args, int); + + spec.precision = (s16)clamp_t(int, tmp, + S16_MIN, S16_MAX); break; + } case FORMAT_TYPE_CHAR: { char c; ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-09 19:26 ` Joe Perches @ 2015-09-10 14:36 ` Tejun Heo 2015-09-10 15:41 ` Joe Perches 0 siblings, 1 reply; 17+ messages in thread From: Tejun Heo @ 2015-09-10 14:36 UTC (permalink / raw) To: Joe Perches; +Cc: Rasmus Villemoes, Maurizio Lombardi, akpm, linux-kernel Hello, Joe. On Wed, Sep 09, 2015 at 12:26:39PM -0700, Joe Perches wrote: > > > %*pb is meant for smallish bitmaps, not big ones. I'm not so sure about that. It's one thing to truncate printk output cuz the actual formatted result is too long but crippling the entire printf family of functions regardless of the actual output, which might as well be just "7-65540", doesn't seem like a good idea. These are pretty basic library functions and people shouldn't need to worry about niggles like that. > > Yup. And that leads to my other confusion: Given that the expected > > output is given as "0-15", does the bitmap really consist of > S16_MAX > > bits with only the first 16 set? > > No idea. Tejun? The use case isn't from me, but why not? > Perhaps the code in lib/vsprintf.c that sets > spec.field_width and spec.precision from format argument > input should be changed to use a temporary int and > clamped to S16_MIN -> S16_MAX. I think it should be able to handle bitmaps >64k. We don't want to cripple the fundamental string formatter because we can't pass around struct larger than 8 bytes. That just reeks of poor decision making. Why are we even copying the struct on invocations? Only some functions modify the values after all. We might as well pass around pointer to the struct and let the callees wihch modify them copy the fieldsin local vars like normal functions. Thanks. -- tejun ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-10 14:36 ` Tejun Heo @ 2015-09-10 15:41 ` Joe Perches 2015-09-10 15:47 ` Tejun Heo 0 siblings, 1 reply; 17+ messages in thread From: Joe Perches @ 2015-09-10 15:41 UTC (permalink / raw) To: Tejun Heo; +Cc: Rasmus Villemoes, Maurizio Lombardi, akpm, linux-kernel On Thu, 2015-09-10 at 10:36 -0400, Tejun Heo wrote: > On Wed, Sep 09, 2015 at 12:26:39PM -0700, Joe Perches wrote: > > > > %*pb is meant for smallish bitmaps, not big ones. [] > The use case isn't from me, but why not? Imagine the output of the 500k bitmap if every other bit is set. %*pb isn't capable of multiple line output and seq_printf output would also fail as it uses k.alloc memory not vmalloc. I think that a more limited mechanism might be to use a multiple line oriented function like print_hex_debug and not try to emit the entire thing in a single go. > Why are we even copying the struct on invocations? > Only some functions modify the values after all. > We might as well pass around pointer to the struct > and let the callees wihch modify them copy the > fields in local vars like normal functions. You are of course welcome and able to change it. btw: the current implementation has a limitation on 32 bit arches as it uses an int argument for the unsigned long count of bits in a bitmap. That's a bitmap that should not be printed anyway. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-10 15:41 ` Joe Perches @ 2015-09-10 15:47 ` Tejun Heo 0 siblings, 0 replies; 17+ messages in thread From: Tejun Heo @ 2015-09-10 15:47 UTC (permalink / raw) To: Joe Perches; +Cc: Rasmus Villemoes, Maurizio Lombardi, akpm, linux-kernel Hello, Joe. On Thu, Sep 10, 2015 at 08:41:25AM -0700, Joe Perches wrote: > On Thu, 2015-09-10 at 10:36 -0400, Tejun Heo wrote: > > On Wed, Sep 09, 2015 at 12:26:39PM -0700, Joe Perches wrote: > > > > > %*pb is meant for smallish bitmaps, not big ones. > [] > > The use case isn't from me, but why not? > > Imagine the output of the 500k bitmap if every other > bit is set. Yeah, but the caller still should be able to call, say, scnprintf() with a limited buffer and get the output till the end of the buffer along with the indication that the output has been truncated. > %*pb isn't capable of multiple line output and > seq_printf output would also fail as it uses k.alloc > memory not vmalloc. Heh, and it should fail. > I think that a more limited mechanism might be to use a > multiple line oriented function like print_hex_debug > and not try to emit the entire thing in a single go. I'm not that worried about the berserk cases which try to print a really long output on consoles but the subtle failure modes are worrying. > > Why are we even copying the struct on invocations? > > Only some functions modify the values after all. > > We might as well pass around pointer to the struct > > and let the callees wihch modify them copy the > > fields in local vars like normal functions. > > You are of course welcome and able to change it. > > btw: the current implementation has a limitation > on 32 bit arches as it uses an int argument for the > unsigned long count of bits in a bitmap. > > That's a bitmap that should not be printed anyway. That's 256Mbytes of bitmap. I don't think we need to worry about that at the moment. Thanks. -- tejun ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-09 18:51 ` Rasmus Villemoes 2015-09-09 19:26 ` Joe Perches @ 2015-09-10 7:04 ` Maurizio Lombardi 2015-09-10 7:13 ` Maurizio Lombardi 2015-09-10 7:38 ` Joe Perches 1 sibling, 2 replies; 17+ messages in thread From: Maurizio Lombardi @ 2015-09-10 7:04 UTC (permalink / raw) To: Rasmus Villemoes, Joe Perches; +Cc: akpm, tj, linux-kernel Hi Rasmus, On 09/09/2015 08:51 PM, Rasmus Villemoes wrote: > I'm also a little confused; I don't see what printk has to do with the > reported problem (I'd expect the /sys/... file to be generated by > something like seq_printf). In the scsi-debug case scnprintf is used, but it doesn't really matter because the change I made would influence printk and all its friends as well... everything that will parse "%*pb[l]". > >> %*pb is meant for smallish bitmaps, not big ones. > > Yup. And that leads to my other confusion: Given that the expected > output is given as "0-15", does the bitmap really consist of > S16_MAX > bits with only the first 16 set? > Yes. To be precise, in the example I mentioned in the commit message, a bitmap of size = 524288 bits is created. If you assign this number to a s16 variable the result will be zero and nothing will be printed. Joe, you mentioned that *pbl is meant for small bitmaps, what should I use with big ones? scsi-debug used the bitmap_scnlistprintf() function but since commit dbc760bcc150cc27160f0131b15db76350df4334 this function is just a wrapper around scnprintf("%*pbl"); as a consequence, the scsi-debug map_show() function stopped working correctly. Thanks, Maurizio Lombardi ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-10 7:04 ` Maurizio Lombardi @ 2015-09-10 7:13 ` Maurizio Lombardi 2015-09-10 7:38 ` Joe Perches 1 sibling, 0 replies; 17+ messages in thread From: Maurizio Lombardi @ 2015-09-10 7:13 UTC (permalink / raw) To: Rasmus Villemoes, Joe Perches; +Cc: akpm, tj, linux-kernel On 09/10/2015 09:04 AM, Maurizio Lombardi wrote: > > scsi-debug used the bitmap_scnlistprintf() function but since commit > dbc760bcc150cc27160f0131b15db76350df4334 this function is just a wrapper > around scnprintf("%*pbl"); I just want to add that since commit 46385326cc1577587ed3e7432c2425cf6d3e4308 the bitmap_scnlistprintf() function has been completely removed because " all the bitmap formatting usages have been converted to '%*pb[l]' ". Thanks, Maurizio Lombardi ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-10 7:04 ` Maurizio Lombardi 2015-09-10 7:13 ` Maurizio Lombardi @ 2015-09-10 7:38 ` Joe Perches 2015-09-10 7:56 ` Rasmus Villemoes 2015-09-10 8:39 ` Maurizio Lombardi 1 sibling, 2 replies; 17+ messages in thread From: Joe Perches @ 2015-09-10 7:38 UTC (permalink / raw) To: Maurizio Lombardi; +Cc: Rasmus Villemoes, akpm, tj, linux-kernel On Thu, 2015-09-10 at 09:04 +0200, Maurizio Lombardi wrote: > Hi Rasmus, > > On 09/09/2015 08:51 PM, Rasmus Villemoes wrote: > > I'm also a little confused; I don't see what printk has to do with the > > reported problem (I'd expect the /sys/... file to be generated by > > something like seq_printf). > > In the scsi-debug case scnprintf is used, but it doesn't really matter > because the change I made would influence printk and all its friends as > well... everything that will parse "%*pb[l]". > > > > >> %*pb is meant for smallish bitmaps, not big ones. > > > > Yup. And that leads to my other confusion: Given that the expected > > output is given as "0-15", does the bitmap really consist of > S16_MAX > > bits with only the first 16 set? > > > > Yes. To be precise, in the example I mentioned in the commit message, a > bitmap of size = 524288 bits is created. > If you assign this number to a s16 variable the result will be zero and > nothing will be printed. Maurizio, did you try the patch I posted? I think it'll work, but it doesn't fix the fundamental issue of %*pbl with large bitmaps. vsnprintf / printk as used in the kernel does have limitations that user mode vsnprintf does not. > Joe, you mentioned that *pbl is meant for small bitmaps, what should I > use with big ones? Something else? > scsi-debug used the bitmap_scnlistprintf() function but since commit > dbc760bcc150cc27160f0131b15db76350df4334 this function is just a wrapper > around scnprintf("%*pbl"); > as a consequence, the scsi-debug map_show() function stopped working > correctly. Perhaps the thin wrapper conversions in lib/bitmap.c in that commit for bitmap_scnprintf, bscnl_emit, and bitmap_scnlistprintf should be reverted. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-10 7:38 ` Joe Perches @ 2015-09-10 7:56 ` Rasmus Villemoes 2015-09-10 8:17 ` Joe Perches 2015-09-10 8:39 ` Maurizio Lombardi 1 sibling, 1 reply; 17+ messages in thread From: Rasmus Villemoes @ 2015-09-10 7:56 UTC (permalink / raw) To: Joe Perches; +Cc: Maurizio Lombardi, akpm, tj, linux-kernel On Thu, Sep 10 2015, Joe Perches <joe@perches.com> wrote: > On Thu, 2015-09-10 at 09:04 +0200, Maurizio Lombardi wrote: >> Hi Rasmus, >> >> On 09/09/2015 08:51 PM, Rasmus Villemoes wrote: >> > I'm also a little confused; I don't see what printk has to do with the >> > reported problem (I'd expect the /sys/... file to be generated by >> > something like seq_printf). >> >> In the scsi-debug case scnprintf is used, but it doesn't really matter >> because the change I made would influence printk and all its friends as >> well... everything that will parse "%*pb[l]". >> >> > >> >> %*pb is meant for smallish bitmaps, not big ones. >> > >> > Yup. And that leads to my other confusion: Given that the expected >> > output is given as "0-15", does the bitmap really consist of > S16_MAX >> > bits with only the first 16 set? >> > >> >> Yes. To be precise, in the example I mentioned in the commit message, a >> bitmap of size = 524288 bits is created. >> If you assign this number to a s16 variable the result will be zero and >> nothing will be printed. > > Maurizio, did you try the patch I posted? > I think it'll work, but it doesn't fix the > fundamental issue of %*pbl with large bitmaps. It also won't work for the case at hand if/when the actual bitmap ever gets a bit set beyond S16_MAX. >> scsi-debug used the bitmap_scnlistprintf() function but since commit >> dbc760bcc150cc27160f0131b15db76350df4334 this function is just a wrapper >> around scnprintf("%*pbl"); >> as a consequence, the scsi-debug map_show() function stopped working >> correctly. > > Perhaps the thin wrapper conversions in lib/bitmap.c > in that commit for bitmap_scnprintf, bscnl_emit, and > bitmap_scnlistprintf should be reverted. Yes, that's the obvious short-term solution, though I think it's a bit sad having to have library functions needed only by very few users (after all, it took 6 months for this to be reported). A (somewhat ugly?) solution might be to teach %pb another flag, say h (for huge), meaning that the pointer is actually (struct printf_bitmap*), with struct printf_bitmap { unsigned long *bits; unsigned long nbits; } Then callers with potentially huge bitmaps would do struct printf_bitmap tmp = { my_bitmap, my_size }; snprintf("%pbhl", &tmp) and I think we'd only need a tiny refactorization in lib/vsprintf.c to support this. (When using this form, the field width would just be ignored.) Basically, move the simplistic flag handling from the generic dispatch function pointer() to its own little helper, let that helper compute/fetch the (unsigned long*) and size we need, and pass that to either bitmap_list_string or bitmap_string - basically, they'd lose the spec argument and grow an explicit nbits argument, and then get to declare their own struct printf_spec. Rasmus ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-10 7:56 ` Rasmus Villemoes @ 2015-09-10 8:17 ` Joe Perches 2015-09-10 14:43 ` Tejun Heo 0 siblings, 1 reply; 17+ messages in thread From: Joe Perches @ 2015-09-10 8:17 UTC (permalink / raw) To: Rasmus Villemoes; +Cc: Maurizio Lombardi, akpm, tj, linux-kernel On Thu, 2015-09-10 at 09:56 +0200, Rasmus Villemoes wrote: > On Thu, Sep 10 2015, Joe Perches <joe@perches.com> wrote: > > On Thu, 2015-09-10 at 09:04 +0200, Maurizio Lombardi wrote: > >> On 09/09/2015 08:51 PM, Rasmus Villemoes wrote: > >> > I'm also a little confused; I don't see what printk has to do with the > >> > reported problem (I'd expect the /sys/... file to be generated by > >> > something like seq_printf). > >> > >> In the scsi-debug case scnprintf is used, but it doesn't really matter > >> because the change I made would influence printk and all its friends as > >> well... everything that will parse "%*pb[l]". > >> > >> > > >> >> %*pb is meant for smallish bitmaps, not big ones. > >> > > >> > Yup. And that leads to my other confusion: Given that the expected > >> > output is given as "0-15", does the bitmap really consist of > S16_MAX > >> > bits with only the first 16 set? > >> > > >> > >> Yes. To be precise, in the example I mentioned in the commit message, a > >> bitmap of size = 524288 bits is created. > >> If you assign this number to a s16 variable the result will be zero and > >> nothing will be printed. > > > > Maurizio, did you try the patch I posted? > > I think it'll work, but it doesn't fix the > > fundamental issue of %*pbl with large bitmaps. > > It also won't work for the case at hand if/when the actual bitmap ever > gets a bit set beyond S16_MAX. But at least it should work for the bitmap sized <= S16_MAX which should be the majority of uses. > A (somewhat ugly?) solution might be to teach %pb another flag, say h (for > huge), meaning that the pointer is actually (struct printf_bitmap*), > with > > struct printf_bitmap { unsigned long *bits; unsigned long nbits; } > > Then callers with potentially huge bitmaps would do > > struct printf_bitmap tmp = { my_bitmap, my_size }; > snprintf("%pbhl", &tmp) Yes, but it still couldn't work without the ability to have large output buffers and printk doesn't support that. seq_printf might have some performance issue with it too as it would repetitively try to emit, fail, and grow the buffer. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-10 8:17 ` Joe Perches @ 2015-09-10 14:43 ` Tejun Heo 0 siblings, 0 replies; 17+ messages in thread From: Tejun Heo @ 2015-09-10 14:43 UTC (permalink / raw) To: Joe Perches; +Cc: Rasmus Villemoes, Maurizio Lombardi, akpm, linux-kernel Hello, On Thu, Sep 10, 2015 at 01:17:36AM -0700, Joe Perches wrote: > > It also won't work for the case at hand if/when the actual bitmap ever > > gets a bit set beyond S16_MAX. > > But at least it should work for the bitmap sized <= S16_MAX > which should be the majority of uses. The failure mode is too subtle and this is a utility function which is too fundamental. I think we really should just get it working properly. > > A (somewhat ugly?) solution might be to teach %pb another flag, say h (for > > huge), meaning that the pointer is actually (struct printf_bitmap*), > > with > > > > struct printf_bitmap { unsigned long *bits; unsigned long nbits; } > > > > Then callers with potentially huge bitmaps would do > > > > struct printf_bitmap tmp = { my_bitmap, my_size }; > > snprintf("%pbhl", &tmp) > > Yes, but it still couldn't work without the ability to have > large output buffers and printk doesn't support that. printk overrunning its output buffer is fine. We've always had that and while we probably should do a better job of indicating those events, when the output line runs off that long, people (and it's usually human minds that process printk outputs) already kinda suspect that. Long bitmaps don't mean long output and silently formatting the wrong output sounds like a pretty bad idea and that because we can't make the width field 32bit? It doesn't make any sense. > seq_printf might have some performance issue with it too as > it would repetitively try to emit, fail, and grow the buffer. That's kinda beside the point here. Thanks. -- tejun ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] lib/vsprintf.c: increase the size of the field_width variable 2015-09-10 7:38 ` Joe Perches 2015-09-10 7:56 ` Rasmus Villemoes @ 2015-09-10 8:39 ` Maurizio Lombardi 1 sibling, 0 replies; 17+ messages in thread From: Maurizio Lombardi @ 2015-09-10 8:39 UTC (permalink / raw) To: Joe Perches; +Cc: Rasmus Villemoes, akpm, tj, linux-kernel On 09/10/2015 09:38 AM, Joe Perches wrote:ing will be printed. > > Maurizio, did you try the patch I posted? > I think it'll work, but it doesn't fix the > fundamental issue of %*pbl with large bitmaps. I tested your patch, it works for the simple cases where bits are set below the S16_MAX limit, example: # modprobe scsi-debug dev_size_mb=256 lbpu=1 lbpws10=1 # vgcreate tsvg /dev/sdb # cat /sys/bus/pseudo/drivers/scsi_debug/map 0-15 <--- OK! # lvcreate -V200m -l99%FREE -T tsvg/pool -n lv1 --discards ignore # cat /sys/bus/pseudo/drivers/scsi_debug/map 0-31,2048-2055 <---- NO! It should be "0-31,2048-2055,501760-501871"! I think it's misleading. Can I suggest as a temporary solution to restore the old bitmap_scnlistprintf() function? > > Perhaps the thin wrapper conversions in lib/bitmap.c > in that commit for bitmap_scnprintf, bscnl_emit, and > bitmap_scnlistprintf should be reverted. > > Thanks, Maurizio Lombardi ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2015-09-10 15:47 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-09-09 10:13 [PATCH] lib/vsprintf.c: increase the size of the field_width variable Maurizio Lombardi 2015-09-09 13:39 ` Tejun Heo 2015-09-09 16:33 ` Joe Perches 2015-09-09 16:36 ` Tejun Heo 2015-09-09 16:55 ` Joe Perches 2015-09-09 18:51 ` Rasmus Villemoes 2015-09-09 19:26 ` Joe Perches 2015-09-10 14:36 ` Tejun Heo 2015-09-10 15:41 ` Joe Perches 2015-09-10 15:47 ` Tejun Heo 2015-09-10 7:04 ` Maurizio Lombardi 2015-09-10 7:13 ` Maurizio Lombardi 2015-09-10 7:38 ` Joe Perches 2015-09-10 7:56 ` Rasmus Villemoes 2015-09-10 8:17 ` Joe Perches 2015-09-10 14:43 ` Tejun Heo 2015-09-10 8:39 ` Maurizio Lombardi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox