From 53f9ee61b46d81a43d8c6694d136896e8f49a7b8 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 5 Nov 2014 20:51:12 +0100 Subject: ieee802154: rework wpan_phy index assignment 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 Signed-off-by: Marcel Holtmann --- net/ieee802154/core.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'net/ieee802154/core.c') diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index ed5b014dbec..d1cd0edfb14 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -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); -- cgit v1.2.3-70-g09d2