All of lore.kernel.org
 help / color / mirror / Atom feed
* Poking ieee80211_default_rc_algo causes kernel lockups
@ 2009-02-15 16:09 Sitsofe Wheeler
  2009-02-15 17:02 ` Frederic Weisbecker
  2009-02-15 19:35 ` Frederic Weisbecker
  0 siblings, 2 replies; 16+ messages in thread
From: Sitsofe Wheeler @ 2009-02-15 16:09 UTC (permalink / raw)
  To: linux-kernel

Hi,

As mentioned on
http://groups.google.com/group/fa.linux.kernel/browse_frm/thread/d4a6ce26360613fa/b362792a2debced6?#b362792a2debced6
, poking /sys/module/mac80211/parameters/ieee80211_default_rc_algo and
then trying to read values back is currently causing the kernel to go
funny. E.g.
echo blah > /sys/module/mac80211/parameters/ieee80211_default_rc_algo
cat /sys/module/mac80211/parameters/ieee80211_default_rc_algo

Causes 2.6.29rc5 on my EeePC 900 to lock up.

-- 
Sitsofe


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Poking ieee80211_default_rc_algo causes kernel lockups
  2009-02-15 16:09 Poking ieee80211_default_rc_algo causes kernel lockups Sitsofe Wheeler
@ 2009-02-15 17:02 ` Frederic Weisbecker
  2009-02-15 19:24   ` Sitsofe Wheeler
  2009-02-15 19:35 ` Frederic Weisbecker
  1 sibling, 1 reply; 16+ messages in thread
From: Frederic Weisbecker @ 2009-02-15 17:02 UTC (permalink / raw)
  To: Sitsofe Wheeler; +Cc: linux-kernel

On Sun, Feb 15, 2009 at 04:09:57PM +0000, Sitsofe Wheeler wrote:
> Hi,
> 
> As mentioned on
> http://groups.google.com/group/fa.linux.kernel/browse_frm/thread/d4a6ce26360613fa/b362792a2debced6?#b362792a2debced6
> , poking /sys/module/mac80211/parameters/ieee80211_default_rc_algo and
> then trying to read values back is currently causing the kernel to go
> funny. E.g.
> echo blah > /sys/module/mac80211/parameters/ieee80211_default_rc_algo
> cat /sys/module/mac80211/parameters/ieee80211_default_rc_algo
> 
> Causes 2.6.29rc5 on my EeePC 900 to lock up.
> 
> -- 
> Sitsofe


Hi,

I'm currently building a 2.6.29-rc5 with CONFIG_MAC80211 enabled
to test it.

Could you please enable the CONFIG_DETECT_SOFTLOCKUP option in your kernel?
It's on Kernel Hacking > Detect Soft Lockups.
With some chances you will have a relevant stacktrace of the lockup, in case
I couldn't reproduce it.

 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Poking ieee80211_default_rc_algo causes kernel lockups
  2009-02-15 17:02 ` Frederic Weisbecker
@ 2009-02-15 19:24   ` Sitsofe Wheeler
  2009-02-15 19:41     ` Frederic Weisbecker
  0 siblings, 1 reply; 16+ messages in thread
From: Sitsofe Wheeler @ 2009-02-15 19:24 UTC (permalink / raw)
  To: Frederic Weisbecker; +Cc: linux-kernel

> Could you please enable the CONFIG_DETECT_SOFTLOCKUP option in your kernel?

> It's on Kernel Hacking > Detect Soft Lockups.
> With some chances you will have a relevant stacktrace of the lockup, in case
> I couldn't reproduce it.

