All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Williams <dcbw@redhat.com>
To: Ivo van Doorn <ivdoorn@gmail.com>
Cc: "John W. Linville" <linville@tuxdriver.com>,
	linux-wireless@vger.kernel.org,
	Arnaud Patard <apatard@mandriva.com>,
	Gertjan van Wingerde <gwingerde@gmail.com>
Subject: Re: [PATCH] Fix SLAB corruption during
Date: Mon, 16 Mar 2009 15:15:30 -0400	[thread overview]
Message-ID: <1237230930.16956.66.camel@localhost.localdomain> (raw)
In-Reply-To: <200903161925.41102.IvDoorn@gmail.com>

On Mon, 2009-03-16 at 19:25 +0100, Ivo van Doorn wrote:
> At rmmod stage, the code path is the following one :
> 
> rt2x00lib_remove_dev
>   ->  rt2x00lib_uninitialize()
>         -> rt2x00rfkill_unregister()
>              -> rfkill_unregister()
>         -> rt2x00rfkill_free()
>              -> rfkill_free()
> 
> The problem is that rfkill_free should not be called after rfkill_free
> otherwise put_device(&rfkill->dev) will be called 2 times. This patch
> fix this by removing the call to rfkill_free

Needs a better patch title :)  During what?  And I assume you mean
"rfkill_free() should not be called after rfkill_unregister(), right?

Dan

> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
> Tested-by: Arnaud Patard <apatard@mandriva.com>
> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
> 
> ---
> John, this patch is for 2.6.29 and only 2.6.29 since rfkill support itself
> was removed from later versions (replaced by input_polldev).
> The patch is quite big to be merged in a late state of the release cycle,
> but since the SLAB corruption is a serious problem, I hope this can get in regardless.
> 
> Thanks.
> 
> diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
> index 39ecf3b..820fdb2 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00.h
> +++ b/drivers/net/wireless/rt2x00/rt2x00.h
> @@ -687,8 +687,7 @@ struct rt2x00_dev {
>  	 */
>  #ifdef CONFIG_RT2X00_LIB_RFKILL
>  	unsigned long rfkill_state;
> -#define RFKILL_STATE_ALLOCATED		1
> -#define RFKILL_STATE_REGISTERED		2
> +#define RFKILL_STATE_REGISTERED		1
>  	struct rfkill *rfkill;
>  	struct delayed_work rfkill_work;
>  #endif /* CONFIG_RT2X00_LIB_RFKILL */
> diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
> index 87c0f2c..e694bb7 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
> @@ -1105,7 +1105,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
>  	 * Register extra components.
>  	 */
>  	rt2x00leds_register(rt2x00dev);
> -	rt2x00rfkill_allocate(rt2x00dev);
>  	rt2x00debug_register(rt2x00dev);
>  
>  	set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
> @@ -1137,7 +1136,6 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
>  	 * Free extra components
>  	 */
>  	rt2x00debug_deregister(rt2x00dev);
> -	rt2x00rfkill_free(rt2x00dev);
>  	rt2x00leds_unregister(rt2x00dev);
>  
>  	/*
> diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
> index 86cd26f..49309d4 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00lib.h
> +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
> @@ -260,8 +260,6 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
>  #ifdef CONFIG_RT2X00_LIB_RFKILL
>  void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev);
>  void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev);
> -void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev);
> -void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev);
>  #else
>  static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
>  {
> @@ -270,14 +268,6 @@ static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
>  static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
>  {
>  }
> -
> -static inline void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
> -{
> -}
> -
> -static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
> -{
> -}
>  #endif /* CONFIG_RT2X00_LIB_RFKILL */
>  
>  /*
> diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
> index 3298cae..08ffc6d 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
> @@ -94,14 +94,50 @@ static void rt2x00rfkill_poll(struct work_struct *work)
>  			   &rt2x00dev->rfkill_work, RFKILL_POLL_INTERVAL);
>  }
>  
> +static int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
> +{
> +	struct device *dev = wiphy_dev(rt2x00dev->hw->wiphy);
> +
> +	rt2x00dev->rfkill = rfkill_allocate(dev, RFKILL_TYPE_WLAN);
> +	if (!rt2x00dev->rfkill)
> +		return -ENOMEM;
> +
> +	rt2x00dev->rfkill->name = rt2x00dev->ops->name;
> +	rt2x00dev->rfkill->data = rt2x00dev;
> +	rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
> +	if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) {
> +		rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state;
> +		rt2x00dev->rfkill->state =
> +			rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
> +			    RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
> +	} else {
> +		rt2x00dev->rfkill->state = RFKILL_STATE_UNBLOCKED;
> +	}
> +
> +	INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll);
> +
> +	return 0;
> +}
> +
> +static void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
> +{
> +	rfkill_free(rt2x00dev->rfkill);
> +	rt2x00dev->rfkill = NULL;
> +}
> +
>  void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
>  {
> -	if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state) ||
> -	    test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
> +	if (test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
> +		return;
> +
> +	if (rt2x00rfkill_allocate(rt2x00dev)) {
> +		ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n");
>  		return;
> +	}
>  
>  	if (rfkill_register(rt2x00dev->rfkill)) {
>  		ERROR(rt2x00dev, "Failed to register rfkill handler.\n");
> +		rt2x00rfkill_free(rt2x00dev);
>  		return;
>  	}
>  
> @@ -117,8 +153,7 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
>  
>  void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
>  {
> -	if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state) ||
> -	    !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
> +	if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
>  		return;
>  
>  	cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
> @@ -127,46 +162,3 @@ void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
>  
>  	__clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
>  }
> -
> -void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
> -{
> -	struct device *dev = wiphy_dev(rt2x00dev->hw->wiphy);
> -
> -	if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
> -		return;
> -
> -	rt2x00dev->rfkill = rfkill_allocate(dev, RFKILL_TYPE_WLAN);
> -	if (!rt2x00dev->rfkill) {
> -		ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n");
> -		return;
> -	}
> -
> -	__set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state);
> -
> -	rt2x00dev->rfkill->name = rt2x00dev->ops->name;
> -	rt2x00dev->rfkill->data = rt2x00dev;
> -	rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
> -	if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) {
> -		rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state;
> -		rt2x00dev->rfkill->state =
> -			rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
> -			    RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
> -	} else {
> -		rt2x00dev->rfkill->state = RFKILL_STATE_UNBLOCKED;
> -	}
> -
> -	INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll);
> -
> -	return;
> -}
> -
> -void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
> -{
> -	if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
> -		return;
> -
> -	cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
> -
> -	rfkill_free(rt2x00dev->rfkill);
> -	rt2x00dev->rfkill = NULL;
> -}
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


  reply	other threads:[~2009-03-16 19:18 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-16 18:25 [PATCH] Fix SLAB corruption during Ivo van Doorn
2009-03-16 19:15 ` Dan Williams [this message]
2009-03-16 19:21   ` Ivo van Doorn
2009-03-16 19:24 ` [PATCH v2] Fix SLAB corruption during rmmod Ivo van Doorn
2009-03-17 21:13   ` John W. Linville
2009-03-17 21:56     ` Ivo van Doorn
2009-03-18 13:02       ` John W. Linville
2009-03-18 13:32         ` Ivo van Doorn
2009-03-18 21:37           ` John W. Linville

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1237230930.16956.66.camel@localhost.localdomain \
    --to=dcbw@redhat.com \
    --cc=apatard@mandriva.com \
    --cc=gwingerde@gmail.com \
    --cc=ivdoorn@gmail.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.