[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[hurd] 04/26: commit ccffad25b5136958d4769ed6de5e87992dd9c65c
From: |
Samuel Thibault |
Subject: |
[hurd] 04/26: commit ccffad25b5136958d4769ed6de5e87992dd9c65c |
Date: |
Tue, 22 Sep 2015 21:51:47 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch dde
in repository hurd.
commit d1fbd2c1aa074259fd1bfda9774364f82a4a77ac
Author: Jiri Pirko <address@hidden>
Date: Fri May 22 23:22:17 2009 +0000
commit ccffad25b5136958d4769ed6de5e87992dd9c65c
net: convert unicast addr list
This patch converts unicast address list to standard list_head using
previously introduced struct netdev_hw_addr. It also relaxes the
locking. Original spinlock (still used for multicast addresses) is not
needed and is no longer used for a protection of this list. All
reading and writing takes place under rtnl (with no changes).
I also removed a possibility to specify the length of the address
while adding or deleting unicast address. It's always dev->addr_len.
The convertion touched especially e1000 and ixgbe codes when the
change is not so trivial.
Signed-off-by: Jiri Pirko <address@hidden>
drivers/net/bnx2.c | 13 +--
drivers/net/e1000/e1000_main.c | 24 +++--
drivers/net/ixgbe/ixgbe_common.c | 14 ++--
drivers/net/ixgbe/ixgbe_common.h | 4 +-
drivers/net/ixgbe/ixgbe_main.c | 6 +-
drivers/net/ixgbe/ixgbe_type.h | 4 +-
drivers/net/macvlan.c | 11 +-
drivers/net/mv643xx_eth.c | 11 +-
drivers/net/niu.c | 7 +-
drivers/net/virtio_net.c | 7 +-
drivers/s390/net/qeth_l2_main.c | 6 +-
drivers/scsi/fcoe/fcoe.c | 16 ++--
include/linux/netdevice.h | 18 ++--
net/8021q/vlan.c | 4 +-
net/8021q/vlan_dev.c | 10 +-
net/core/dev.c | 195
+++++++++++++++++++++++++++-----------
net/dsa/slave.c | 10 +-
net/packet/af_packet.c | 4 +-
18 files changed, 227 insertions(+), 137 deletions(-)
Signed-off-by: David S. Miller <address@hidden>
---
libdde_linux26/contrib/include/linux/netdevice.h | 18 ++-
libdde_linux26/lib/src/net/core/dev.c | 195 ++++++++++++++++-------
2 files changed, 149 insertions(+), 64 deletions(-)
diff --git a/libdde_linux26/contrib/include/linux/netdevice.h
b/libdde_linux26/contrib/include/linux/netdevice.h
index 3f2cd12..d85de86 100644
--- a/libdde_linux26/contrib/include/linux/netdevice.h
+++ b/libdde_linux26/contrib/include/linux/netdevice.h
@@ -215,9 +215,12 @@ struct netdev_hw_addr {
struct list_head list;
unsigned char addr[MAX_ADDR_LEN];
unsigned char type;
-#define NETDEV_HW_ADDR_T_LAN 1
-#define NETDEV_HW_ADDR_T_SAN 2
-#define NETDEV_HW_ADDR_T_SLAVE 3
+#define NETDEV_HW_ADDR_T_LAN 1
+#define NETDEV_HW_ADDR_T_SAN 2
+#define NETDEV_HW_ADDR_T_SLAVE 3
+#define NETDEV_HW_ADDR_T_UNICAST 4
+ int refcount;
+ bool synced;
struct rcu_head rcu_head;
};
@@ -738,10 +741,11 @@ struct net_device
unsigned char addr_len; /* hardware address length
*/
unsigned short dev_id; /* for shared network cards */
- spinlock_t addr_list_lock;
- struct dev_addr_list *uc_list; /* Secondary unicast mac
addresses */
+ struct list_head uc_list; /* Secondary unicast mac
+ addresses */
int uc_count; /* Number of installed ucasts
*/
int uc_promisc;
+ spinlock_t addr_list_lock;
struct dev_addr_list *mc_list; /* Multicast mac addresses
*/
int mc_count; /* Number of installed mcasts
*/
unsigned int promiscuity;
@@ -1816,8 +1820,8 @@ extern int dev_addr_del_multiple(struct net_device
*to_dev,
/* Functions used for secondary unicast and multicast support */
extern void dev_set_rx_mode(struct net_device *dev);
extern void __dev_set_rx_mode(struct net_device *dev);
-extern int dev_unicast_delete(struct net_device *dev, void *addr,
int alen);
-extern int dev_unicast_add(struct net_device *dev, void *addr, int
alen);
+extern int dev_unicast_delete(struct net_device *dev, void *addr);
+extern int dev_unicast_add(struct net_device *dev, void *addr);
extern int dev_unicast_sync(struct net_device *to, struct
net_device *from);
extern void dev_unicast_unsync(struct net_device *to, struct
net_device *from);
extern int dev_mc_delete(struct net_device *dev, void *addr, int
alen, int all);
diff --git a/libdde_linux26/lib/src/net/core/dev.c
b/libdde_linux26/lib/src/net/core/dev.c
index 6d193de..958345b 100644
--- a/libdde_linux26/lib/src/net/core/dev.c
+++ b/libdde_linux26/lib/src/net/core/dev.c
@@ -3399,8 +3399,9 @@ void dev_set_rx_mode(struct net_device *dev)
/* hw addresses list handling functions */
-static int __hw_addr_add(struct list_head *list, unsigned char *addr,
- int addr_len, unsigned char addr_type)
+static int __hw_addr_add(struct list_head *list, int *delta,
+ unsigned char *addr, int addr_len,
+ unsigned char addr_type)
{
struct netdev_hw_addr *ha;
int alloc_size;
@@ -3408,6 +3409,15 @@ static int __hw_addr_add(struct list_head *list,
unsigned char *addr,
if (addr_len > MAX_ADDR_LEN)
return -EINVAL;
+ list_for_each_entry(ha, list, list) {
+ if (!memcmp(ha->addr, addr, addr_len) &&
+ ha->type == addr_type) {
+ ha->refcount++;
+ return 0;
+ }
+ }
+
+
alloc_size = sizeof(*ha);
if (alloc_size < L1_CACHE_BYTES)
alloc_size = L1_CACHE_BYTES;
@@ -3416,7 +3426,11 @@ static int __hw_addr_add(struct list_head *list,
unsigned char *addr,
return -ENOMEM;
memcpy(ha->addr, addr, addr_len);
ha->type = addr_type;
+ ha->refcount = 1;
+ ha->synced = false;
list_add_tail_rcu(&ha->list, list);
+ if (delta)
+ (*delta)++;
return 0;
}
@@ -3428,29 +3442,30 @@ static void ha_rcu_free(struct rcu_head *head)
kfree(ha);
}
-static int __hw_addr_del_ii(struct list_head *list, unsigned char *addr,
- int addr_len, unsigned char addr_type,
- int ignore_index)
+static int __hw_addr_del(struct list_head *list, int *delta,
+ unsigned char *addr, int addr_len,
+ unsigned char addr_type)
{
struct netdev_hw_addr *ha;
- int i = 0;
list_for_each_entry(ha, list, list) {
- if (i++ != ignore_index &&
- !memcmp(ha->addr, addr, addr_len) &&
+ if (!memcmp(ha->addr, addr, addr_len) &&
(ha->type == addr_type || !addr_type)) {
+ if (--ha->refcount)
+ return 0;
list_del_rcu(&ha->list);
call_rcu(&ha->rcu_head, ha_rcu_free);
+ if (delta)
+ (*delta)--;
return 0;
}
}
return -ENOENT;
}
-static int __hw_addr_add_multiple_ii(struct list_head *to_list,
- struct list_head *from_list,
- int addr_len, unsigned char addr_type,
- int ignore_index)
+static int __hw_addr_add_multiple(struct list_head *to_list, int *to_delta,
+ struct list_head *from_list, int addr_len,
+ unsigned char addr_type)
{
int err;
struct netdev_hw_addr *ha, *ha2;
@@ -3458,7 +3473,8 @@ static int __hw_addr_add_multiple_ii(struct list_head
*to_list,
list_for_each_entry(ha, from_list, list) {
type = addr_type ? addr_type : ha->type;
- err = __hw_addr_add(to_list, ha->addr, addr_len, type);
+ err = __hw_addr_add(to_list, to_delta, ha->addr,
+ addr_len, type);
if (err)
goto unroll;
}
@@ -3469,27 +3485,69 @@ unroll:
if (ha2 == ha)
break;
type = addr_type ? addr_type : ha2->type;
- __hw_addr_del_ii(to_list, ha2->addr, addr_len, type,
- ignore_index);
+ __hw_addr_del(to_list, to_delta, ha2->addr,
+ addr_len, type);
}
return err;
}
-static void __hw_addr_del_multiple_ii(struct list_head *to_list,
- struct list_head *from_list,
- int addr_len, unsigned char addr_type,
- int ignore_index)
+static void __hw_addr_del_multiple(struct list_head *to_list, int *to_delta,
+ struct list_head *from_list, int addr_len,
+ unsigned char addr_type)
{
struct netdev_hw_addr *ha;
unsigned char type;
list_for_each_entry(ha, from_list, list) {
type = addr_type ? addr_type : ha->type;
- __hw_addr_del_ii(to_list, ha->addr, addr_len, addr_type,
- ignore_index);
+ __hw_addr_del(to_list, to_delta, ha->addr,
+ addr_len, addr_type);
+ }
+}
+
+static int __hw_addr_sync(struct list_head *to_list, int *to_delta,
+ struct list_head *from_list, int *from_delta,
+ int addr_len)
+{
+ int err = 0;
+ struct netdev_hw_addr *ha, *tmp;
+
+ list_for_each_entry_safe(ha, tmp, from_list, list) {
+ if (!ha->synced) {
+ err = __hw_addr_add(to_list, to_delta, ha->addr,
+ addr_len, ha->type);
+ if (err)
+ break;
+ ha->synced = true;
+ ha->refcount++;
+ } else if (ha->refcount == 1) {
+ __hw_addr_del(to_list, to_delta, ha->addr,
+ addr_len, ha->type);
+ __hw_addr_del(from_list, from_delta, ha->addr,
+ addr_len, ha->type);
+ }
}
+ return err;
}
+static void __hw_addr_unsync(struct list_head *to_list, int *to_delta,
+ struct list_head *from_list, int *from_delta,
+ int addr_len)
+{
+ struct netdev_hw_addr *ha, *tmp;
+
+ list_for_each_entry_safe(ha, tmp, from_list, list) {
+ if (ha->synced) {
+ __hw_addr_del(to_list, to_delta, ha->addr,
+ addr_len, ha->type);
+ ha->synced = false;
+ __hw_addr_del(from_list, from_delta, ha->addr,
+ addr_len, ha->type);
+ }
+ }
+}
+
+
static void __hw_addr_flush(struct list_head *list)
{
struct netdev_hw_addr *ha, *tmp;
@@ -3520,7 +3578,7 @@ static int dev_addr_init(struct net_device *dev)
INIT_LIST_HEAD(&dev->dev_addr_list);
memset(addr, 0, sizeof(*addr));
- err = __hw_addr_add(&dev->dev_addr_list, addr, sizeof(*addr),
+ err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(*addr),
NETDEV_HW_ADDR_T_LAN);
if (!err) {
/*
@@ -3552,7 +3610,7 @@ int dev_addr_add(struct net_device *dev, unsigned char
*addr,
ASSERT_RTNL();
- err = __hw_addr_add(&dev->dev_addr_list, addr, dev->addr_len,
+ err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, dev->addr_len,
addr_type);
if (!err)
call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
@@ -3575,11 +3633,20 @@ int dev_addr_del(struct net_device *dev, unsigned char
*addr,
unsigned char addr_type)
{
int err;
+ struct netdev_hw_addr *ha;
ASSERT_RTNL();
- err = __hw_addr_del_ii(&dev->dev_addr_list, addr, dev->addr_len,
- addr_type, 0);
+ /*
+ * We can not remove the first address from the list because
+ * dev->dev_addr points to that.
+ */
+ ha = list_first_entry(&dev->dev_addr_list, struct netdev_hw_addr, list);
+ if (ha->addr == dev->dev_addr && ha->refcount == 1)
+ return -ENOENT;
+
+ err = __hw_addr_del(&dev->dev_addr_list, NULL, addr, dev->addr_len,
+ addr_type);
if (!err)
call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
return err;
@@ -3606,9 +3673,9 @@ int dev_addr_add_multiple(struct net_device *to_dev,
if (from_dev->addr_len != to_dev->addr_len)
return -EINVAL;
- err = __hw_addr_add_multiple_ii(&to_dev->dev_addr_list,
- &from_dev->dev_addr_list,
- to_dev->addr_len, addr_type, 0);
+ err = __hw_addr_add_multiple(&to_dev->dev_addr_list, NULL,
+ &from_dev->dev_addr_list,
+ to_dev->addr_len, addr_type);
if (!err)
call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev);
return err;
@@ -3633,9 +3700,9 @@ int dev_addr_del_multiple(struct net_device *to_dev,
if (from_dev->addr_len != to_dev->addr_len)
return -EINVAL;
- __hw_addr_del_multiple_ii(&to_dev->dev_addr_list,
- &from_dev->dev_addr_list,
- to_dev->addr_len, addr_type, 0);
+ __hw_addr_del_multiple(&to_dev->dev_addr_list, NULL,
+ &from_dev->dev_addr_list,
+ to_dev->addr_len, addr_type);
call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev);
return 0;
}
@@ -3705,24 +3772,22 @@ int __dev_addr_add(struct dev_addr_list **list, int
*count,
* dev_unicast_delete - Release secondary unicast address.
* @dev: device
* @addr: address to delete
- * @alen: length of @addr
*
* Release reference to a secondary unicast address and remove it
* from the device if the reference count drops to zero.
*
* The caller must hold the rtnl_mutex.
*/
-int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
+int dev_unicast_delete(struct net_device *dev, void *addr)
{
int err;
ASSERT_RTNL();
- netif_addr_lock_bh(dev);
- err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
+ err = __hw_addr_del(&dev->uc_list, &dev->uc_count, addr,
+ dev->addr_len, NETDEV_HW_ADDR_T_UNICAST);
if (!err)
__dev_set_rx_mode(dev);
- netif_addr_unlock_bh(dev);
return err;
}
EXPORT_SYMBOL(dev_unicast_delete);
@@ -3731,24 +3796,22 @@ EXPORT_SYMBOL(dev_unicast_delete);
* dev_unicast_add - add a secondary unicast address
* @dev: device
* @addr: address to add
- * @alen: length of @addr
*
* Add a secondary unicast address to the device or increase
* the reference count if it already exists.
*
* The caller must hold the rtnl_mutex.
*/
-int dev_unicast_add(struct net_device *dev, void *addr, int alen)
+int dev_unicast_add(struct net_device *dev, void *addr)
{
int err;
ASSERT_RTNL();
- netif_addr_lock_bh(dev);
- err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
+ err = __hw_addr_add(&dev->uc_list, &dev->uc_count, addr,
+ dev->addr_len, NETDEV_HW_ADDR_T_UNICAST);
if (!err)
__dev_set_rx_mode(dev);
- netif_addr_unlock_bh(dev);
return err;
}
EXPORT_SYMBOL(dev_unicast_add);
@@ -3805,8 +3868,7 @@ void __dev_addr_unsync(struct dev_addr_list **to, int
*to_count,
* @from: source device
*
* Add newly added addresses to the destination device and release
- * addresses that have no users left. The source device must be
- * locked by netif_addr_lock_bh.
+ * addresses that have no users left.
*
* This function is intended to be called from the dev->set_rx_mode
* function of layered software devices.
@@ -3815,12 +3877,15 @@ int dev_unicast_sync(struct net_device *to, struct
net_device *from)
{
int err = 0;
- netif_addr_lock_bh(to);
- err = __dev_addr_sync(&to->uc_list, &to->uc_count,
- &from->uc_list, &from->uc_count);
+ ASSERT_RTNL();
+
+ if (to->addr_len != from->addr_len)
+ return -EINVAL;
+
+ err = __hw_addr_sync(&to->uc_list, &to->uc_count,
+ &from->uc_list, &from->uc_count, to->addr_len);
if (!err)
__dev_set_rx_mode(to);
- netif_addr_unlock_bh(to);
return err;
}
EXPORT_SYMBOL(dev_unicast_sync);
@@ -3836,18 +3901,33 @@ EXPORT_SYMBOL(dev_unicast_sync);
*/
void dev_unicast_unsync(struct net_device *to, struct net_device *from)
{
- netif_addr_lock_bh(from);
- netif_addr_lock(to);
+ ASSERT_RTNL();
- __dev_addr_unsync(&to->uc_list, &to->uc_count,
- &from->uc_list, &from->uc_count);
- __dev_set_rx_mode(to);
+ if (to->addr_len != from->addr_len)
+ return;
- netif_addr_unlock(to);
- netif_addr_unlock_bh(from);
+ __hw_addr_unsync(&to->uc_list, &to->uc_count,
+ &from->uc_list, &from->uc_count, to->addr_len);
+ __dev_set_rx_mode(to);
}
EXPORT_SYMBOL(dev_unicast_unsync);
+static void dev_unicast_flush(struct net_device *dev)
+{
+ /* rtnl_mutex must be held here */
+
+ __hw_addr_flush(&dev->uc_list);
+ dev->uc_count = 0;
+}
+
+static void dev_unicast_init(struct net_device *dev)
+{
+ /* rtnl_mutex must be held here */
+
+ INIT_LIST_HEAD(&dev->uc_list);
+}
+
+
static void __dev_addr_discard(struct dev_addr_list **list)
{
struct dev_addr_list *tmp;
@@ -3866,9 +3946,6 @@ static void dev_addr_discard(struct net_device *dev)
{
netif_addr_lock_bh(dev);
- __dev_addr_discard(&dev->uc_list);
- dev->uc_count = 0;
-
__dev_addr_discard(&dev->mc_list);
dev->mc_count = 0;
@@ -4459,6 +4536,7 @@ static void rollback_registered(struct net_device *dev)
/*
* Flush the unicast and multicast chains
*/
+ dev_unicast_flush(dev);
dev_addr_discard(dev);
if (dev->netdev_ops->ndo_uninit)
@@ -4975,6 +5053,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const
char *name,
dev = (struct net_device *)
(((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
dev->padded = (char *)dev - (char *)p;
+ dev_unicast_init(dev);
+
dev_net_set(dev, &init_net);
dev->_tx = tx;
@@ -5173,6 +5253,7 @@ int dev_change_net_namespace(struct net_device *dev,
struct net *net, const char
/*
* Flush the unicast and multicast chains
*/
+ dev_unicast_flush(dev);
dev_addr_discard(dev);
netdev_unregister_kobject(dev);
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/hurd.git
- [hurd] 12/26: update pci_ids, (continued)
- [hurd] 12/26: update pci_ids, Samuel Thibault, 2015/09/22
- [hurd] 17/26: Add pr_cont, Samuel Thibault, 2015/09/22
- [hurd] 26/26: Move files, Samuel Thibault, 2015/09/22
- [hurd] 14/26: update workqueue.h, Samuel Thibault, 2015/09/22
- [hurd] 25/26: Merge branch 'dde-upstream' into dde, Samuel Thibault, 2015/09/22
- [hurd] 23/26: Fix build with gcc 5, Samuel Thibault, 2015/09/22
- [hurd] 15/26: commit 9d21493b4beb8f918ba248032fefa393074a5e2b, Samuel Thibault, 2015/09/22
- [hurd] 21/26: Fix insecure format, Samuel Thibault, 2015/09/22
- [hurd] 03/26: commit f001fde5eadd915f4858d22ed70d7040f48767cf, Samuel Thibault, 2015/09/22
- [hurd] 06/26: commit 31278e71471399beaff9280737e52b47db4dc345, Samuel Thibault, 2015/09/22
- [hurd] 04/26: commit ccffad25b5136958d4769ed6de5e87992dd9c65c,
Samuel Thibault <=
- [hurd] 09/26: Add mdio.h, Samuel Thibault, 2015/09/22
- [hurd] 19/26: Add rcuclassic.c, Samuel Thibault, 2015/09/22
- [hurd] 20/26: really add files, Samuel Thibault, 2015/09/22