I'll try (the kernel I'm currently using is jam packed with with debug options) but I'm unconvinced it will unfreeze enough for anything useful...



      

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Poking ieee80211_default_rc_algo causes kernel lockups
  2009-02-15 16:09 Poking ieee80211_default_rc_algo causes kernel lockups Sitsofe Wheeler
  2009-02-15 17:02 ` Frederic Weisbecker
@ 2009-02-15 19:35 ` Frederic Weisbecker
  2009-02-16 10:10   ` Rusty Russell
  1 sibling, 1 reply; 16+ messages in thread
From: Frederic Weisbecker @ 2009-02-15 19:35 UTC (permalink / raw)
  To: Sitsofe Wheeler; +Cc: Ingo Molnar, Andrew Morton, linux-kernel, Rusty Russell

On Sun, Feb 15, 2009 at 04:09:57PM +0000, Sitsofe Wheeler wrote:
> Hi,
> 
> As mentioned on
> http://groups.google.com/group/fa.linux.kernel/browse_frm/thread/d4a6ce26360613fa/b362792a2debced6?#b362792a2debced6
> , poking /sys/module/mac80211/parameters/ieee80211_default_rc_algo and
> then trying to read values back is currently causing the kernel to go
> funny. E.g.
> echo blah > /sys/module/mac80211/parameters/ieee80211_default_rc_algo
> cat /sys/module/mac80211/parameters/ieee80211_default_rc_algo
> 
> Causes 2.6.29rc5 on my EeePC 900 to lock up.
> 
> -- 
> Sitsofe
> 


On Sun, Feb 15, 2009 at 04:09:57PM +0000, Sitsofe Wheeler wrote:
> Hi,
> 
> As mentioned on
> http://groups.google.com/group/fa.linux.kernel/browse_frm/thread/d4a6ce26360613fa/b362792a2debced6?#b362792a2debced6
> , poking /sys/module/mac80211/parameters/ieee80211_default_rc_algo and
> then trying to read values back is currently causing the kernel to go
> funny. E.g.
> echo blah > /sys/module/mac80211/parameters/ieee80211_default_rc_algo
> cat /sys/module/mac80211/parameters/ieee80211_default_rc_algo
> 
> Causes 2.6.29rc5 on my EeePC 900 to lock up.
> 

I think I've found something:

When you set a new value to a module parameter through
sysfs, here is what happens (traced with the function_graph_tracer,
I've zapped a lot of entries to keep it clear)


 1)               |  sys_open() {
 1)               |            sysfs_open_file() {
 1)               |              kmem_cache_alloc() {
 1)   0.609 us    |                __might_sleep();
 1)   2.046 us    |              }
 1) + 58.976 us   |            }
 1) ! 471.823 us  |  }


The file is opened here, and sysfs will allocate a private buffer for this
file...


 1)               |  sys_write() {
 1)               |    vfs_write() {
 1)               |      sysfs_write_file() {
 1) + 26.446 us   |        get_zeroed_page();
 1)   0.789 us    |        sysfs_get_active_two();
 1)               |        module_attr_store() {
 1)               |          param_attr_store() {
 1)   5.625 us    |            param_set_charp();
 1)   7.279 us    |          }
 1)   8.919 us    |        }
 1)   4.113 us    |      }
 1) + 62.502 us   |    }
 1) + 64.961 us   |  }

Then we go to write the file, the buffer we allocated is used to store what
the user gave us as the new value of the module parameter.

This filled buffer is relayed to the module parameter and the address of the buffer
is directly assigned to the pointer of the module parameter:

int param_set_charp(const char *val, struct kernel_param *kp)
{
	[...]
	*(char **)kp->arg = (char *)val;
	return 0;
}

At this stage, all is good.

But just after we close the file:


 1)               |            sysfs_release() {
 1)               |              kfree() {
 1)   1.105 us    |                __phys_addr();
 1)   2.842 us    |              }
 1)               |              free_pages() {
 1)   0.609 us    |                __phys_addr();
 1)               |                __free_pages() {
 1)               |                  free_hot_page() {
 1)               |                    free_hot_cold_page() {
 1)   1.113 us    |                      get_pageblock_flags_group();
 1)   3.061 us    |                    }
 1)   4.466 us    |                  }
 1)   5.744 us    |                }
 1)   8.166 us    |              }
 1)               |              kfree() {
 1)   0.601 us    |                __phys_addr();
 1)   2.052 us    |              }
 1) + 18.686 us   |            }

The buffer we just assigned to the module parameter is freed. So we can't reuse it later,
but that's what is done later when we read it, since this bad address is dereferenced:

int param_get_charp(char *buffer, struct kernel_param *kp)
{
	return sprintf(buffer, "%s", *((char **)kp->arg));
}

So the problem seems not related to mac80211 but actually to module parameter management.
I'm not sure what is the right fix.

I guess we should use the following field in struct kernel_param:
struct kparam_string *str;

But this implies that string module params must not be simply pointers but static arrays.
Although I find it a bit insane to modify a string parameter at runtime.

The string is parsed by a module on load but not after, so a callback given by the module
seems to me more sane...



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Poking ieee80211_default_rc_algo causes kernel lockups
  2009-02-15 19:24   ` Sitsofe Wheeler
@ 2009-02-15 19:41     ` Frederic Weisbecker
  2009-02-15 21:02       ` Sitsofe Wheeler
  0 siblings, 1 reply; 16+ messages in thread
From: Frederic Weisbecker @ 2009-02-15 19:41 UTC (permalink / raw)
  To: Sitsofe Wheeler; +Cc: linux-kernel

On Sun, Feb 15, 2009 at 11:24:41AM -0800, Sitsofe Wheeler wrote:
> > Could you please enable the CONFIG_DETECT_SOFTLOCKUP option in your kernel?
> 
> > It's on Kernel Hacking > Detect Soft Lockups.
> > With some chances you will have a relevant stacktrace of the lockup, in case
> > I couldn't reproduce it.
> 
> I'll try (the kernel I'm currently using is jam packed with with debug options) but I'm unconvinced it will unfreeze enough for anything useful...

No need to actually, I guess we found it...


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Poking ieee80211_default_rc_algo causes kernel lockups
  2009-02-15 19:41     ` Frederic Weisbecker
@ 2009-02-15 21:02       ` Sitsofe Wheeler
  2009-02-16  1:40         ` Frederic Weisbecker
  0 siblings, 1 reply; 16+ messages in thread
From: Sitsofe Wheeler @ 2009-02-15 21:02 UTC (permalink / raw)
  To: Frederic Weisbecker; +Cc: linux-kernel

> From: Frederic Weisbecker <fweisbec@gmail.com>

> 
> On Sun, Feb 15, 2009 at 11:24:41AM -0800, Sitsofe Wheeler wrote:
> > > Could you please enable the CONFIG_DETECT_SOFTLOCKUP option in your kernel?
> > 
> > > It's on Kernel Hacking > Detect Soft Lockups.
> > > With some chances you will have a relevant stacktrace of the lockup, in case
> > > I couldn't reproduce it.
> > 
> > I'll try (the kernel I'm currently using is jam packed with with debug 
> options) but I'm unconvinced it will unfreeze enough for anything useful...
> 
> No need to actually, I guess we found it...

That's good news - the only way I could have reported the soft lockup stack trace would have been by taking a photo of the screen. The stack trace was pretty much what is seen inside <http://groups.google.com/group/fa.linux.kernel/browse_frm/thread/d4a6ce26360613fa/b362792a2debced6?#b362792a2debced6> anyway. The thing that I'm curious about is why did it show up as an oops last time and as a complete lockup this time?

My one thought is that this is actually a parameter that was not intended to be changed and shouldn't have accepted being written to. However one wonders how the syfs framework was supposed to work in other cases. It sounds like there is a very small window for making your own private copy of whatever sysfs passes to you and under the current system who throws away old strings (given that it looks like pointers are being swapped)? Are they refcounted or something?



      

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Poking ieee80211_default_rc_algo causes kernel lockups
  2009-02-15 21:02       ` Sitsofe Wheeler
