lkml.org 
[lkml]   [2009]   [Feb]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 09/33] orinoco: move kmalloc(..., GFP_KERNEL) outside spinlock in orinoco_ioctl_set_genie

    2.6.28-stable review patch. If anyone has any objections, please let us know.

    ------------------

    From: Andrey Borzenkov <arvidjaar@mail.ru>

    commit 7fe99c4e28ab54eada8aa456b417114e6ef21587 upstream

    orinoco: move kmalloc(..., GFP_KERNEL) outside spinlock in orinoco_ioctl_set_genie

    [ 56.923623] BUG: sleeping function called from invalid context at /home/bor/src/linux-git/mm/slub.c:1599
    [ 56.923644] in_atomic(): 0, irqs_disabled(): 1, pid: 3031, name: wpa_supplicant
    [ 56.923656] 2 locks held by wpa_supplicant/3031:
    [ 56.923662] #0: (rtnl_mutex){--..}, at: [<c02abd1f>] rtnl_lock+0xf/0x20
    [ 56.923703] #1: (&priv->lock){++..}, at: [<dfc840c2>] orinoco_ioctl_set_genie+0x52/0x130 [orinoco]
    [ 56.923782] irq event stamp: 910
    [ 56.923788] hardirqs last enabled at (909): [<c01957db>] __kmalloc+0x7b/0x140
    [ 56.923820] hardirqs last disabled at (910): [<c0309419>] _spin_lock_irqsave+0x19/0x80
    [ 56.923847] softirqs last enabled at (880): [<c0124f54>] __do_softirq+0xc4/0x110
    [ 56.923865] softirqs last disabled at (871): [<c01049ae>] do_softirq+0x8e/0xe0
    [ 56.923895] Pid: 3031, comm: wpa_supplicant Not tainted 2.6.29-rc2-1avb #1
    [ 56.923905] Call Trace:
    [ 56.923919] [<c01049ae>] ? do_softirq+0x8e/0xe0
    [ 56.923941] [<c011ad12>] __might_sleep+0xd2/0x100
    [ 56.923952] [<c0195837>] __kmalloc+0xd7/0x140
    [ 56.923963] [<c030946a>] ? _spin_lock_irqsave+0x6a/0x80
    [ 56.923981] [<dfc840e9>] ? orinoco_ioctl_set_genie+0x79/0x130 [orinoco]
    [ 56.923999] [<dfc840c2>] ? orinoco_ioctl_set_genie+0x52/0x130 [orinoco]
    [ 56.924017] [<dfc840e9>] orinoco_ioctl_set_genie+0x79/0x130 [orinoco]
    [ 56.924036] [<c0209325>] ? copy_from_user+0x35/0x130
    [ 56.924061] [<c02ffd96>] ioctl_standard_call+0x196/0x380
    [ 56.924085] [<c029f945>] ? __dev_get_by_name+0x85/0xb0
    [ 56.924096] [<c02ff88f>] wext_handle_ioctl+0x14f/0x230
    [ 56.924113] [<dfc84070>] ? orinoco_ioctl_set_genie+0x0/0x130 [orinoco]
    [ 56.924132] [<c02a3da5>] dev_ioctl+0x495/0x570
    [ 56.924155] [<c0293e05>] ? sys_sendto+0xa5/0xd0
    [ 56.924171] [<c0142fe8>] ? mark_held_locks+0x48/0x90
    [ 56.924183] [<c0292880>] ? sock_ioctl+0x0/0x280
    [ 56.924193] [<c029297d>] sock_ioctl+0xfd/0x280
    [ 56.924203] [<c0292880>] ? sock_ioctl+0x0/0x280
    [ 56.924235] [<c01a51d0>] vfs_ioctl+0x20/0x80
    [ 56.924246] [<c01a53e2>] do_vfs_ioctl+0x72/0x570
    [ 56.924257] [<c0293e62>] ? sys_send+0x32/0x40
    [ 56.924268] [<c02947c0>] ? sys_socketcall+0x1d0/0x2a0
    [ 56.924280] [<c010339f>] ? sysenter_exit+0xf/0x16
    [ 56.924292] [<c01a5919>] sys_ioctl+0x39/0x70
    [ 56.924302] [<c0103371>] sysenter_do_call+0x12/0x31

    Signed-off-by: Andrey Borzenkov <arvidjaar@mail.ru>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/net/wireless/orinoco.c | 30 +++++++++++++-----------------
    1 file changed, 13 insertions(+), 17 deletions(-)

    --- a/drivers/net/wireless/orinoco.c
    +++ b/drivers/net/wireless/orinoco.c
    @@ -4938,32 +4938,29 @@ static int orinoco_ioctl_set_genie(struc
    struct orinoco_private *priv = netdev_priv(dev);
    u8 *buf;
    unsigned long flags;
    - int err = 0;

    if ((wrqu->data.length > MAX_WPA_IE_LEN) ||
    (wrqu->data.length && (extra == NULL)))
    return -EINVAL;

    - if (orinoco_lock(priv, &flags) != 0)
    - return -EBUSY;
    -
    if (wrqu->data.length) {
    buf = kmalloc(wrqu->data.length, GFP_KERNEL);
    - if (buf == NULL) {
    - err = -ENOMEM;
    - goto out;
    - }
    + if (buf == NULL)
    + return -ENOMEM;

    memcpy(buf, extra, wrqu->data.length);
    - kfree(priv->wpa_ie);
    - priv->wpa_ie = buf;
    - priv->wpa_ie_len = wrqu->data.length;
    - } else {
    - kfree(priv->wpa_ie);
    - priv->wpa_ie = NULL;
    - priv->wpa_ie_len = 0;
    + } else
    + buf = NULL;
    +
    + if (orinoco_lock(priv, &flags) != 0) {
    + kfree(buf);
    + return -EBUSY;
    }

    + kfree(priv->wpa_ie);
    + priv->wpa_ie = buf;
    + priv->wpa_ie_len = wrqu->data.length;
    +
    if (priv->wpa_ie) {
    /* Looks like wl_lkm wants to check the auth alg, and
    * somehow pass it to the firmware.
    @@ -4972,9 +4969,8 @@ static int orinoco_ioctl_set_genie(struc
    */
    }

    -out:
    orinoco_unlock(priv, &flags);
    - return err;
    + return 0;
    }

    static int orinoco_ioctl_get_genie(struct net_device *dev,


    \
     
     \ /
      Last update: 2009-02-04 19:43    [W:0.023 / U:0.872 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site