summaryrefslogtreecommitdiffstats
path: root/drivers/net/ieee802154/fakelb.c
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2015-05-17 21:45:05 +0200
committerMarcel Holtmann <marcel@holtmann.org>2015-05-19 11:44:46 +0200
commite369dc8f1aa95cd490e1ab75043dcf50d2190453 (patch)
tree4e6693168f9ffa162fe1c4566750ef20ac9f7962 /drivers/net/ieee802154/fakelb.c
parentfakelb: move lock out of iteration (diff)
downloadlinux-e369dc8f1aa95cd490e1ab75043dcf50d2190453.tar.xz
linux-e369dc8f1aa95cd490e1ab75043dcf50d2190453.zip
fakelb: introduce fakelb ifup phys list
This patch introduce a fakelb ifup phys list, which stores all registered phys which are in an operated mode. This will reduce the iterations of non-operated phys while transmit frames. There exists two locks now, one rwlock for the operated interfaces and the spinlock for protecting the list for all registered virtual phys. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/net/ieee802154/fakelb.c')
-rw-r--r--drivers/net/ieee802154/fakelb.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index e1c0195c18aa..83957de47243 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -28,16 +28,18 @@
#include <net/cfg802154.h>
static int numlbs = 2;
-static DEFINE_RWLOCK(fakelb_lock);
+
static LIST_HEAD(fakelb_phys);
+static DEFINE_SPINLOCK(fakelb_phys_lock);
+
+static LIST_HEAD(fakelb_ifup_phys);
+static DEFINE_RWLOCK(fakelb_ifup_phys_lock);
struct fakelb_phy {
struct ieee802154_hw *hw;
struct list_head list;
-
- spinlock_t lock;
- bool working;
+ struct list_head list_ifup;
};
static int
@@ -62,13 +64,9 @@ fakelb_hw_deliver(struct fakelb_phy *phy, struct sk_buff *skb)
{
struct sk_buff *newskb;
- spin_lock(&phy->lock);
- if (phy->working) {
- newskb = pskb_copy(skb, GFP_ATOMIC);
- if (newskb)
- ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
- }
- spin_unlock(&phy->lock);
+ newskb = pskb_copy(skb, GFP_ATOMIC);
+ if (newskb)
+ ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
}
static int
@@ -77,8 +75,8 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
struct fakelb_phy *current_phy = hw->priv;
struct fakelb_phy *phy;
- read_lock_bh(&fakelb_lock);
- list_for_each_entry(phy, &fakelb_phys, list) {
+ read_lock_bh(&fakelb_ifup_phys_lock);
+ list_for_each_entry(phy, &fakelb_ifup_phys, list_ifup) {
if (current_phy == phy)
continue;
@@ -86,7 +84,7 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
current_phy->hw->phy->current_channel)
fakelb_hw_deliver(phy, skb);
}
- read_unlock_bh(&fakelb_lock);
+ read_unlock_bh(&fakelb_ifup_phys_lock);
return 0;
}
@@ -94,25 +92,21 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
static int
fakelb_hw_start(struct ieee802154_hw *hw) {
struct fakelb_phy *phy = hw->priv;
- int ret = 0;
- spin_lock(&phy->lock);
- if (phy->working)
- ret = -EBUSY;
- else
- phy->working = 1;
- spin_unlock(&phy->lock);
+ write_lock_bh(&fakelb_ifup_phys_lock);
+ list_add(&phy->list_ifup, &fakelb_ifup_phys);
+ write_unlock_bh(&fakelb_ifup_phys_lock);
- return ret;
+ return 0;
}
static void
fakelb_hw_stop(struct ieee802154_hw *hw) {
struct fakelb_phy *phy = hw->priv;
- spin_lock(&phy->lock);
- phy->working = 0;
- spin_unlock(&phy->lock);
+ write_lock_bh(&fakelb_ifup_phys_lock);
+ list_del(&phy->list_ifup);
+ write_unlock_bh(&fakelb_ifup_phys_lock);
}
static const struct ieee802154_ops fakelb_ops = {
@@ -172,17 +166,15 @@ static int fakelb_add_one(struct device *dev)
/* 950 MHz GFSK 802.15.4d-2009 */
hw->phy->supported.channels[6] |= 0x3ffc00;
- spin_lock_init(&phy->lock);
-
hw->parent = dev;
err = ieee802154_register_hw(hw);
if (err)
goto err_reg;
- write_lock_bh(&fakelb_lock);
+ spin_lock(&fakelb_phys_lock);
list_add_tail(&phy->list, &fakelb_phys);
- write_unlock_bh(&fakelb_lock);
+ spin_unlock(&fakelb_phys_lock);
return 0;
@@ -215,10 +207,10 @@ static int fakelb_probe(struct platform_device *pdev)
return 0;
err_slave:
- write_lock_bh(&fakelb_lock);
+ spin_lock(&fakelb_phys_lock);
list_for_each_entry_safe(phy, tmp, &fakelb_phys, list)
fakelb_del(phy);
- write_unlock_bh(&fakelb_lock);
+ spin_unlock(&fakelb_phys_lock);
return err;
}
@@ -226,10 +218,10 @@ static int fakelb_remove(struct platform_device *pdev)
{
struct fakelb_phy *phy, *temp;
- write_lock_bh(&fakelb_lock);
+ spin_lock(&fakelb_phys_lock);
list_for_each_entry_safe(phy, temp, &fakelb_phys, list)
fakelb_del(phy);
- write_unlock_bh(&fakelb_lock);
+ spin_unlock(&fakelb_phys_lock);
return 0;
}