@ 2009-02-16  1:40         ` Frederic Weisbecker
  2009-02-16  2:37           ` Frederic Weisbecker
  0 siblings, 1 reply; 16+ messages in thread
From: Frederic Weisbecker @ 2009-02-16  1:40 UTC (permalink / raw)
  To: Sitsofe Wheeler; +Cc: linux-kernel, Andrew Morton, rusty

On Sun, Feb 15, 2009 at 01:02:15PM -0800, Sitsofe Wheeler wrote:
> > From: Frederic Weisbecker <fweisbec@gmail.com>
> 
> > 
> > On Sun, Feb 15, 2009 at 11:24:41AM -0800, Sitsofe Wheeler wrote:
> > > > Could you please enable the CONFIG_DETECT_SOFTLOCKUP option in your kernel?
> > > 
> > > > It's on Kernel Hacking > Detect Soft Lockups.
> > > > With some chances you will have a relevant stacktrace of the lockup, in case
> > > > I couldn't reproduce it.
> > > 
> > > I'll try (the kernel I'm currently using is jam packed with with debug 
> > options) but I'm unconvinced it will unfreeze enough for anything useful...
> > 
> > No need to actually, I guess we found it...
> 
> That's good news - the only way I could have reported the soft lockup stack trace would have been by taking a photo of the screen. The stack trace was pretty much what is seen inside <http://groups.google.com/group/fa.linux.kernel/browse_frm/thread/d4a6ce26360613fa/b362792a2debced6?#b362792a2debced6> anyway. The thing that I'm curious about is why did it show up as an oops last time and as a complete lockup this time?


I don't know :-)

> 
> My one thought is that this is actually a parameter that was not intended to be changed and shouldn't have accepted being written to.


I guess there aren't any module string parameter which expect to be changed like that,
just by changing the pointer value.
Usually, when you have a string parameter, you parse it at load time, and keep the value as an integer.
So it makes only sense to change such values at runtime through a callback given by the module. And that's
what mac80211 does through debugfs.

> However one wonders how the syfs framework was supposed to work in other cases. 


Actually, what I can see is that in case of module_param() with char * types, the permission
of the file is often 0444 or 0, so it is safe.

There are exceptions however:

$ git-grep -E "charp, 04?[123567]+"
arch/um/drivers/hostaudio_kern.c:module_param(dsp, charp, 0644);
arch/um/drivers/hostaudio_kern.c:module_param(mixer, charp, 0644);
drivers/misc/lkdtm.c:module_param(cpoint_name, charp, 0644);
drivers/misc/lkdtm.c:module_param(cpoint_type, charp, 0644);
drivers/net/wireless/libertas/if_sdio.c:module_param_named(helper_name, lbs_helper_name, charp, 0644);
drivers/net/wireless/libertas/if_sdio.c:module_param_named(fw_name, lbs_fw_name, charp, 0644);
drivers/net/wireless/libertas/if_usb.c:module_param_named(fw_name, lbs_fw_name, charp, 0644);
drivers/net/wireless/libertas_tf/if_usb.c:module_param_named(fw_name, lbtf_fw_name, charp, 0644);
drivers/video/vt8623fb.c:module_param(mode_option, charp, 0644);
net/mac80211/rate.c:module_param(ieee80211_default_rc_algo, charp, 0644);

I'm preparing a patchset to set them only readable, it doesn't fix this module bug,
but anyway, such string params writable at runtime don't make any sense.

>It sounds like there is a very
>small window for making your own private copy of whatever sysfs passes to you and under the current system who 
>throws away old strings (given that it looks like pointers are being swapped)? Are they refcounted or something?

When you register a module param, its address is stored inside a struct kernel_param.
Once you change the value of the param, it's totally fine for int/long/boolean...
since no memory is allocated for that, only the integer value is changed on the static memory, though
a module must deal with this asynchronous event given the fact it let it writable by the
user, and I guess it's not always a good idea.

So for an integer called a, you will put a module_param(a, int, ...) which will
allocate a struct kernel_param, and store &a inside.

For params such as strings, its very different, since you register a char *p,
its address is stored in, say,  pp (as a char **).
and later the equivalent of the following is done:

open: tmp = kzalloc(PAGE_SIZE, GFP_KERNEL);
write: fill(pp);
      *(char **)pp = tmp;
release: kfree(tmp)
read: read(**pp) => crash

