ieee802154: rework wpan_phy index assignment
authorAlexander Aring <alex.aring@gmail.com>
Wed, 5 Nov 2014 19:51:12 +0000 (20:51 +0100)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 5 Nov 2014 20:53:03 +0000 (21:53 +0100)
This patch reworks the wpan_phy index incrementation. It's now similar
like wireless wiphy index incrementation. We move the wpan_phy index
attribute inside of cfg802154_registered_device and use atomic
operations instead locking mechanism via wpan_phy_mutex.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/cfg802154.h
net/ieee802154/core.c
net/ieee802154/core.h

index 864bce2b0728e3924c0497388ad95ff1ba7d1a00..29c6de5a426c9dc87eb3e98295edacd29ef9174a 100644 (file)
@@ -61,7 +61,6 @@ struct wpan_phy {
        s32 cca_ed_level;
 
        struct device dev;
-       int idx;
 
        char priv[0] __aligned(NETDEV_ALIGN);
 };
index ed5b014dbec72227d6d2a0531674a5bcd8761a09..d1cd0edfb14989bd3bb7bad6eee197314e758b04 100644 (file)
@@ -23,9 +23,6 @@
 #include "sysfs.h"
 #include "core.h"
 
-static DEFINE_MUTEX(wpan_phy_mutex);
-static int wpan_phy_idx;
-
 static int wpan_phy_match(struct device *dev, const void *data)
 {
        return !strcmp(dev_name(dev), (const char *)data);
@@ -72,14 +69,10 @@ int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data),
 }
 EXPORT_SYMBOL(wpan_phy_for_each);
 
-static int wpan_phy_idx_valid(int idx)
-{
-       return idx >= 0;
-}
-
 struct wpan_phy *
 wpan_phy_alloc(const struct cfg802154_ops *ops, size_t priv_size)
 {
+       static atomic_t wpan_phy_counter = ATOMIC_INIT(0);
        struct cfg802154_registered_device *rdev;
        size_t alloc_size;
 
@@ -90,28 +83,27 @@ wpan_phy_alloc(const struct cfg802154_ops *ops, size_t priv_size)
 
        rdev->ops = ops;
 
-       mutex_lock(&wpan_phy_mutex);
-       rdev->wpan_phy.idx = wpan_phy_idx++;
-       if (unlikely(!wpan_phy_idx_valid(rdev->wpan_phy.idx))) {
-               wpan_phy_idx--;
-               mutex_unlock(&wpan_phy_mutex);
+       rdev->wpan_phy_idx = atomic_inc_return(&wpan_phy_counter);
+
+       if (unlikely(rdev->wpan_phy_idx < 0)) {
+               /* ugh, wrapped! */
+               atomic_dec(&wpan_phy_counter);
                kfree(rdev);
-               goto out;
+               return NULL;
        }
-       mutex_unlock(&wpan_phy_mutex);
+
+       /* atomic_inc_return makes it start at 1, make it start at 0 */
+       rdev->wpan_phy_idx--;
 
        mutex_init(&rdev->wpan_phy.pib_lock);
 
        device_initialize(&rdev->wpan_phy.dev);
-       dev_set_name(&rdev->wpan_phy.dev, "wpan-phy%d", rdev->wpan_phy.idx);
+       dev_set_name(&rdev->wpan_phy.dev, "wpan-phy%d", rdev->wpan_phy_idx);
 
        rdev->wpan_phy.dev.class = &wpan_phy_class;
        rdev->wpan_phy.dev.platform_data = rdev;
 
        return &rdev->wpan_phy;
-
-out:
-       return NULL;
 }
 EXPORT_SYMBOL(wpan_phy_alloc);
 
index 1bc1725871573f95368fd69a65728b137e548981..fea60b3a884609eca84c012610f83f93562e708b 100644 (file)
@@ -6,6 +6,9 @@
 struct cfg802154_registered_device {
        const struct cfg802154_ops *ops;
 
+       /* wpan_phy index, internal only */
+       int wpan_phy_idx;
+
        /* must be last because of the way we do wpan_phy_priv(),
         * and it should at least be aligned to NETDEV_ALIGN
         */