lkml.org 
[lkml]   [2002]   [Mar]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] ATM locking fix. [Re: [PATCH] spinlock not locked when unlocking in atm_dev_register]
    Hi Folks,

    Some time ago I promised a patch that fixes ATM device allocation code.
    Fix that Alan's got in his 2.4.19-pre2-ac3 is wrong because it just removes
    locking instead of fixing it.
    So here goes my patch. Tested on dual Athlon box.

    Marcelo, Alan, please apply.

    Patch URL:
    http://bluez.sf.net/atm.patch-2.4.19-pre2.gz


    --- linux/net/atm/resources.c.orig Thu Mar 7 13:56:00 2002
    +++ linux/net/atm/resources.c Thu Mar 7 13:56:40 2002
    @@ -32,7 +32,7 @@
    {
    struct atm_dev *dev;

    - dev = kmalloc(sizeof(*dev),GFP_KERNEL);
    + dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
    if (!dev) return NULL;
    memset(dev,0,sizeof(*dev));
    dev->type = type;
    @@ -40,32 +40,24 @@
    dev->link_rate = ATM_OC3_PCR;
    dev->next = NULL;

    - spin_lock(&atm_dev_lock);
    -
    dev->prev = last_dev;

    if (atm_devs) last_dev->next = dev;
    else atm_devs = dev;
    last_dev = dev;
    - spin_unlock(&atm_dev_lock);
    return dev;
    }


    static void free_atm_dev(struct atm_dev *dev)
    {
    - spin_lock (&atm_dev_lock);
    -
    if (dev->prev) dev->prev->next = dev->next;
    else atm_devs = dev->next;
    if (dev->next) dev->next->prev = dev->prev;
    else last_dev = dev->prev;
    kfree(dev);
    -
    - spin_unlock (&atm_dev_lock);
    }

    -
    struct atm_dev *atm_find_dev(int number)
    {
    struct atm_dev *dev;
    @@ -75,17 +67,18 @@
    return NULL;
    }

    -
    struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops
    *ops,
    int number,atm_dev_flags_t *flags)
    {
    - struct atm_dev *dev;
    + struct atm_dev *dev = NULL;
    +
    + spin_lock(&atm_dev_lock);

    dev = alloc_atm_dev(type);
    if (!dev) {
    printk(KERN_ERR "atm_dev_register: no space for dev %s\n",
    type);
    - return NULL;
    + goto done;
    }
    if (number != -1) {
    if (atm_find_dev(number)) {
    @@ -93,8 +86,7 @@
    return NULL;
    }
    dev->number = number;
    - }
    - else {
    + } else {
    dev->number = 0;
    while (atm_find_dev(dev->number)) dev->number++;
    }
    @@ -102,20 +94,23 @@
    dev->dev_data = NULL;
    barrier();
    dev->ops = ops;
    - if (flags) dev->flags = *flags;
    - else memset(&dev->flags,0,sizeof(dev->flags));
    + if (flags)
    + dev->flags = *flags;
    + else
    + memset(&dev->flags,0,sizeof(dev->flags));
    memset((void *) &dev->stats,0,sizeof(dev->stats));
    #ifdef CONFIG_PROC_FS
    if (ops->proc_read)
    if (atm_proc_dev_register(dev) < 0) {
    printk(KERN_ERR "atm_dev_register: "
    "atm_proc_dev_register failed for dev %s\n",type);
    - spin_unlock (&atm_dev_lock);
    free_atm_dev(dev);
    - return NULL;
    + goto done;
    }
    #endif
    - spin_unlock (&atm_dev_lock);
    +
    +done:
    + spin_unlock(&atm_dev_lock);
    return dev;
    }

    @@ -125,10 +120,11 @@
    #ifdef CONFIG_PROC_FS
    if (dev->ops->proc_read) atm_proc_dev_deregister(dev);
    #endif
    + spin_lock(&atm_dev_lock);
    free_atm_dev(dev);
    + spin_unlock(&atm_dev_lock);
    }

    -
    void shutdown_atm_dev(struct atm_dev *dev)
    {
    if (dev->vccs) {
    @@ -146,7 +142,6 @@
    kfree(sk->protinfo.af_atm);
    }

    -
    struct sock *alloc_atm_vcc_sk(int family)
    {
    struct sock *sk;

    -
    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/

    \
     
     \ /
      Last update: 2005-03-22 13:24    [W:0.030 / U:1.084 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site