And no there is no refcounting. But that would be perhaps too much for that.
Really I think a callback registered on module_param() would be better, not only
for appropriate allocation but for event handling too.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Poking ieee80211_default_rc_algo causes kernel lockups
  2009-02-16  1:40         ` Frederic Weisbecker
@ 2009-02-16  2:37           ` Frederic Weisbecker
  0 siblings, 0 replies; 16+ messages in thread
From: Frederic Weisbecker @ 2009-02-16  2:37 UTC (permalink / raw)
  To: Sitsofe Wheeler; +Cc: linux-kernel, Andrew Morton, rusty

On Mon, Feb 16, 2009 at 02:40:15AM +0100, Frederic Weisbecker wrote:
> On Sun, Feb 15, 2009 at 01:02:15PM -0800, Sitsofe Wheeler wrote:
> > > From: Frederic Weisbecker <fweisbec@gmail.com>
> > 
> > > 
> > > On Sun, Feb 15, 2009 at 11:24:41AM -0800, Sitsofe Wheeler wrote:
> > > > > Could you please enable the CONFIG_DETECT_SOFTLOCKUP option in your kernel?
> > > > 
> > > > > It's on Kernel Hacking > Detect Soft Lockups.
> > > > > With some chances you will have a relevant stacktrace of the lockup, in case
> > > > > I couldn't reproduce it.
> > > > 
> > > > I'll try (the kernel I'm currently using is jam packed with with debug 
> > > options) but I'm unconvinced it will unfreeze enough for anything useful...
> > > 
> > > No need to actually, I guess we found it...
> > 
> > That's good news - the only way I could have reported the soft lockup stack trace would have been by taking a photo of the screen. The stack trace was pretty much what is seen inside <http://groups.google.com/group/fa.linux.kernel/browse_frm/thread/d4a6ce26360613fa/b362792a2debced6?#b362792a2debced6> anyway. The thing that I'm curious about is why did it show up as an oops last time and as a complete lockup this time?
> 
> 
> I don't know :-)
> 
> > 
> > My one thought is that this is actually a parameter that was not intended to be changed and shouldn't have accepted being written to.
> 
> 
> I guess there aren't any module string parameter which expect to be changed like that,
> just by changing the pointer value.
> Usually, when you have a string parameter, you parse it at load time, and keep the value as an integer.
> So it makes only sense to change such values at runtime through a callback given by the module. And that's
> what mac80211 does through debugfs.
> 
> > However one wonders how the syfs framework was supposed to work in other cases. 
> 
> 
> Actually, what I can see is that in case of module_param() with char * types, the permission
> of the file is often 0444 or 0, so it is safe.
> 
> There are exceptions however:
> 
> $ git-grep -E "charp, 04?[123567]+"
> arch/um/drivers/hostaudio_kern.c:module_param(dsp, charp, 0644);
> arch/um/drivers/hostaudio_kern.c:module_param(mixer, charp, 0644);
> drivers/misc/lkdtm.c:module_param(cpoint_name, charp, 0644);
> drivers/misc/lkdtm.c:module_param(cpoint_type, charp, 0644);
> drivers/net/wireless/libertas/if_sdio.c:module_param_named(helper_name, lbs_helper_name, charp, 0644);
> drivers/net/wireless/libertas/if_sdio.c:module_param_named(fw_name, lbs_fw_name, charp, 0644);
> drivers/net/wireless/libertas/if_usb.c:module_param_named(fw_name, lbs_fw_name, charp, 0644);
> drivers/net/wireless/libertas_tf/if_usb.c:module_param_named(fw_name, lbtf_fw_name, charp, 0644);
> drivers/video/vt8623fb.c:module_param(mode_option, charp, 0644);
> net/mac80211/rate.c:module_param(ieee80211_default_rc_algo, charp, 0644);
> 
> I'm preparing a patchset to set them only readable, it doesn't fix this module bug,
> but anyway, such string params writable at runtime don't make any sense.


