LKML Archive on lore.kernel.org help / color / mirror / Atom feed
* [PATCH] video: limit stack usage of ir-kbd-i2c.c @ 2008-02-25 20:51 Marcin Slusarz 2008-02-26 12:32 ` Jean Delvare 0 siblings, 1 reply; 7+ messages in thread From: Marcin Slusarz @ 2008-02-25 20:51 UTC (permalink / raw) To: LKML; +Cc: Mauro Carvalho Chehab, Jean Delvare, i2c, video4linux-list ir_probe allocated struct i2c_client on stack; it's pretty big structure, so allocate it with kzalloc make checkstack output without this patch: x059d ir_probe [ir-kbd-i2c]: 1000 compile tested only Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com> Cc: Mauro Carvalho Chehab <mchehab@infradead.org> Cc: Jean Delvare <khali@linux-fr.org> --- drivers/media/video/ir-kbd-i2c.c | 18 +++++++++++------- 1 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 9851987..aec122f 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -510,9 +510,9 @@ static int ir_probe(struct i2c_adapter *adap) static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; static const int probe_cx23885[] = { 0x6b, -1 }; const int *probe = NULL; - struct i2c_client c; + struct i2c_client *c; unsigned char buf; - int i,rc; + int i, rc; switch (adap->id) { case I2C_HW_B_BT848: @@ -537,19 +537,23 @@ static int ir_probe(struct i2c_adapter *adap) if (NULL == probe) return 0; - memset(&c,0,sizeof(c)); - c.adapter = adap; + c = kzalloc(sizeof(*c), GFP_KERNEL); + if (!c) + return -ENOMEM; + + c->adapter = adap; for (i = 0; -1 != probe[i]; i++) { - c.addr = probe[i]; - rc = i2c_master_recv(&c,&buf,0); + c->addr = probe[i]; + rc = i2c_master_recv(c, &buf, 0); dprintk(1,"probe 0x%02x @ %s: %s\n", probe[i], adap->name, (0 == rc) ? "yes" : "no"); if (0 == rc) { - ir_attach(adap,probe[i],0,0); + ir_attach(adap, probe[i], 0, 0); break; } } + kfree(c); return 0; } -- 1.5.3.7 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] video: limit stack usage of ir-kbd-i2c.c 2008-02-25 20:51 [PATCH] video: limit stack usage of ir-kbd-i2c.c Marcin Slusarz @ 2008-02-26 12:32 ` Jean Delvare 2008-02-26 21:03 ` Marcin Slusarz 0 siblings, 1 reply; 7+ messages in thread From: Jean Delvare @ 2008-02-26 12:32 UTC (permalink / raw) To: Marcin Slusarz; +Cc: LKML, Mauro Carvalho Chehab, i2c, video4linux-list Hi Marcin, On Mon, 25 Feb 2008 21:51:00 +0100, Marcin Slusarz wrote: > ir_probe allocated struct i2c_client on stack; > it's pretty big structure, so allocate it with kzalloc > > make checkstack output without this patch: > x059d ir_probe [ir-kbd-i2c]: 1000 > > compile tested only > > Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com> > Cc: Mauro Carvalho Chehab <mchehab@infradead.org> > Cc: Jean Delvare <khali@linux-fr.org> > --- > drivers/media/video/ir-kbd-i2c.c | 18 +++++++++++------- > 1 files changed, 11 insertions(+), 7 deletions(-) > > diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c > index 9851987..aec122f 100644 > --- a/drivers/media/video/ir-kbd-i2c.c > +++ b/drivers/media/video/ir-kbd-i2c.c > @@ -510,9 +510,9 @@ static int ir_probe(struct i2c_adapter *adap) > static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; > static const int probe_cx23885[] = { 0x6b, -1 }; > const int *probe = NULL; > - struct i2c_client c; > + struct i2c_client *c; > unsigned char buf; > - int i,rc; > + int i, rc; > > switch (adap->id) { > case I2C_HW_B_BT848: > @@ -537,19 +537,23 @@ static int ir_probe(struct i2c_adapter *adap) > if (NULL == probe) > return 0; > > - memset(&c,0,sizeof(c)); > - c.adapter = adap; > + c = kzalloc(sizeof(*c), GFP_KERNEL); > + if (!c) > + return -ENOMEM; > + > + c->adapter = adap; > for (i = 0; -1 != probe[i]; i++) { > - c.addr = probe[i]; > - rc = i2c_master_recv(&c,&buf,0); > + c->addr = probe[i]; > + rc = i2c_master_recv(c, &buf, 0); > dprintk(1,"probe 0x%02x @ %s: %s\n", > probe[i], adap->name, > (0 == rc) ? "yes" : "no"); > if (0 == rc) { > - ir_attach(adap,probe[i],0,0); > + ir_attach(adap, probe[i], 0, 0); > break; > } > } > + kfree(c); > return 0; > } > While this works, I'd rather change the code to call i2c_transfer() instead of i2c_master_recv(). i2c_transfer() is meant exactly for this case (no i2c_client at hand.) This solves the stack usage problem without requiring a temporary memory allocation: * * * * * Limit stack usage in ir_probe by calling i2c_transfer, which doesn't require a struct i2c_client, instead of i2c_master_recv which does. Signed-off-by: Jean Delvare <khali@linux-fr.org> --- drivers/media/video/ir-kbd-i2c.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) --- linux-2.6.25-rc3.orig/drivers/media/video/ir-kbd-i2c.c 2008-02-26 11:35:51.000000000 +0100 +++ linux-2.6.25-rc3/drivers/media/video/ir-kbd-i2c.c 2008-02-26 11:44:54.000000000 +0100 @@ -510,8 +510,11 @@ static int ir_probe(struct i2c_adapter * static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; static const int probe_cx23885[] = { 0x6b, -1 }; const int *probe = NULL; - struct i2c_client c; - unsigned char buf; + struct i2c_msg msg = { + .flags = I2C_M_RD, + .len = 0, + .buf = NULL, + }; int i,rc; switch (adap->id) { @@ -537,15 +540,13 @@ static int ir_probe(struct i2c_adapter * if (NULL == probe) return 0; - memset(&c,0,sizeof(c)); - c.adapter = adap; for (i = 0; -1 != probe[i]; i++) { - c.addr = probe[i]; - rc = i2c_master_recv(&c,&buf,0); + msg.addr = probe[i]; + rc = i2c_transfer(adap, &msg, 1); dprintk(1,"probe 0x%02x @ %s: %s\n", probe[i], adap->name, - (0 == rc) ? "yes" : "no"); - if (0 == rc) { + (1 == rc) ? "yes" : "no"); + if (1 == rc) { ir_attach(adap,probe[i],0,0); break; } Built-tested, I've also tested loading the ir-kbd-i2c driver on an unsupported cx88 adapter. Review and more testing welcome. -- Jean Delvare ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] video: limit stack usage of ir-kbd-i2c.c 2008-02-26 12:32 ` Jean Delvare @ 2008-02-26 21:03 ` Marcin Slusarz 2008-02-26 22:23 ` Jean Delvare 0 siblings, 1 reply; 7+ messages in thread From: Marcin Slusarz @ 2008-02-26 21:03 UTC (permalink / raw) To: Jean Delvare; +Cc: LKML, Mauro Carvalho Chehab, i2c, video4linux-list On Tue, Feb 26, 2008 at 01:32:22PM +0100, Jean Delvare wrote: > Hi Marcin, > > On Mon, 25 Feb 2008 21:51:00 +0100, Marcin Slusarz wrote: > > ir_probe allocated struct i2c_client on stack; > > it's pretty big structure, so allocate it with kzalloc > > > > make checkstack output without this patch: > > x059d ir_probe [ir-kbd-i2c]: 1000 > > > > compile tested only > > > > Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com> > > Cc: Mauro Carvalho Chehab <mchehab@infradead.org> > > Cc: Jean Delvare <khali@linux-fr.org> > > --- > > drivers/media/video/ir-kbd-i2c.c | 18 +++++++++++------- > > 1 files changed, 11 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c > > index 9851987..aec122f 100644 > > --- a/drivers/media/video/ir-kbd-i2c.c > > +++ b/drivers/media/video/ir-kbd-i2c.c > > @@ -510,9 +510,9 @@ static int ir_probe(struct i2c_adapter *adap) > > static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; > > static const int probe_cx23885[] = { 0x6b, -1 }; > > const int *probe = NULL; > > - struct i2c_client c; > > + struct i2c_client *c; > > unsigned char buf; > > - int i,rc; > > + int i, rc; > > > > switch (adap->id) { > > case I2C_HW_B_BT848: > > @@ -537,19 +537,23 @@ static int ir_probe(struct i2c_adapter *adap) > > if (NULL == probe) > > return 0; > > > > - memset(&c,0,sizeof(c)); > > - c.adapter = adap; > > + c = kzalloc(sizeof(*c), GFP_KERNEL); > > + if (!c) > > + return -ENOMEM; > > + > > + c->adapter = adap; > > for (i = 0; -1 != probe[i]; i++) { > > - c.addr = probe[i]; > > - rc = i2c_master_recv(&c,&buf,0); > > + c->addr = probe[i]; > > + rc = i2c_master_recv(c, &buf, 0); > > dprintk(1,"probe 0x%02x @ %s: %s\n", > > probe[i], adap->name, > > (0 == rc) ? "yes" : "no"); > > if (0 == rc) { > > - ir_attach(adap,probe[i],0,0); > > + ir_attach(adap, probe[i], 0, 0); > > break; > > } > > } > > + kfree(c); > > return 0; > > } > > > > While this works, I'd rather change the code to call i2c_transfer() > instead of i2c_master_recv(). i2c_transfer() is meant exactly for this > case (no i2c_client at hand.) This solves the stack usage problem > without requiring a temporary memory allocation: > > * * * * * > > Limit stack usage in ir_probe by calling i2c_transfer, which doesn't > require a struct i2c_client, instead of i2c_master_recv which does. > > Signed-off-by: Jean Delvare <khali@linux-fr.org> > --- > drivers/media/video/ir-kbd-i2c.c | 17 +++++++++-------- > 1 file changed, 9 insertions(+), 8 deletions(-) > > --- linux-2.6.25-rc3.orig/drivers/media/video/ir-kbd-i2c.c 2008-02-26 11:35:51.000000000 +0100 > +++ linux-2.6.25-rc3/drivers/media/video/ir-kbd-i2c.c 2008-02-26 11:44:54.000000000 +0100 > @@ -510,8 +510,11 @@ static int ir_probe(struct i2c_adapter * > static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; > static const int probe_cx23885[] = { 0x6b, -1 }; > const int *probe = NULL; > - struct i2c_client c; > - unsigned char buf; > + struct i2c_msg msg = { > + .flags = I2C_M_RD, > + .len = 0, > + .buf = NULL, > + }; > int i,rc; > > switch (adap->id) { > @@ -537,15 +540,13 @@ static int ir_probe(struct i2c_adapter * > if (NULL == probe) > return 0; > > - memset(&c,0,sizeof(c)); > - c.adapter = adap; > for (i = 0; -1 != probe[i]; i++) { > - c.addr = probe[i]; > - rc = i2c_master_recv(&c,&buf,0); > + msg.addr = probe[i]; > + rc = i2c_transfer(adap, &msg, 1); > dprintk(1,"probe 0x%02x @ %s: %s\n", > probe[i], adap->name, > - (0 == rc) ? "yes" : "no"); > - if (0 == rc) { > + (1 == rc) ? "yes" : "no"); > + if (1 == rc) { > ir_attach(adap,probe[i],0,0); > break; > } > > > Built-tested, I've also tested loading the ir-kbd-i2c driver on an > unsupported cx88 adapter. Review and more testing welcome. I know nothing about I2C API, so I can't comment on correctness of this patch ;) Do you have an idea (or patch :D) how to solve this: 0x00000234 v4l_compat_translate_ioctl [v4l1-compat]: 1376 ? That's on top of my make checkstack output Marcin ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] video: limit stack usage of ir-kbd-i2c.c 2008-02-26 21:03 ` Marcin Slusarz @ 2008-02-26 22:23 ` Jean Delvare 2008-02-27 10:23 ` Marcin Slusarz 0 siblings, 1 reply; 7+ messages in thread From: Jean Delvare @ 2008-02-26 22:23 UTC (permalink / raw) To: Marcin Slusarz; +Cc: LKML, Mauro Carvalho Chehab, i2c, video4linux-list Hi Marcin, On Tue, 26 Feb 2008 22:03:16 +0100, Marcin Slusarz wrote: > Do you have an idea (or patch :D) how to solve this: > 0x00000234 v4l_compat_translate_ioctl [v4l1-compat]: 1376 > ? That's on top of my make checkstack output Random ideas (but I am in no way a specialist of this exercise): * You could try moving the structures to the blocks where they are used, in the case a given structure is used for only one ioctl. I'm not too sure how gcc handles local variables declared inside blocks with regards to stack reservation though. I thought it would work but my experiments today seem to suggest it doesn't. * You can move the handling of some ioctls to dedicated functions, just like I did in i2c-dev: http://lists.lm-sensors.org/pipermail/i2c/2008-February/003010.html However there is a risk that gcc will inline these functions (that's what happened to me...) Not sure how to prevent gcc from inlining. * You can allocate the structures dynamically, as you originally wanted to do for ir-kbd-i2c. However this has a performance penalty and will fragment the memory, so it's not ideal. * If each ioctl uses only one of the structures, you may define a union of all the structures. The size of the union will be the size of the biggest structure, so you save a lot of space on the stack. -- Jean Delvare ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] video: limit stack usage of ir-kbd-i2c.c 2008-02-26 22:23 ` Jean Delvare @ 2008-02-27 10:23 ` Marcin Slusarz 2008-02-27 10:33 ` Mauro Carvalho Chehab 2008-02-28 18:29 ` Jean Delvare 0 siblings, 2 replies; 7+ messages in thread From: Marcin Slusarz @ 2008-02-27 10:23 UTC (permalink / raw) To: Jean Delvare; +Cc: LKML, Mauro Carvalho Chehab, i2c, video4linux-list On Tue, Feb 26, 2008 at 11:23:20PM +0100, Jean Delvare wrote: > Hi Marcin, Hi > On Tue, 26 Feb 2008 22:03:16 +0100, Marcin Slusarz wrote: > > Do you have an idea (or patch :D) how to solve this: > > 0x00000234 v4l_compat_translate_ioctl [v4l1-compat]: 1376 > > ? That's on top of my make checkstack output > > Random ideas (but I am in no way a specialist of this exercise): > > * You could try moving the structures to the blocks where they are used, > in the case a given structure is used for only one ioctl. I'm not too > sure how gcc handles local variables declared inside blocks with > regards to stack reservation though. I thought it would work but my > experiments today seem to suggest it doesn't. That won't work. Variables at beginning of function take only ~600 bytes, so the rest must be from inner blocks and inlines (probably). > * You can move the handling of some ioctls to dedicated functions, just > like I did in i2c-dev: > http://lists.lm-sensors.org/pipermail/i2c/2008-February/003010.html > However there is a risk that gcc will inline these functions (that's > what happened to me...) Not sure how to prevent gcc from inlining. There's "noinline" attribute in linux/compiler.h (compiler-gcc.h actually) for these situations. > * You can allocate the structures dynamically, as you originally wanted > to do for ir-kbd-i2c. However this has a performance penalty and will > fragment the memory, so it's not ideal. > > * If each ioctl uses only one of the structures, you may define a union > of all the structures. The size of the union will be the size of the > biggest structure, so you save a lot of space on the stack. Nice idea. I'll try 2nd and 4th approaches. Marcin Slusarz ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] video: limit stack usage of ir-kbd-i2c.c 2008-02-27 10:23 ` Marcin Slusarz @ 2008-02-27 10:33 ` Mauro Carvalho Chehab 2008-02-28 18:29 ` Jean Delvare 1 sibling, 0 replies; 7+ messages in thread From: Mauro Carvalho Chehab @ 2008-02-27 10:33 UTC (permalink / raw) To: Marcin Slusarz; +Cc: Jean Delvare, LKML, i2c, video4linux-list On Wed, 27 Feb 2008 11:23:26 +0100 Marcin Slusarz <marcin.slusarz@gmail.com> wrote: > On Tue, Feb 26, 2008 at 11:23:20PM +0100, Jean Delvare wrote: > > Hi Marcin, > Hi > > > On Tue, 26 Feb 2008 22:03:16 +0100, Marcin Slusarz wrote: > > > Do you have an idea (or patch :D) how to solve this: > > > 0x00000234 v4l_compat_translate_ioctl [v4l1-compat]: 1376 > > > ? That's on top of my make checkstack output > > > > Random ideas (but I am in no way a specialist of this exercise): > > > > * You could try moving the structures to the blocks where they are used, > > in the case a given structure is used for only one ioctl. I'm not too > > sure how gcc handles local variables declared inside blocks with > > regards to stack reservation though. I thought it would work but my > > experiments today seem to suggest it doesn't. > That won't work. Variables at beginning of function take only ~600 bytes, > so the rest must be from inner blocks and inlines (probably). > > > * You can move the handling of some ioctls to dedicated functions, just > > like I did in i2c-dev: > > http://lists.lm-sensors.org/pipermail/i2c/2008-February/003010.html > > However there is a risk that gcc will inline these functions (that's > > what happened to me...) Not sure how to prevent gcc from inlining. > There's "noinline" attribute in linux/compiler.h (compiler-gcc.h actually) > for these situations. > > > * You can allocate the structures dynamically, as you originally wanted > > to do for ir-kbd-i2c. However this has a performance penalty and will > > fragment the memory, so it's not ideal. > > > > * If each ioctl uses only one of the structures, you may define a union > > of all the structures. The size of the union will be the size of the > > biggest structure, so you save a lot of space on the stack. > Nice idea. > > I'll try 2nd and 4th approaches. The union will probably solve. This function is very complex, since it needs to deal with almost all v4l1 v4l2 ioctls (about 80-90). Splitting into small functions might help, but probably, gcc will create the functions as inline. > > Marcin Slusarz Cheers, Mauro ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] video: limit stack usage of ir-kbd-i2c.c 2008-02-27 10:23 ` Marcin Slusarz 2008-02-27 10:33 ` Mauro Carvalho Chehab @ 2008-02-28 18:29 ` Jean Delvare 1 sibling, 0 replies; 7+ messages in thread From: Jean Delvare @ 2008-02-28 18:29 UTC (permalink / raw) To: Marcin Slusarz; +Cc: LKML, Mauro Carvalho Chehab, i2c, video4linux-list On Wed, 27 Feb 2008 11:23:26 +0100, Marcin Slusarz wrote: > On Tue, Feb 26, 2008 at 11:23:20PM +0100, Jean Delvare wrote: > > * You can move the handling of some ioctls to dedicated functions, just > > like I did in i2c-dev: > > http://lists.lm-sensors.org/pipermail/i2c/2008-February/003010.html > > However there is a risk that gcc will inline these functions (that's > > what happened to me...) Not sure how to prevent gcc from inlining. > > There's "noinline" attribute in linux/compiler.h (compiler-gcc.h actually) > for these situations. I didn't know about noinline, thanks for the tip. It works as expected, however in the case of i2cdev_ioctl I'm not sure if it's worth it. Without it, I have: 0x02ae i2cdev_ioctl [i2c-dev]: 192 With noinline, I have: 0x02ac i2cdev_ioctl_smbus [i2c-dev]: 112 0x05bc i2cdev_ioctl_rdrw [i2c-dev]: 112 0x087e i2cdev_ioctl [i2c-dev]: 32 32 + 112 = 144, 192 - 144 = only 48 bytes saved on the stack, at the price of some performance loss. OTOH this makes the binary slightly smaller (not sure why), which is always nice: add/remove: 2/0 grow/shrink: 0/1 up/down: 1121/-1182 (-61) function old new delta i2cdev_ioctl_rdrw - 696 +696 i2cdev_ioctl_smbus - 425 +425 i2cdev_ioctl 1482 300 -1182 -- Jean Delvare ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-02-28 18:29 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-02-25 20:51 [PATCH] video: limit stack usage of ir-kbd-i2c.c Marcin Slusarz 2008-02-26 12:32 ` Jean Delvare 2008-02-26 21:03 ` Marcin Slusarz 2008-02-26 22:23 ` Jean Delvare 2008-02-27 10:23 ` Marcin Slusarz 2008-02-27 10:33 ` Mauro Carvalho Chehab 2008-02-28 18:29 ` Jean Delvare
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).