Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On Thu, 2014-06-19 at 21:54 -0700, Paul E. McKenney wrote: > On Thu, Jun 19, 2014 at 08:13:22PM -0400, Pranith Kumar wrote: > > On 06/19/2014 07:49 PM, Paul E. McKenney wrote: > > > On Thu, Jun 19, 2014 at 07:24:48PM -0400, Pranith Kumar wrote: > > >> (dropping some CCs) > > >> > > >> On 06/19/2014 05:00 PM, Paul E. McKenney wrote: > > >>> On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: > > > > I believe the function doesn't work well. > > > > static void > > rcu_torture_stats_print(void) > > { > > int size = nr_cpu_ids * 200 + 8192; > > char *buf; > > > > buf = kmalloc(size, GFP_KERNEL); > > if (!buf) { > > pr_err("rcu-torture: Out of memory, need: %d\n", size); > > return; > > } > > rcu_torture_printk(buf); > > pr_alert("%s", buf); > > kfree(buf); > > } > > > > rcu_torture_printk simply fills buf > > > > btw: I believe the arguments should pass size and > > rcu_torture_printk should use snprintf/size > > > > but all printks are limited to a maximum of 1024 > > bytes so the large allocation is senseless and > > would even if it worked, would likely need to be > > vmalloc/vfree > > >>> > > >>> Fair point! > > >>> > > >>> Pranith, Romanov, if you would like part of RCU that is less touchy > > >>> about random hacking, this would be a good place to start. Scripts in > > >>> tools/testing/selftests/rcutorture/bin do care about some of the format, > > >>> but the variable-length portion generated by cur_ops->stats() is as far > > >>> as I know only parsed by human eyes. > > >>> > > >> > > >> Here is a first run of the change. Please let me know if I am totally > > >> off. RFC. :) > > > > > > Thank you for taking this on! > > > > You are most welcome :) > > > > > > > >> Three things on Todo list: > > >> > > >> * We need to check that we are using less than the allocated size of the > > >> buffer (used > size). (we are allocating a big buffer, so not sure if > > >> necessary) > > >> * Need to check with the scripts if they are working. > > >> * I used a loop for pr_alert(). I am not sure this is right, there > > >> should be a better way for printing large buffers > > >> > > >> If the overall structure is ok I will go ahead and check how the scripts > > >> are handling these changes. > > > > > > One other thing... Convince this function (and a few others that it > > > calls) that the system really has 4096 CPUs, run this code, and see wshat > > > actually happens both before and after. Just to get a bit of practice > > > mixed in with the theory. ;-) > > > > > > > OK. I think to do this I need to use 4096 instead of nr_cpu_ids. I will try > > this and see how it goes :) > > That's the spirit! You will probably have to adjust a few other things > as well. Perhaps this should not use the allocation / page buffer and instead call pr_alert and pr_cont directly like this: include/linux/torture.h | 2 +- kernel/rcu/rcutorture.c | 110 +++- kernel/torture.c| 16 +++ 3 files changed, 60 insertions(+), 68 deletions(-) diff --git a/include/linux/torture.h b/include/linux/torture.h index 5ca58fc..fec46f8 100644 --- a/include/linux/torture.h +++ b/include/linux/torture.h @@ -51,7 +51,7 @@ /* Definitions for online/offline exerciser. */ int torture_onoff_init(long ooholdoff, long oointerval); -char *torture_onoff_stats(char *page); +void torture_onoff_stats(void); bool torture_onoff_failures(void); /* Low-rider random number generator. */ diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 7fa34f8..bb6db08 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -242,7 +242,7 @@ struct rcu_torture_ops { void (*call)(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); void (*cb_barrier)(void); void (*fqs)(void); - void (*stats)(char *page); + void (*stats)(void); int irq_capable; int can_boost; const char *name; @@ -525,21 +525,21 @@ static void srcu_torture_barrier(void) srcu_barrier(_ctl); } -static void srcu_torture_stats(char *page) +static void srcu_torture_stats(void) { int cpu; int idx = srcu_ctl.completed & 0x1; - page += sprintf(page, "%s%s per-CPU(idx=%d):", - torture_type, TORTURE_FLAG, idx); + pr_alert("%s%s per-CPU(idx=%d):", +torture_type, TORTURE_FLAG, idx); for_each_possible_cpu(cpu) { long c0, c1; c0 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[!idx]; c1 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[idx]; - page += sprintf(page, " %d(%ld,%ld)", cpu, c0, c1); + pr_cont(" %d(%ld,%ld)", cpu, c0, c1); } -
Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On Thu, 2014-06-19 at 21:54 -0700, Paul E. McKenney wrote: On Thu, Jun 19, 2014 at 08:13:22PM -0400, Pranith Kumar wrote: On 06/19/2014 07:49 PM, Paul E. McKenney wrote: On Thu, Jun 19, 2014 at 07:24:48PM -0400, Pranith Kumar wrote: (dropping some CCs) On 06/19/2014 05:00 PM, Paul E. McKenney wrote: On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: I believe the function doesn't work well. static void rcu_torture_stats_print(void) { int size = nr_cpu_ids * 200 + 8192; char *buf; buf = kmalloc(size, GFP_KERNEL); if (!buf) { pr_err(rcu-torture: Out of memory, need: %d\n, size); return; } rcu_torture_printk(buf); pr_alert(%s, buf); kfree(buf); } rcu_torture_printk simply fills buf btw: I believe the arguments should pass size and rcu_torture_printk should use snprintf/size but all printks are limited to a maximum of 1024 bytes so the large allocation is senseless and would even if it worked, would likely need to be vmalloc/vfree Fair point! Pranith, Romanov, if you would like part of RCU that is less touchy about random hacking, this would be a good place to start. Scripts in tools/testing/selftests/rcutorture/bin do care about some of the format, but the variable-length portion generated by cur_ops-stats() is as far as I know only parsed by human eyes. Here is a first run of the change. Please let me know if I am totally off. RFC. :) Thank you for taking this on! You are most welcome :) Three things on Todo list: * We need to check that we are using less than the allocated size of the buffer (used size). (we are allocating a big buffer, so not sure if necessary) * Need to check with the scripts if they are working. * I used a loop for pr_alert(). I am not sure this is right, there should be a better way for printing large buffers If the overall structure is ok I will go ahead and check how the scripts are handling these changes. One other thing... Convince this function (and a few others that it calls) that the system really has 4096 CPUs, run this code, and see wshat actually happens both before and after. Just to get a bit of practice mixed in with the theory. ;-) OK. I think to do this I need to use 4096 instead of nr_cpu_ids. I will try this and see how it goes :) That's the spirit! You will probably have to adjust a few other things as well. Perhaps this should not use the allocation / page buffer and instead call pr_alert and pr_cont directly like this: include/linux/torture.h | 2 +- kernel/rcu/rcutorture.c | 110 +++- kernel/torture.c| 16 +++ 3 files changed, 60 insertions(+), 68 deletions(-) diff --git a/include/linux/torture.h b/include/linux/torture.h index 5ca58fc..fec46f8 100644 --- a/include/linux/torture.h +++ b/include/linux/torture.h @@ -51,7 +51,7 @@ /* Definitions for online/offline exerciser. */ int torture_onoff_init(long ooholdoff, long oointerval); -char *torture_onoff_stats(char *page); +void torture_onoff_stats(void); bool torture_onoff_failures(void); /* Low-rider random number generator. */ diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 7fa34f8..bb6db08 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -242,7 +242,7 @@ struct rcu_torture_ops { void (*call)(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); void (*cb_barrier)(void); void (*fqs)(void); - void (*stats)(char *page); + void (*stats)(void); int irq_capable; int can_boost; const char *name; @@ -525,21 +525,21 @@ static void srcu_torture_barrier(void) srcu_barrier(srcu_ctl); } -static void srcu_torture_stats(char *page) +static void srcu_torture_stats(void) { int cpu; int idx = srcu_ctl.completed 0x1; - page += sprintf(page, %s%s per-CPU(idx=%d):, - torture_type, TORTURE_FLAG, idx); + pr_alert(%s%s per-CPU(idx=%d):, +torture_type, TORTURE_FLAG, idx); for_each_possible_cpu(cpu) { long c0, c1; c0 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)-c[!idx]; c1 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)-c[idx]; - page += sprintf(page, %d(%ld,%ld), cpu, c0, c1); + pr_cont( %d(%ld,%ld), cpu, c0, c1); } - sprintf(page, \n); + pr_cont(\n); } static void srcu_torture_synchronize_expedited(void) @@ -1031,10 +1031,10 @@ rcu_torture_reader(void *arg) } /* - * Create an RCU-torture statistics message in the specified buffer. + * Print RCU-torture statistics */ static void -rcu_torture_printk(char *page) +rcu_torture_printk(void) {
Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On Thu, Jun 19, 2014 at 08:13:22PM -0400, Pranith Kumar wrote: > On 06/19/2014 07:49 PM, Paul E. McKenney wrote: > > On Thu, Jun 19, 2014 at 07:24:48PM -0400, Pranith Kumar wrote: > >> (dropping some CCs) > >> > >> On 06/19/2014 05:00 PM, Paul E. McKenney wrote: > >>> On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: > > I believe the function doesn't work well. > > static void > rcu_torture_stats_print(void) > { > int size = nr_cpu_ids * 200 + 8192; > char *buf; > > buf = kmalloc(size, GFP_KERNEL); > if (!buf) { > pr_err("rcu-torture: Out of memory, need: %d\n", size); > return; > } > rcu_torture_printk(buf); > pr_alert("%s", buf); > kfree(buf); > } > > rcu_torture_printk simply fills buf > > btw: I believe the arguments should pass size and > rcu_torture_printk should use snprintf/size > > but all printks are limited to a maximum of 1024 > bytes so the large allocation is senseless and > would even if it worked, would likely need to be > vmalloc/vfree > >>> > >>> Fair point! > >>> > >>> Pranith, Romanov, if you would like part of RCU that is less touchy > >>> about random hacking, this would be a good place to start. Scripts in > >>> tools/testing/selftests/rcutorture/bin do care about some of the format, > >>> but the variable-length portion generated by cur_ops->stats() is as far > >>> as I know only parsed by human eyes. > >>> > >> > >> Here is a first run of the change. Please let me know if I am totally off. > >> RFC. :) > > > > Thank you for taking this on! > > You are most welcome :) > > > > >> Three things on Todo list: > >> > >> * We need to check that we are using less than the allocated size of the > >> buffer (used > size). (we are allocating a big buffer, so not sure if > >> necessary) > >> * Need to check with the scripts if they are working. > >> * I used a loop for pr_alert(). I am not sure this is right, there should > >> be a better way for printing large buffers > >> > >> If the overall structure is ok I will go ahead and check how the scripts > >> are handling these changes. > > > > One other thing... Convince this function (and a few others that it > > calls) that the system really has 4096 CPUs, run this code, and see what > > actually happens both before and after. Just to get a bit of practice > > mixed in with the theory. ;-) > > > > OK. I think to do this I need to use 4096 instead of nr_cpu_ids. I will try > this and see how it goes :) That's the spirit! You will probably have to adjust a few other things as well. Thanx, Paul -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On 06/19/2014 07:49 PM, Paul E. McKenney wrote: > On Thu, Jun 19, 2014 at 07:24:48PM -0400, Pranith Kumar wrote: >> (dropping some CCs) >> >> On 06/19/2014 05:00 PM, Paul E. McKenney wrote: >>> On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: I believe the function doesn't work well. static void rcu_torture_stats_print(void) { int size = nr_cpu_ids * 200 + 8192; char *buf; buf = kmalloc(size, GFP_KERNEL); if (!buf) { pr_err("rcu-torture: Out of memory, need: %d\n", size); return; } rcu_torture_printk(buf); pr_alert("%s", buf); kfree(buf); } rcu_torture_printk simply fills buf btw: I believe the arguments should pass size and rcu_torture_printk should use snprintf/size but all printks are limited to a maximum of 1024 bytes so the large allocation is senseless and would even if it worked, would likely need to be vmalloc/vfree >>> >>> Fair point! >>> >>> Pranith, Romanov, if you would like part of RCU that is less touchy >>> about random hacking, this would be a good place to start. Scripts in >>> tools/testing/selftests/rcutorture/bin do care about some of the format, >>> but the variable-length portion generated by cur_ops->stats() is as far >>> as I know only parsed by human eyes. >>> >> >> Here is a first run of the change. Please let me know if I am totally off. >> RFC. :) > > Thank you for taking this on! You are most welcome :) > >> Three things on Todo list: >> >> * We need to check that we are using less than the allocated size of the >> buffer (used > size). (we are allocating a big buffer, so not sure if >> necessary) >> * Need to check with the scripts if they are working. >> * I used a loop for pr_alert(). I am not sure this is right, there should be >> a better way for printing large buffers >> >> If the overall structure is ok I will go ahead and check how the scripts are >> handling these changes. > > One other thing... Convince this function (and a few others that it > calls) that the system really has 4096 CPUs, run this code, and see what > actually happens both before and after. Just to get a bit of practice > mixed in with the theory. ;-) > OK. I think to do this I need to use 4096 instead of nr_cpu_ids. I will try this and see how it goes :) -- Pranith -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On 06/19/2014 07:33 PM, Joe Perches wrote: >> >> Here is a first run of the change. Please let me know if I am totally off. >> RFC. :) >> >> Three things on Todo list: >> >> * We need to check that we are using less than the allocated size of the >> buffer (used > size). (we are allocating a big buffer, so not sure if >> necessary) >> * Need to check with the scripts if they are working. >> * I used a loop for pr_alert(). I am not sure this is right, there should be >> a better way for printing large buffers >> >> If the overall structure is ok I will go ahead and check how the scripts are >> handling these changes. > [] >> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c > [] >> @@ -1130,17 +1134,23 @@ rcu_torture_printk(char *page) >> static void >> rcu_torture_stats_print(void) >> { > [] >> +/* printk can print only print LOG_LINE_MAX chars at a time */ >> +while (used > 0) { >> +size_pr = pr_alert("%s", buf); >> +used -= size_pr; >> +buf += size_pr; >> +} >> +vfree(buf); >> } > > You can't increment buf then vfree it. > > Try a char *tmpbuf = buf, and increment it. > > I suggest you check by strcspn(tmpbuf, "\n") > save the byte after, replace it with 0, > print, replace the 0 with saved byte, and > loop until end of buffer. > Please find v2 which I changed according to your comments: v2: * use tmpbuf to increment * print each line (search for "\n" as suggested and mark with '\0') * minor fix while calling cur_ops->stats Signed-off-by: Pranith Kumar --- include/linux/torture.h | 2 +- kernel/rcu/rcutorture.c | 86 ++--- kernel/torture.c| 7 ++-- 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/include/linux/torture.h b/include/linux/torture.h index 5ca58fc..1e47ec7 100644 --- a/include/linux/torture.h +++ b/include/linux/torture.h @@ -51,7 +51,7 @@ /* Definitions for online/offline exerciser. */ int torture_onoff_init(long ooholdoff, long oointerval); -char *torture_onoff_stats(char *page); +int torture_onoff_stats(char *page, int size); bool torture_onoff_failures(void); /* Low-rider random number generator. */ diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 7fa34f8..b149c5f 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -242,7 +242,7 @@ struct rcu_torture_ops { void (*call)(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); void (*cb_barrier)(void); void (*fqs)(void); - void (*stats)(char *page); + int (*stats)(char *page, int size); int irq_capable; int can_boost; const char *name; @@ -525,21 +525,22 @@ static void srcu_torture_barrier(void) srcu_barrier(_ctl); } -static void srcu_torture_stats(char *page) +static int srcu_torture_stats(char *page, int size) { - int cpu; + int cpu, used = 0; int idx = srcu_ctl.completed & 0x1; - page += sprintf(page, "%s%s per-CPU(idx=%d):", + used = snprintf(page, size, "%s%s per-CPU(idx=%d):", torture_type, TORTURE_FLAG, idx); for_each_possible_cpu(cpu) { long c0, c1; c0 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[!idx]; c1 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[idx]; - page += sprintf(page, " %d(%ld,%ld)", cpu, c0, c1); + used += snprintf(page + used, size - used, " %d(%ld,%ld)", cpu, c0, c1); } - sprintf(page, "\n"); + used += snprintf(page + used, size - used, "\n"); + return used; } static void srcu_torture_synchronize_expedited(void) @@ -1033,10 +1034,10 @@ rcu_torture_reader(void *arg) /* * Create an RCU-torture statistics message in the specified buffer. */ -static void -rcu_torture_printk(char *page) +static int +rcu_torture_printk(char *page, int size) { - int cpu; + int cpu, used = 0; int i; long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 }; long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 }; @@ -1052,8 +1053,8 @@ rcu_torture_printk(char *page) if (pipesummary[i] != 0) break; } - page += sprintf(page, "%s%s ", torture_type, TORTURE_FLAG); - page += sprintf(page, + used += snprintf(page + used, size - used, "%s%s ", torture_type, TORTURE_FLAG); + used += snprintf(page + used, size - used, "rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d ", rcu_torture_current, rcu_torture_current_version, @@ -1061,46 +1062,47 @@ rcu_torture_printk(char *page) atomic_read(_rcu_torture_alloc), atomic_read(_rcu_torture_alloc_fail), atomic_read(_rcu_torture_free)); - page += sprintf(page, "rtmbe: %d rtbke: %ld rtbre: %ld ", + used +=
Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On Thu, Jun 19, 2014 at 07:24:48PM -0400, Pranith Kumar wrote: > (dropping some CCs) > > On 06/19/2014 05:00 PM, Paul E. McKenney wrote: > > On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: > >> > >> I believe the function doesn't work well. > >> > >> static void > >> rcu_torture_stats_print(void) > >> { > >>int size = nr_cpu_ids * 200 + 8192; > >>char *buf; > >> > >>buf = kmalloc(size, GFP_KERNEL); > >>if (!buf) { > >>pr_err("rcu-torture: Out of memory, need: %d\n", size); > >>return; > >>} > >>rcu_torture_printk(buf); > >>pr_alert("%s", buf); > >>kfree(buf); > >> } > >> > >> rcu_torture_printk simply fills buf > >> > >> btw: I believe the arguments should pass size and > >> rcu_torture_printk should use snprintf/size > >> > >> but all printks are limited to a maximum of 1024 > >> bytes so the large allocation is senseless and > >> would even if it worked, would likely need to be > >> vmalloc/vfree > > > > Fair point! > > > > Pranith, Romanov, if you would like part of RCU that is less touchy > > about random hacking, this would be a good place to start. Scripts in > > tools/testing/selftests/rcutorture/bin do care about some of the format, > > but the variable-length portion generated by cur_ops->stats() is as far > > as I know only parsed by human eyes. > > > > Here is a first run of the change. Please let me know if I am totally off. > RFC. :) Thank you for taking this on! > Three things on Todo list: > > * We need to check that we are using less than the allocated size of the > buffer (used > size). (we are allocating a big buffer, so not sure if > necessary) > * Need to check with the scripts if they are working. > * I used a loop for pr_alert(). I am not sure this is right, there should be > a better way for printing large buffers > > If the overall structure is ok I will go ahead and check how the scripts are > handling these changes. One other thing... Convince this function (and a few others that it calls) that the system really has 4096 CPUs, run this code, and see what actually happens both before and after. Just to get a bit of practice mixed in with the theory. ;-) Thanx, Paul > >From 0d52fdcd941b0eaaacb6732f59f609595ac14d11 Mon Sep 17 00:00:00 2001 > From: Pranith Kumar > Date: Thu, 19 Jun 2014 19:00:46 -0400 > Subject: [PATCH 1/1] use snprintf instead of sprintf in > rcu_torture_print_stats > > Signed-off-by: Pranith Kumar > --- > include/linux/torture.h | 2 +- > kernel/rcu/rcutorture.c | 76 > - > kernel/torture.c| 7 +++-- > 3 files changed, 48 insertions(+), 37 deletions(-) > > diff --git a/include/linux/torture.h b/include/linux/torture.h > index 5ca58fc..1e47ec7 100644 > --- a/include/linux/torture.h > +++ b/include/linux/torture.h > @@ -51,7 +51,7 @@ > > /* Definitions for online/offline exerciser. */ > int torture_onoff_init(long ooholdoff, long oointerval); > -char *torture_onoff_stats(char *page); > +int torture_onoff_stats(char *page, int size); > bool torture_onoff_failures(void); > > /* Low-rider random number generator. */ > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c > index 7fa34f8..f708db4 100644 > --- a/kernel/rcu/rcutorture.c > +++ b/kernel/rcu/rcutorture.c > @@ -242,7 +242,7 @@ struct rcu_torture_ops { > void (*call)(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); > void (*cb_barrier)(void); > void (*fqs)(void); > - void (*stats)(char *page); > + int (*stats)(char *page, int size); > int irq_capable; > int can_boost; > const char *name; > @@ -525,21 +525,22 @@ static void srcu_torture_barrier(void) > srcu_barrier(_ctl); > } > > -static void srcu_torture_stats(char *page) > +static int srcu_torture_stats(char *page, int size) > { > - int cpu; > + int cpu, used = 0; > int idx = srcu_ctl.completed & 0x1; > > - page += sprintf(page, "%s%s per-CPU(idx=%d):", > + used = snprintf(page, size, "%s%s per-CPU(idx=%d):", > torture_type, TORTURE_FLAG, idx); > for_each_possible_cpu(cpu) { > long c0, c1; > > c0 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[!idx]; > c1 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[idx]; > - page += sprintf(page, " %d(%ld,%ld)", cpu, c0, c1); > + used += snprintf(page + used, size - used, " %d(%ld,%ld)", cpu, > c0, c1); > } > - sprintf(page, "\n"); > + used += snprintf(page + used, size - used, "\n"); > + return used; > } > > static void srcu_torture_synchronize_expedited(void) > @@ -1033,10 +1034,10 @@ rcu_torture_reader(void *arg) > /* > * Create an RCU-torture statistics message in the specified buffer. > */ > -static void > -rcu_torture_printk(char *page) > +static int > +rcu_torture_printk(char
Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On Thu, 2014-06-19 at 19:24 -0400, Pranith Kumar wrote: > (dropping some CCs) > > On 06/19/2014 05:00 PM, Paul E. McKenney wrote: > > On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: > >> > >> I believe the function doesn't work well. > >> > >> static void > >> rcu_torture_stats_print(void) > >> { > >>int size = nr_cpu_ids * 200 + 8192; > >>char *buf; > >> > >>buf = kmalloc(size, GFP_KERNEL); > >>if (!buf) { > >>pr_err("rcu-torture: Out of memory, need: %d\n", size); > >>return; > >>} > >>rcu_torture_printk(buf); > >>pr_alert("%s", buf); > >>kfree(buf); > >> } > >> > >> rcu_torture_printk simply fills buf > >> > >> btw: I believe the arguments should pass size and > >> rcu_torture_printk should use snprintf/size > >> > >> but all printks are limited to a maximum of 1024 > >> bytes so the large allocation is senseless and > >> would even if it worked, would likely need to be > >> vmalloc/vfree > > > > Fair point! > > > > Pranith, Romanov, if you would like part of RCU that is less touchy > > about random hacking, this would be a good place to start. Scripts in > > tools/testing/selftests/rcutorture/bin do care about some of the format, > > but the variable-length portion generated by cur_ops->stats() is as far > > as I know only parsed by human eyes. > > > > Here is a first run of the change. Please let me know if I am totally off. > RFC. :) > > Three things on Todo list: > > * We need to check that we are using less than the allocated size of the > buffer (used > size). (we are allocating a big buffer, so not sure if > necessary) > * Need to check with the scripts if they are working. > * I used a loop for pr_alert(). I am not sure this is right, there should be > a better way for printing large buffers > > If the overall structure is ok I will go ahead and check how the scripts are > handling these changes. [] > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c [] > @@ -1130,17 +1134,23 @@ rcu_torture_printk(char *page) > static void > rcu_torture_stats_print(void) > { [] > + /* printk can print only print LOG_LINE_MAX chars at a time */ > + while (used > 0) { > + size_pr = pr_alert("%s", buf); > + used -= size_pr; > + buf += size_pr; > + } > + vfree(buf); > } You can't increment buf then vfree it. Try a char *tmpbuf = buf, and increment it. I suggest you check by strcspn(tmpbuf, "\n") save the byte after, replace it with 0, print, replace the 0 with saved byte, and loop until end of buffer. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
(dropping some CCs) On 06/19/2014 05:00 PM, Paul E. McKenney wrote: > On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: >> >> I believe the function doesn't work well. >> >> static void >> rcu_torture_stats_print(void) >> { >> int size = nr_cpu_ids * 200 + 8192; >> char *buf; >> >> buf = kmalloc(size, GFP_KERNEL); >> if (!buf) { >> pr_err("rcu-torture: Out of memory, need: %d\n", size); >> return; >> } >> rcu_torture_printk(buf); >> pr_alert("%s", buf); >> kfree(buf); >> } >> >> rcu_torture_printk simply fills buf >> >> btw: I believe the arguments should pass size and >> rcu_torture_printk should use snprintf/size >> >> but all printks are limited to a maximum of 1024 >> bytes so the large allocation is senseless and >> would even if it worked, would likely need to be >> vmalloc/vfree > > Fair point! > > Pranith, Romanov, if you would like part of RCU that is less touchy > about random hacking, this would be a good place to start. Scripts in > tools/testing/selftests/rcutorture/bin do care about some of the format, > but the variable-length portion generated by cur_ops->stats() is as far > as I know only parsed by human eyes. > Here is a first run of the change. Please let me know if I am totally off. RFC. :) Three things on Todo list: * We need to check that we are using less than the allocated size of the buffer (used > size). (we are allocating a big buffer, so not sure if necessary) * Need to check with the scripts if they are working. * I used a loop for pr_alert(). I am not sure this is right, there should be a better way for printing large buffers If the overall structure is ok I will go ahead and check how the scripts are handling these changes. >From 0d52fdcd941b0eaaacb6732f59f609595ac14d11 Mon Sep 17 00:00:00 2001 From: Pranith Kumar Date: Thu, 19 Jun 2014 19:00:46 -0400 Subject: [PATCH 1/1] use snprintf instead of sprintf in rcu_torture_print_stats Signed-off-by: Pranith Kumar --- include/linux/torture.h | 2 +- kernel/rcu/rcutorture.c | 76 - kernel/torture.c| 7 +++-- 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/include/linux/torture.h b/include/linux/torture.h index 5ca58fc..1e47ec7 100644 --- a/include/linux/torture.h +++ b/include/linux/torture.h @@ -51,7 +51,7 @@ /* Definitions for online/offline exerciser. */ int torture_onoff_init(long ooholdoff, long oointerval); -char *torture_onoff_stats(char *page); +int torture_onoff_stats(char *page, int size); bool torture_onoff_failures(void); /* Low-rider random number generator. */ diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 7fa34f8..f708db4 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -242,7 +242,7 @@ struct rcu_torture_ops { void (*call)(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); void (*cb_barrier)(void); void (*fqs)(void); - void (*stats)(char *page); + int (*stats)(char *page, int size); int irq_capable; int can_boost; const char *name; @@ -525,21 +525,22 @@ static void srcu_torture_barrier(void) srcu_barrier(_ctl); } -static void srcu_torture_stats(char *page) +static int srcu_torture_stats(char *page, int size) { - int cpu; + int cpu, used = 0; int idx = srcu_ctl.completed & 0x1; - page += sprintf(page, "%s%s per-CPU(idx=%d):", + used = snprintf(page, size, "%s%s per-CPU(idx=%d):", torture_type, TORTURE_FLAG, idx); for_each_possible_cpu(cpu) { long c0, c1; c0 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[!idx]; c1 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[idx]; - page += sprintf(page, " %d(%ld,%ld)", cpu, c0, c1); + used += snprintf(page + used, size - used, " %d(%ld,%ld)", cpu, c0, c1); } - sprintf(page, "\n"); + used += snprintf(page + used, size - used, "\n"); + return used; } static void srcu_torture_synchronize_expedited(void) @@ -1033,10 +1034,10 @@ rcu_torture_reader(void *arg) /* * Create an RCU-torture statistics message in the specified buffer. */ -static void -rcu_torture_printk(char *page) +static int +rcu_torture_printk(char *page, int size) { - int cpu; + int cpu, used = 0; int i; long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 }; long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 }; @@ -1052,8 +1053,8 @@ rcu_torture_printk(char *page) if (pipesummary[i] != 0) break; } - page += sprintf(page, "%s%s ", torture_type, TORTURE_FLAG); - page += sprintf(page, + used += snprintf(page + used, size - used, "%s%s ", torture_type, TORTURE_FLAG); + used += snprintf(page + used, size - used, "rtc:
[RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
(dropping some CCs) On 06/19/2014 05:00 PM, Paul E. McKenney wrote: On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: I believe the function doesn't work well. static void rcu_torture_stats_print(void) { int size = nr_cpu_ids * 200 + 8192; char *buf; buf = kmalloc(size, GFP_KERNEL); if (!buf) { pr_err(rcu-torture: Out of memory, need: %d\n, size); return; } rcu_torture_printk(buf); pr_alert(%s, buf); kfree(buf); } rcu_torture_printk simply fills buf btw: I believe the arguments should pass size and rcu_torture_printk should use snprintf/size but all printks are limited to a maximum of 1024 bytes so the large allocation is senseless and would even if it worked, would likely need to be vmalloc/vfree Fair point! Pranith, Romanov, if you would like part of RCU that is less touchy about random hacking, this would be a good place to start. Scripts in tools/testing/selftests/rcutorture/bin do care about some of the format, but the variable-length portion generated by cur_ops-stats() is as far as I know only parsed by human eyes. Here is a first run of the change. Please let me know if I am totally off. RFC. :) Three things on Todo list: * We need to check that we are using less than the allocated size of the buffer (used size). (we are allocating a big buffer, so not sure if necessary) * Need to check with the scripts if they are working. * I used a loop for pr_alert(). I am not sure this is right, there should be a better way for printing large buffers If the overall structure is ok I will go ahead and check how the scripts are handling these changes. From 0d52fdcd941b0eaaacb6732f59f609595ac14d11 Mon Sep 17 00:00:00 2001 From: Pranith Kumar bobby.pr...@gmail.com Date: Thu, 19 Jun 2014 19:00:46 -0400 Subject: [PATCH 1/1] use snprintf instead of sprintf in rcu_torture_print_stats Signed-off-by: Pranith Kumar bobby.pr...@gmail.com --- include/linux/torture.h | 2 +- kernel/rcu/rcutorture.c | 76 - kernel/torture.c| 7 +++-- 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/include/linux/torture.h b/include/linux/torture.h index 5ca58fc..1e47ec7 100644 --- a/include/linux/torture.h +++ b/include/linux/torture.h @@ -51,7 +51,7 @@ /* Definitions for online/offline exerciser. */ int torture_onoff_init(long ooholdoff, long oointerval); -char *torture_onoff_stats(char *page); +int torture_onoff_stats(char *page, int size); bool torture_onoff_failures(void); /* Low-rider random number generator. */ diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 7fa34f8..f708db4 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -242,7 +242,7 @@ struct rcu_torture_ops { void (*call)(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); void (*cb_barrier)(void); void (*fqs)(void); - void (*stats)(char *page); + int (*stats)(char *page, int size); int irq_capable; int can_boost; const char *name; @@ -525,21 +525,22 @@ static void srcu_torture_barrier(void) srcu_barrier(srcu_ctl); } -static void srcu_torture_stats(char *page) +static int srcu_torture_stats(char *page, int size) { - int cpu; + int cpu, used = 0; int idx = srcu_ctl.completed 0x1; - page += sprintf(page, %s%s per-CPU(idx=%d):, + used = snprintf(page, size, %s%s per-CPU(idx=%d):, torture_type, TORTURE_FLAG, idx); for_each_possible_cpu(cpu) { long c0, c1; c0 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)-c[!idx]; c1 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)-c[idx]; - page += sprintf(page, %d(%ld,%ld), cpu, c0, c1); + used += snprintf(page + used, size - used, %d(%ld,%ld), cpu, c0, c1); } - sprintf(page, \n); + used += snprintf(page + used, size - used, \n); + return used; } static void srcu_torture_synchronize_expedited(void) @@ -1033,10 +1034,10 @@ rcu_torture_reader(void *arg) /* * Create an RCU-torture statistics message in the specified buffer. */ -static void -rcu_torture_printk(char *page) +static int +rcu_torture_printk(char *page, int size) { - int cpu; + int cpu, used = 0; int i; long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 }; long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 }; @@ -1052,8 +1053,8 @@ rcu_torture_printk(char *page) if (pipesummary[i] != 0) break; } - page += sprintf(page, %s%s , torture_type, TORTURE_FLAG); - page += sprintf(page, + used += snprintf(page + used, size - used, %s%s , torture_type, TORTURE_FLAG); + used += snprintf(page + used, size - used, rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d ,
Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On Thu, 2014-06-19 at 19:24 -0400, Pranith Kumar wrote: (dropping some CCs) On 06/19/2014 05:00 PM, Paul E. McKenney wrote: On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: I believe the function doesn't work well. static void rcu_torture_stats_print(void) { int size = nr_cpu_ids * 200 + 8192; char *buf; buf = kmalloc(size, GFP_KERNEL); if (!buf) { pr_err(rcu-torture: Out of memory, need: %d\n, size); return; } rcu_torture_printk(buf); pr_alert(%s, buf); kfree(buf); } rcu_torture_printk simply fills buf btw: I believe the arguments should pass size and rcu_torture_printk should use snprintf/size but all printks are limited to a maximum of 1024 bytes so the large allocation is senseless and would even if it worked, would likely need to be vmalloc/vfree Fair point! Pranith, Romanov, if you would like part of RCU that is less touchy about random hacking, this would be a good place to start. Scripts in tools/testing/selftests/rcutorture/bin do care about some of the format, but the variable-length portion generated by cur_ops-stats() is as far as I know only parsed by human eyes. Here is a first run of the change. Please let me know if I am totally off. RFC. :) Three things on Todo list: * We need to check that we are using less than the allocated size of the buffer (used size). (we are allocating a big buffer, so not sure if necessary) * Need to check with the scripts if they are working. * I used a loop for pr_alert(). I am not sure this is right, there should be a better way for printing large buffers If the overall structure is ok I will go ahead and check how the scripts are handling these changes. [] diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c [] @@ -1130,17 +1134,23 @@ rcu_torture_printk(char *page) static void rcu_torture_stats_print(void) { [] + /* printk can print only print LOG_LINE_MAX chars at a time */ + while (used 0) { + size_pr = pr_alert(%s, buf); + used -= size_pr; + buf += size_pr; + } + vfree(buf); } You can't increment buf then vfree it. Try a char *tmpbuf = buf, and increment it. I suggest you check by strcspn(tmpbuf, \n) save the byte after, replace it with 0, print, replace the 0 with saved byte, and loop until end of buffer. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On Thu, Jun 19, 2014 at 07:24:48PM -0400, Pranith Kumar wrote: (dropping some CCs) On 06/19/2014 05:00 PM, Paul E. McKenney wrote: On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: I believe the function doesn't work well. static void rcu_torture_stats_print(void) { int size = nr_cpu_ids * 200 + 8192; char *buf; buf = kmalloc(size, GFP_KERNEL); if (!buf) { pr_err(rcu-torture: Out of memory, need: %d\n, size); return; } rcu_torture_printk(buf); pr_alert(%s, buf); kfree(buf); } rcu_torture_printk simply fills buf btw: I believe the arguments should pass size and rcu_torture_printk should use snprintf/size but all printks are limited to a maximum of 1024 bytes so the large allocation is senseless and would even if it worked, would likely need to be vmalloc/vfree Fair point! Pranith, Romanov, if you would like part of RCU that is less touchy about random hacking, this would be a good place to start. Scripts in tools/testing/selftests/rcutorture/bin do care about some of the format, but the variable-length portion generated by cur_ops-stats() is as far as I know only parsed by human eyes. Here is a first run of the change. Please let me know if I am totally off. RFC. :) Thank you for taking this on! Three things on Todo list: * We need to check that we are using less than the allocated size of the buffer (used size). (we are allocating a big buffer, so not sure if necessary) * Need to check with the scripts if they are working. * I used a loop for pr_alert(). I am not sure this is right, there should be a better way for printing large buffers If the overall structure is ok I will go ahead and check how the scripts are handling these changes. One other thing... Convince this function (and a few others that it calls) that the system really has 4096 CPUs, run this code, and see what actually happens both before and after. Just to get a bit of practice mixed in with the theory. ;-) Thanx, Paul From 0d52fdcd941b0eaaacb6732f59f609595ac14d11 Mon Sep 17 00:00:00 2001 From: Pranith Kumar bobby.pr...@gmail.com Date: Thu, 19 Jun 2014 19:00:46 -0400 Subject: [PATCH 1/1] use snprintf instead of sprintf in rcu_torture_print_stats Signed-off-by: Pranith Kumar bobby.pr...@gmail.com --- include/linux/torture.h | 2 +- kernel/rcu/rcutorture.c | 76 - kernel/torture.c| 7 +++-- 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/include/linux/torture.h b/include/linux/torture.h index 5ca58fc..1e47ec7 100644 --- a/include/linux/torture.h +++ b/include/linux/torture.h @@ -51,7 +51,7 @@ /* Definitions for online/offline exerciser. */ int torture_onoff_init(long ooholdoff, long oointerval); -char *torture_onoff_stats(char *page); +int torture_onoff_stats(char *page, int size); bool torture_onoff_failures(void); /* Low-rider random number generator. */ diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 7fa34f8..f708db4 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -242,7 +242,7 @@ struct rcu_torture_ops { void (*call)(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); void (*cb_barrier)(void); void (*fqs)(void); - void (*stats)(char *page); + int (*stats)(char *page, int size); int irq_capable; int can_boost; const char *name; @@ -525,21 +525,22 @@ static void srcu_torture_barrier(void) srcu_barrier(srcu_ctl); } -static void srcu_torture_stats(char *page) +static int srcu_torture_stats(char *page, int size) { - int cpu; + int cpu, used = 0; int idx = srcu_ctl.completed 0x1; - page += sprintf(page, %s%s per-CPU(idx=%d):, + used = snprintf(page, size, %s%s per-CPU(idx=%d):, torture_type, TORTURE_FLAG, idx); for_each_possible_cpu(cpu) { long c0, c1; c0 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)-c[!idx]; c1 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)-c[idx]; - page += sprintf(page, %d(%ld,%ld), cpu, c0, c1); + used += snprintf(page + used, size - used, %d(%ld,%ld), cpu, c0, c1); } - sprintf(page, \n); + used += snprintf(page + used, size - used, \n); + return used; } static void srcu_torture_synchronize_expedited(void) @@ -1033,10 +1034,10 @@ rcu_torture_reader(void *arg) /* * Create an RCU-torture statistics message in the specified buffer. */ -static void -rcu_torture_printk(char *page) +static int +rcu_torture_printk(char *page, int size) { - int cpu; + int cpu, used = 0; int i; long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 }; long
Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On 06/19/2014 07:33 PM, Joe Perches wrote: Here is a first run of the change. Please let me know if I am totally off. RFC. :) Three things on Todo list: * We need to check that we are using less than the allocated size of the buffer (used size). (we are allocating a big buffer, so not sure if necessary) * Need to check with the scripts if they are working. * I used a loop for pr_alert(). I am not sure this is right, there should be a better way for printing large buffers If the overall structure is ok I will go ahead and check how the scripts are handling these changes. [] diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c [] @@ -1130,17 +1134,23 @@ rcu_torture_printk(char *page) static void rcu_torture_stats_print(void) { [] +/* printk can print only print LOG_LINE_MAX chars at a time */ +while (used 0) { +size_pr = pr_alert(%s, buf); +used -= size_pr; +buf += size_pr; +} +vfree(buf); } You can't increment buf then vfree it. Try a char *tmpbuf = buf, and increment it. I suggest you check by strcspn(tmpbuf, \n) save the byte after, replace it with 0, print, replace the 0 with saved byte, and loop until end of buffer. Please find v2 which I changed according to your comments: v2: * use tmpbuf to increment * print each line (search for \n as suggested and mark with '\0') * minor fix while calling cur_ops-stats Signed-off-by: Pranith Kumar bobby.pr...@gmail.com --- include/linux/torture.h | 2 +- kernel/rcu/rcutorture.c | 86 ++--- kernel/torture.c| 7 ++-- 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/include/linux/torture.h b/include/linux/torture.h index 5ca58fc..1e47ec7 100644 --- a/include/linux/torture.h +++ b/include/linux/torture.h @@ -51,7 +51,7 @@ /* Definitions for online/offline exerciser. */ int torture_onoff_init(long ooholdoff, long oointerval); -char *torture_onoff_stats(char *page); +int torture_onoff_stats(char *page, int size); bool torture_onoff_failures(void); /* Low-rider random number generator. */ diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 7fa34f8..b149c5f 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -242,7 +242,7 @@ struct rcu_torture_ops { void (*call)(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); void (*cb_barrier)(void); void (*fqs)(void); - void (*stats)(char *page); + int (*stats)(char *page, int size); int irq_capable; int can_boost; const char *name; @@ -525,21 +525,22 @@ static void srcu_torture_barrier(void) srcu_barrier(srcu_ctl); } -static void srcu_torture_stats(char *page) +static int srcu_torture_stats(char *page, int size) { - int cpu; + int cpu, used = 0; int idx = srcu_ctl.completed 0x1; - page += sprintf(page, %s%s per-CPU(idx=%d):, + used = snprintf(page, size, %s%s per-CPU(idx=%d):, torture_type, TORTURE_FLAG, idx); for_each_possible_cpu(cpu) { long c0, c1; c0 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)-c[!idx]; c1 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)-c[idx]; - page += sprintf(page, %d(%ld,%ld), cpu, c0, c1); + used += snprintf(page + used, size - used, %d(%ld,%ld), cpu, c0, c1); } - sprintf(page, \n); + used += snprintf(page + used, size - used, \n); + return used; } static void srcu_torture_synchronize_expedited(void) @@ -1033,10 +1034,10 @@ rcu_torture_reader(void *arg) /* * Create an RCU-torture statistics message in the specified buffer. */ -static void -rcu_torture_printk(char *page) +static int +rcu_torture_printk(char *page, int size) { - int cpu; + int cpu, used = 0; int i; long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 }; long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 }; @@ -1052,8 +1053,8 @@ rcu_torture_printk(char *page) if (pipesummary[i] != 0) break; } - page += sprintf(page, %s%s , torture_type, TORTURE_FLAG); - page += sprintf(page, + used += snprintf(page + used, size - used, %s%s , torture_type, TORTURE_FLAG); + used += snprintf(page + used, size - used, rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d , rcu_torture_current, rcu_torture_current_version, @@ -1061,46 +1062,47 @@ rcu_torture_printk(char *page) atomic_read(n_rcu_torture_alloc), atomic_read(n_rcu_torture_alloc_fail), atomic_read(n_rcu_torture_free)); - page += sprintf(page, rtmbe: %d rtbke: %ld rtbre: %ld , + used += snprintf(page + used, size - used, rtmbe: %d rtbke: %ld rtbre: %ld ,
Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On 06/19/2014 07:49 PM, Paul E. McKenney wrote: On Thu, Jun 19, 2014 at 07:24:48PM -0400, Pranith Kumar wrote: (dropping some CCs) On 06/19/2014 05:00 PM, Paul E. McKenney wrote: On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: I believe the function doesn't work well. static void rcu_torture_stats_print(void) { int size = nr_cpu_ids * 200 + 8192; char *buf; buf = kmalloc(size, GFP_KERNEL); if (!buf) { pr_err(rcu-torture: Out of memory, need: %d\n, size); return; } rcu_torture_printk(buf); pr_alert(%s, buf); kfree(buf); } rcu_torture_printk simply fills buf btw: I believe the arguments should pass size and rcu_torture_printk should use snprintf/size but all printks are limited to a maximum of 1024 bytes so the large allocation is senseless and would even if it worked, would likely need to be vmalloc/vfree Fair point! Pranith, Romanov, if you would like part of RCU that is less touchy about random hacking, this would be a good place to start. Scripts in tools/testing/selftests/rcutorture/bin do care about some of the format, but the variable-length portion generated by cur_ops-stats() is as far as I know only parsed by human eyes. Here is a first run of the change. Please let me know if I am totally off. RFC. :) Thank you for taking this on! You are most welcome :) Three things on Todo list: * We need to check that we are using less than the allocated size of the buffer (used size). (we are allocating a big buffer, so not sure if necessary) * Need to check with the scripts if they are working. * I used a loop for pr_alert(). I am not sure this is right, there should be a better way for printing large buffers If the overall structure is ok I will go ahead and check how the scripts are handling these changes. One other thing... Convince this function (and a few others that it calls) that the system really has 4096 CPUs, run this code, and see what actually happens both before and after. Just to get a bit of practice mixed in with the theory. ;-) OK. I think to do this I need to use 4096 instead of nr_cpu_ids. I will try this and see how it goes :) -- Pranith -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] use snprintf instead of sprintf in rcu_torture_printk
On Thu, Jun 19, 2014 at 08:13:22PM -0400, Pranith Kumar wrote: On 06/19/2014 07:49 PM, Paul E. McKenney wrote: On Thu, Jun 19, 2014 at 07:24:48PM -0400, Pranith Kumar wrote: (dropping some CCs) On 06/19/2014 05:00 PM, Paul E. McKenney wrote: On Wed, Jun 18, 2014 at 12:49:42PM -0700, Joe Perches wrote: I believe the function doesn't work well. static void rcu_torture_stats_print(void) { int size = nr_cpu_ids * 200 + 8192; char *buf; buf = kmalloc(size, GFP_KERNEL); if (!buf) { pr_err(rcu-torture: Out of memory, need: %d\n, size); return; } rcu_torture_printk(buf); pr_alert(%s, buf); kfree(buf); } rcu_torture_printk simply fills buf btw: I believe the arguments should pass size and rcu_torture_printk should use snprintf/size but all printks are limited to a maximum of 1024 bytes so the large allocation is senseless and would even if it worked, would likely need to be vmalloc/vfree Fair point! Pranith, Romanov, if you would like part of RCU that is less touchy about random hacking, this would be a good place to start. Scripts in tools/testing/selftests/rcutorture/bin do care about some of the format, but the variable-length portion generated by cur_ops-stats() is as far as I know only parsed by human eyes. Here is a first run of the change. Please let me know if I am totally off. RFC. :) Thank you for taking this on! You are most welcome :) Three things on Todo list: * We need to check that we are using less than the allocated size of the buffer (used size). (we are allocating a big buffer, so not sure if necessary) * Need to check with the scripts if they are working. * I used a loop for pr_alert(). I am not sure this is right, there should be a better way for printing large buffers If the overall structure is ok I will go ahead and check how the scripts are handling these changes. One other thing... Convince this function (and a few others that it calls) that the system really has 4096 CPUs, run this code, and see what actually happens both before and after. Just to get a bit of practice mixed in with the theory. ;-) OK. I think to do this I need to use 4096 instead of nr_cpu_ids. I will try this and see how it goes :) That's the spirit! You will probably have to adjust a few other things as well. Thanx, Paul -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/