Well, actually all of these callsites seem to handle the case when their param value change.
So only the module param core should be fixed...

 
> >It sounds like there is a very
> >small window for making your own private copy of whatever sysfs passes to you and under the current system who 
> >throws away old strings (given that it looks like pointers are being swapped)? Are they refcounted or something?
> 
> When you register a module param, its address is stored inside a struct kernel_param.
> Once you change the value of the param, it's totally fine for int/long/boolean...
> since no memory is allocated for that, only the integer value is changed on the static memory, though
> a module must deal with this asynchronous event given the fact it let it writable by the
> user, and I guess it's not always a good idea.
> 
> So for an integer called a, you will put a module_param(a, int, ...) which will
> allocate a struct kernel_param, and store &a inside.
> 
> For params such as strings, its very different, since you register a char *p,
> its address is stored in, say,  pp (as a char **).
> and later the equivalent of the following is done:
> 
> open: tmp = kzalloc(PAGE_SIZE, GFP_KERNEL);
> write: fill(pp);
>       *(char **)pp = tmp;
> release: kfree(tmp)
> read: read(**pp) => crash
> 
> And no there is no refcounting. But that would be perhaps too much for that.
> Really I think a callback registered on module_param() would be better, not only
> for appropriate allocation but for event handling too.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Poking ieee80211_default_rc_algo causes kernel lockups
  2009-02-15 19:35 ` Frederic Weisbecker
@ 2009-02-16 10:10   ` Rusty Russell
  2009-02-16 17:59     ` Frederic Weisbecker
  0 siblings, 1 reply; 16+ messages in thread
From: Rusty Russell @ 2009-02-16 10:10 UTC (permalink / raw)
  To: Frederic Weisbecker
  Cc: Sitsofe Wheeler, Ingo Molnar, Andrew Morton, linux-kernel

On Monday 16 February 2009 06:05:23 Frederic Weisbecker wrote:
> So the problem seems not related to mac80211 but actually to module parameter management.
> I'm not sure what is the right fix.

Good spotting.  And in fact this bug has been here for quite a while...

The "simple" fix is to kstrdup, but that leaks.

How's this?

param: fix charp parameters set via sysfs (eg. ieee80211_default_rc_algo)

The module_param type "charp" simply sets a char * pointer in the
module to the parameter in the commandline string: this is why we keep
the (mangled) module command line around.  But when set via sysfs (as
about 11 charp parameters can be) this memory is freed on the way
out of the write().

So we kstrdup instead: this is fine, but it means we have to note when
we've used it so we can reliably kfree the parameter when it's next
overwritten, and also on module unload.

Reported-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>

diff --git a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -247,6 +247,10 @@ struct module
 	const struct kernel_symbol *syms;
 	const unsigned long *crcs;
 	unsigned int num_syms;
+
+	/* Kernel parameters. */
+	struct kernel_param *kp;
+	unsigned int num_kp;
 
 	/* GPL-only exported symbols. */
 	unsigned int num_gpl_syms;
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -138,6 +138,9 @@ extern int parse_args(const char *name,
 		      unsigned num,
 		      int (*unknown)(char *param, char *val));
 
+/* Called by module remove. */
+extern void destroy_params(const struct kernel_param *params, unsigned num);
+
 /* All the helper functions */
 /* The macros to do compile-time type checking stolen from Jakub
    Jelinek, who IIRC came up with this idea for the 2.4 module init code. */
diff --git a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1457,6 +1457,9 @@ static void free_module(struct module *m
 	/* Module unload stuff */
 	module_unload_free(mod);
 
+	/* Free any allocated parameters. */
+	destroy_params(mod->kp, mod->num_kp);
+
 	/* release any pointers to mcount in this module */
 	ftrace_release(mod->module_core, mod->core_size);
 
@@ -1870,8 +1873,7 @@ static noinline struct module *load_modu
 	unsigned int symindex = 0;
 	unsigned int strindex = 0;
 	unsigned int modindex, versindex, infoindex, pcpuindex;
-	unsigned int num_kp, num_mcount;
-	struct kernel_param *kp;
+	unsigned int num_mcount;
 	struct module *mod;
 	long err = 0;
 	void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -2116,8 +2118,8 @@ static noinline struct module *load_modu
 
 	/* Now we've got everything in the final locations, we can
 	 * find optional sections. */
-	kp = section_objs(hdr, sechdrs, secstrings, "__param", sizeof(*kp),
-			  &num_kp);
+	mod->kp = section_objs(hdr, sechdrs, secstrings, "__param",
+			       sizeof(*mod->kp), &mod->num_kp);
 	mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
 				 sizeof(*mod->syms), &mod->num_syms);
 	mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
@@ -2262,11 +2264,11 @@ static noinline struct module *load_modu
 	 */
 	list_add_rcu(&mod->list, &modules);
 
-	err = parse_args(mod->name, mod->args, kp, num_kp, NULL);
+	err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL);
 	if (err < 0)
 		goto unlink;
 
-	err = mod_sysfs_setup(mod, kp, num_kp);
+	err = mod_sysfs_setup(mod, mod->kp, mod->num_kp);
 	if (err < 0)
 		goto unlink;
 	add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
diff --git a/kernel/params.c b/kernel/params.c
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -23,6 +23,9 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+
+/* We abuse the high bits of "perm" to record whether we kmalloc'ed. */
+#define KPARAM_KMALLOCED	0x80000000
 
 #if 0
 #define DEBUGP printk
@@ -217,7 +220,13 @@ int param_set_charp(const char *val, str
 		return -ENOSPC;
 	}
 
-	*(char **)kp->arg = (char *)val;
+	if (kp->perm & KPARAM_KMALLOCED)
+		kfree(*(char **)kp->arg);
+
+	kp->perm |= KPARAM_KMALLOCED;
+	*(char **)kp->arg = kstrdup(val, GFP_KERNEL);
+	if (!kp->arg)
+		return -ENOMEM;
 	return 0;
 }
 
@@ -571,6 +580,15 @@ void module_param_sysfs_remove(struct mo
 }
 #endif
 
+void destroy_params(const struct kernel_param *params, unsigned num)
+{
+	unsigned int i;
+
+	for (i = 0; i < num; i++)
+		if (params[i].perm & KPARAM_KMALLOCED)
+			kfree(*(char **)params[i].arg);
+}
+
 static void __init kernel_add_sysfs_param(const char *name,
 					  struct kernel_param *kparam,
 					  unsigned int name_skip)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Poking ieee80211_default_rc_algo causes kernel lockups
  2009-02-16 10:10   ` Rusty Russell
@ 2009-02-16 17:59     ` Frederic Weisbecker
  2009-02-16 23:37       ` Rusty Russell
  0 siblings, 1 reply; 16+ messages in thread
From: Frederic Weisbecker @ 2009-02-16 17:59 UTC (permalink / raw)
  To: Rusty Russell; +Cc: Sitsofe Wheeler, Ingo Molnar, Andrew Morton, linux-kernel

On Mon, Feb 16, 2009 at 08:40:43PM +1030, Rusty Russell wrote:
> On Monday 16 February 2009 06:05:23 Frederic Weisbecker wrote:
> > So the problem seems not related to mac80211 but actually to module parameter management.
> > I'm not sure what is the right fix.
> 
> Good spotting.  And in fact this bug has been here for quite a while...
> 
> The "simple" fix is to kstrdup, but that leaks.
> 
> How's this?


Simple solution, and fixes the problem :-)
I've tested the string parameter change and the mac80211 module unloading as well.
No obvious problem.

Tested-by: Frederic Weisbecker <fweisbec@gmail.com>

And also, Reported-by: Sitsofe Wheeler <sitsofe@yahoo.com>

Just one last little thing, it would be good to strip the ending newline
while using echo without -n
ie:

root@nowhere:/sys/module/mac80211/parameters# echo heh_look_at_my_newline > ieee80211_default_rc_algo 
root@nowhere:/sys/module/mac80211/parameters# cat ieee80211_default_rc_algo 
heh_look_at_my_newline

root@nowhere:/sys/module/mac80211/parameters# echo -n heh_look_at_hum_nothing > ieee80211_default_rc_algo 
root@nowhere:/sys/module/mac80211/parameters# cat ieee80211_default_rc_algo 
heh_look_at_hum_nothing
root@nowhere:/sys/module/mac80211/parameters#

Because I guess modules don't expect this newline on their strcmp.

Thanks :-)

 
> param: fix charp parameters set via sysfs (eg. ieee80211_default_rc_algo)
> 
> The module_param type "charp" simply sets a char * pointer in the
> module to the parameter in the commandline string: this is why we keep
> the (mangled) module command line around.  But when set via sysfs (as
> about 11 charp parameters can be) this memory is freed on the way
> out of the write().
> 
> So we kstrdup instead: this is fine, but it means we have to note when
> we've used it so we can reliably kfree the parameter when it's next
> overwritten, and also on module unload.
> 
> Reported-by: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> 
> diff --git a/include/linux/module.h b/include/linux/module.h
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -247,6 +247,10 @@ struct module
>  	const struct kernel_symbol *syms;
>  	const unsigned long *crcs;
>  	unsigned int num_syms;
> +
> +	/* Kernel parameters. */
> +	struct kernel_param *kp;
> +	unsigned int num_kp;
>  
>  	/* GPL-only exported symbols. */
>  	unsigned int num_gpl_syms;
> diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
> --- a/include/linux/moduleparam.h
> +++ b/include/linux/moduleparam.h
> @@ -138,6 +138,9 @@ extern int parse_args(const char *name,
>  		      unsigned num,
>  		      int (*unknown)(char *param, char *val));
>  
> +/* Called by module remove. */
> +extern void destroy_params(const struct kernel_param *params, unsigned num);
> +
>  /* All the helper functions */
>  /* The macros to do compile-time type checking stolen from Jakub
>     Jelinek, who IIRC came up with this idea for the 2.4 module init code. */
> diff --git a/kernel/module.c b/kernel/module.c
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -1457,6 +1457,9 @@ static void free_module(struct module *m
>  	/* Module unload stuff */
>  	module_unload_free(mod);
>  
> +	/* Free any allocated parameters. */
> +	destroy_params(mod->kp, mod->num_kp);
> +
>  	/* release any pointers to mcount in this module */
>  	ftrace_release(mod->module_core, mod->core_size);
>  
> @@ -1870,8 +1873,7 @@ static noinline struct module *load_modu
>  	unsigned int symindex = 0;
>  	unsigned int strindex = 0;
>  	unsigned int modindex, versindex, infoindex, pcpuindex;
> -	unsigned int num_kp, num_mcount;
> -	struct kernel_param *kp;
> +	unsigned int num_mcount;
>  	struct module *mod;
>  	long err = 0;
>  	void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
> @@ -2116,8 +2118,8 @@ static noinline struct module *load_modu
>  
>  	/* Now we've got everything in the final locations, we can
>  	 * find optional sections. */
> -	kp = section_objs(hdr, sechdrs, secstrings, "__param", sizeof(*kp),
> -			  &num_kp);
> +	mod->kp = section_objs(hdr, sechdrs, secstrings, "__param",
> +			       sizeof(*mod->kp), &mod->num_kp);
>  	mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
>  				 sizeof(*mod->syms), &mod->num_syms);
>  	mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
> @@ -2262,11 +2264,11 @@ static noinline struct module *load_modu
>  	 */
>  	list_add_rcu(&mod->list, &modules);
>  
> -	err = parse_args(mod->name, mod->args, kp, num_kp, NULL);
> +	err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL);
>  	if (err < 0)
>  		goto unlink;
>  
> -	err = mod_sysfs_setup(mod, kp, num_kp);
> +	err = mod_sysfs_setup(mod, mod->kp, mod->num_kp);
>  	if (err < 0)
>  		goto unlink;
>  	add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
> diff --git a/kernel/params.c b/kernel/params.c
> --- a/kernel/params.c
> +++ b/kernel/params.c
> @@ -23,6 +23,9 @@
>  #include <linux/device.h>
>  #include <linux/err.h>
>  #include <linux/slab.h>
> +
> +/* We abuse the high bits of "perm" to record whether we kmalloc'ed. */
> +#define KPARAM_KMALLOCED	0x80000000
>  
>  #if 0
>  #define DEBUGP printk
> @@ -217,7 +220,13 @@ int param_set_charp(const char *val, str
>  		return -ENOSPC;
>  	}
>  
> -	*(char **)kp->arg = (char *)val;
> +	if (kp->perm & KPARAM_KMALLOCED)
> +		kfree(*(char **)kp->arg);
> +
> +	kp->perm |= KPARAM_KMALLOCED;
> +	*(char **)kp->arg = kstrdup(val, GFP_KERNEL);
> +	if (!kp->arg)
> +		return -ENOMEM;
>  	return 0;
>  }
>  
> @@ -571,6 +580,15 @@ void module_param_sysfs_remove(struct mo
>  }
>  #endif
>  
> +void destroy_params(const struct kernel_param *params, unsigned num)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < num; i++)
> +		if (params[i].perm & KPARAM_KMALLOCED)
> +			kfree(*(char **)params[i].arg);
> +}
> +
>  static void __init kernel_add_sysfs_param(const char *name,
>  					  struct kernel_param *kparam,
>  					  unsigned int name_skip)


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Poking ieee80211_default_rc_algo causes kernel lockups
  2009-02-16 17:59     ` Frederic Weisbecker
@ 2009-02-16 23:37       ` Rusty Russell
  2009-02-20 10:27         ` What made this bug report better? (was Re: Poking ieee80211_default_rc_algo causes kernel lockups) Sitsofe Wheeler
  0 siblings, 1 reply; 16+ messages in thread
From: Rusty Russell @ 2009-02-16 23:37 UTC (permalink / raw)
  To: Frederic Weisbecker
  Cc: Sitsofe Wheeler, Ingo Molnar, Andrew Morton, linux-kernel

On Tuesday 17 February 2009 04:29:08 Frederic Weisbecker wrote:
> Tested-by: Frederic Weisbecker <fweisbec@gmail.com>
> 
> And also, Reported-by: Sitsofe Wheeler <sitsofe@yahoo.com>

Thanks, done, and I'll send to Linus and -stable immediately.

> Just one last little thing, it would be good to strip the ending newline
> while using echo without -n

Agreed, but fixing that is much less urgent.  (It also effects "string"
module parameters).

Thanks!
Rusty.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* What made this bug report better? (was Re: Poking ieee80211_default_rc_algo causes kernel lockups)
  2009-02-16 23:37       ` Rusty Russell
@ 2009-02-20 10:27         ` Sitsofe Wheeler
  2009-02-20 11:31           ` Ingo Molnar
  2009-02-24  3:13           ` Rusty Russell
  0 siblings, 2 replies; 16+ messages in thread
From: Sitsofe Wheeler @ 2009-02-20 10:27 UTC (permalink / raw)
  To: Rusty Russell
  Cc: Frederic Weisbecker, Ingo Molnar, Andrew Morton, linux-kernel

On Tue, Feb 17, 2009 at 10:07:27AM +1030, Rusty Russell wrote:
> 
> Thanks, done, and I'll send to Linus and -stable immediately.

I'm curious - only two days after I reposted this the problem [1] it
appears to have been resolved. When I posted it the first time [2] I
only received one reply (privately) and that was from Greg wondering why
I had only sent the email to him (which was an unfortunate problem and
down to how I was trying to send LKML mails at the time).

What happened this time that made things succesful? Was the original
mail too big? Did it not make it to the list?

[1] http://groups.google.com/group/fa.linux.kernel/browse_frm/thread/2a816ca521d72494/bd607c7e143def6f?#bd607c7e143def6f
[2] http://groups.google.com/group/fa.linux.kernel/browse_frm/thread/d4a6ce26360613fa/b362792a2debced6?#b362792a2debced6

-- 
Sitsofe | http://sucs.org/~sits/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: What made this bug report better? (was Re: Poking ieee80211_default_rc_algo causes kernel lockups)
  2009-02-20 10:27         ` What made this bug report better? (was Re: Poking ieee80211_default_rc_algo causes kernel lockups) Sitsofe Wheeler
@ 2009-02-20 11:31           ` Ingo Molnar
  2009-02-24  3:13           ` Rusty Russell
  1 sibling, 0 replies; 16+ messages in thread
From: Ingo Molnar @ 2009-02-20 11:31 UTC (permalink / raw)
  To: Sitsofe Wheeler
  Cc: Rusty Russell, Frederic Weisbecker, Andrew Morton, linux-kernel


* Sitsofe Wheeler <sitsofe@yahoo.com> wrote:

> On Tue, Feb 17, 2009 at 10:07:27AM +1030, Rusty Russell wrote:
> > 
> > Thanks, done, and I'll send to Linus and -stable immediately.
> 
> I'm curious - only two days after I reposted this the problem 
> [1] it appears to have been resolved. When I posted it the 
> first time [2] I only received one reply (privately) and that 
> was from Greg wondering why I had only sent the email to him 
> (which was an unfortunate problem and down to how I was trying 
> to send LKML mails at the time).
> 
> What happened this time that made things succesful? Was the 
> original mail too big? Did it not make it to the list?
> 
> [1] http://groups.google.com/group/fa.linux.kernel/browse_frm/thread/2a816ca521d72494/bd607c7e143def6f?#bd607c7e143def6f
> [2] http://groups.google.com/group/fa.linux.kernel/browse_frm/thread/d4a6ce26360613fa/b362792a2debced6?#b362792a2debced6

It does not seem to have made it to everyone - it's not in my 
lkml folder for example. Sometimes vger eats emails. Filing a 
bugzilla for reproducible bugs makes sense - especially if you 
see that no action has been taken by anyone.

But note that even with expanded Cc:s and a properly working 
list it needed Frederic's excellent function-graph trace and 
analysis.

A crash in the wireless code rarely gets tracked back to a core 
kernel module support bug, and it would have taken quite some 
time for someone to make that connection.

	Ingo

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: What made this bug report better? (was Re: Poking ieee80211_default_rc_algo causes kernel lockups)
  2009-02-20 10:27         ` What made this bug report better? (was Re: Poking ieee80211_default_rc_algo causes kernel lockups) Sitsofe Wheeler
  2009-02-20 11:31           ` Ingo Molnar
@ 2009-02-24  3:13           ` Rusty Russell
  2009-02-24  8:16             ` What made this bug report better? Sitsofe Wheeler
  1 sibling, 1 reply; 16+ messages in thread
From: Rusty Russell @ 2009-02-24  3:13 UTC (permalink / raw)
  To: Sitsofe Wheeler
  Cc: Frederic Weisbecker, Ingo Molnar, Andrew Morton, linux-kernel

On Friday 20 February 2009 20:57:05 Sitsofe Wheeler wrote:
> What happened this time that made things succesful? Was the original
> mail too big? Did it not make it to the list?

Frederic was the difference; he pulled me in by CC'ing me, once he figured
out it was my bug.

Cheers,
Rusty.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: What made this bug report better?
  2009-02-24  3:13           ` Rusty Russell
@ 2009-02-24  8:16             ` Sitsofe Wheeler
  2009-02-24 17:58               ` Frederic Weisbecker
  0 siblings, 1 reply; 16+ messages in thread
From: Sitsofe Wheeler @ 2009-02-24  8:16 UTC (permalink / raw)
  To: Rusty Russell
  Cc: Frederic Weisbecker, Ingo Molnar, Andrew Morton, linux-kernel

On Tue, Feb 24, 2009 at 01:43:22PM +1030, Rusty Russell wrote:
> On Friday 20 February 2009 20:57:05 Sitsofe Wheeler wrote:
> > What happened this time that made things succesful? Was the original
> > mail too big? Did it not make it to the list?
> 
> Frederic was the difference; he pulled me in by CC'ing me, once he figured
> out it was my bug.

Rusty, Ingo: Thanks for letting me know!

Frederic: What information are you looking for in bug reports? What sort
of areas interest you?

-- 
Sitsofe | http://sucs.org/~sits/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: What made this bug report better?
  2009-02-24  8:16             ` What made this bug report better? Sitsofe Wheeler
@ 2009-02-24 17:58               ` Frederic Weisbecker
  0 siblings, 0 replies; 16+ messages in thread
From: Frederic Weisbecker @ 2009-02-24 17:58 UTC (permalink / raw)
  To: Sitsofe Wheeler; +Cc: Rusty Russell, Ingo Molnar, Andrew Morton, linux-kernel

On Tue, Feb 24, 2009 at 08:16:12AM +0000, Sitsofe Wheeler wrote:
> On Tue, Feb 24, 2009 at 01:43:22PM +1030, Rusty Russell wrote:
> > On Friday 20 February 2009 20:57:05 Sitsofe Wheeler wrote:
> > > What happened this time that made things succesful? Was the original
> > > mail too big? Did it not make it to the list?
> > 
> > Frederic was the difference; he pulled me in by CC'ing me, once he figured
> > out it was my bug.
> 
> Rusty, Ingo: Thanks for letting me know!
> 
> Frederic: What information are you looking for in bug reports? 


Like everyone, the most possible matching traces, locking states, and other
states (irq, atomic, ...), well it depends on the particular case.

The best thing is to provide a way to reproduce it, that's what you did, so
that we can use specific tracers for specific issues.


> What sort of areas interest you?

You mean, what I'm interested in the kernel?
All the kernel :-)
Though I have a preference for the kernel core, and improving tracing
because I'm lazy and I like when there are tools which do most of the things
for me.
 
> -- 
> Sitsofe | http://sucs.org/~sits/


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2009-02-24 17:59 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-15 16:09 Poking ieee80211_default_rc_algo causes kernel lockups Sitsofe Wheeler
2009-02-15 17:02 ` Frederic Weisbecker
2009-02-15 19:24   ` Sitsofe Wheeler
2009-02-15 19:41     ` Frederic Weisbecker
2009-02-15 21:02       ` Sitsofe Wheeler
2009-02-16  1:40         ` Frederic Weisbecker
2009-02-16  2:37           ` Frederic Weisbecker
2009-02-15 19:35 ` Frederic Weisbecker
2009-02-16 10:10   ` Rusty Russell
2009-02-16 17:59     ` Frederic Weisbecker
2009-02-16 23:37       ` Rusty Russell
2009-02-20 10:27         ` What made this bug report better? (was Re: Poking ieee80211_default_rc_algo causes kernel lockups) Sitsofe Wheeler
2009-02-20 11:31           ` Ingo Molnar
2009-02-24  3:13           ` Rusty Russell
2009-02-24  8:16             ` What made this bug report better? Sitsofe Wheeler
2009-02-24 17:58               ` Frederic Weisbecker

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.