* Re: [PATCH net-next-2.6] net: use helpers to access uc list V2
From: David Miller @ 2010-01-25 21:36 UTC (permalink / raw)
To: jpirko; +Cc: netdev
In-Reply-To: <20100125210543.GB6746@psychotron.redhat.com>
From: Jiri Pirko <jpirko@redhat.com>
Date: Mon, 25 Jan 2010 22:05:45 +0100
> This patch introduces three macros to work with uc list from net drivers.
>
> Signed-off-by: Jiri Pirko <jpirko@redhat.com>
This looks better, applied, thanks!
^ permalink raw reply
* Re: [PATCH] IPv6: Update documentation for better built-in help with params
From: David Miller @ 2010-01-25 21:34 UTC (permalink / raw)
To: rdunlap; +Cc: brian.haley, greg, nhorman, netdev
In-Reply-To: <20100125133133.aa2b86a2.rdunlap@xenotime.net>
From: Randy Dunlap <rdunlap@xenotime.net>
Date: Mon, 25 Jan 2010 13:31:33 -0800
> On Mon, 25 Jan 2010 13:21:42 -0800 (PST) David Miller wrote:
>
>> From: Brian Haley <brian.haley@hp.com>
>> Date: Mon, 25 Jan 2010 12:28:15 -0500
>>
>> > I guess Documentation/kernel-parameters.txt is where such things
>> > live, can I send you a patch for that or does it need to go
>> > through someone else?
>>
>> I think lkml is a suitable place to submit something like
>> that.
>> --
>
> Sure, but if it's networking parameters, you (David) could still merge it...
It's not about networking parameters.
It's about adding a generic mention somewhere central that you can set
"module parameters" on the kernel command line when a module is built
statically into the kernel.
^ permalink raw reply
* Re: [PATCH 4/8] percpu: add __percpu sparse annotations to net drivers
From: David Miller @ 2010-01-25 21:33 UTC (permalink / raw)
To: tj
Cc: linux-kernel, axboe, rusty, akpm, ebiederm, tytso,
Trond.Myklebust, aelder, hch, viro, netdev, x86, mingo, fweisbec,
dan.j.williams, borislav.petkov, ying.huang, lenb, neilb, cl,
eric.dumazet, arnd
In-Reply-To: <1264432935-10453-5-git-send-email-tj@kernel.org>
From: Tejun Heo <tj@kernel.org>
Date: Tue, 26 Jan 2010 00:22:11 +0900
> Add __percpu sparse annotations to net drivers.
>
> These annotations are to make sparse consider percpu variables to be
> in a different address space and warn if accessed without going
> through percpu accessors. This patch doesn't affect normal builds.
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: [PATCH 3/8] percpu: add __percpu sparse annotations to net
From: David Miller @ 2010-01-25 21:32 UTC (permalink / raw)
To: tj
Cc: linux-kernel, axboe, rusty, akpm, ebiederm, tytso,
Trond.Myklebust, aelder, hch, viro, netdev, x86, mingo, fweisbec,
dan.j.williams, borislav.petkov, ying.huang, lenb, neilb, cl,
kaber, acme, vladislav.yasevich
In-Reply-To: <1264432935-10453-4-git-send-email-tj@kernel.org>
From: Tejun Heo <tj@kernel.org>
Date: Tue, 26 Jan 2010 00:22:10 +0900
> Add __percpu sparse annotations to net.
>
> These annotations are to make sparse consider percpu variables to be
> in a different address space and warn if accessed without going
> through percpu accessors. This patch doesn't affect normal builds.
>
> The macro and type tricks around snmp stats make things a bit
> interesting. DEFINE/DECLARE_SNMP_STAT() macros mark the target field
> as __percpu and SNMP_UPD_PO_STATS() macro is updated accordingly. All
> snmp_mib_*() users which used to cast the argument to (void **) are
> updated to cast it to (void __percpu **).
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: [PATCH] IPv6: Update documentation for better built-in help with params
From: Randy Dunlap @ 2010-01-25 21:31 UTC (permalink / raw)
To: David Miller; +Cc: brian.haley, greg, nhorman, netdev
In-Reply-To: <20100125.132142.144428296.davem@davemloft.net>
On Mon, 25 Jan 2010 13:21:42 -0800 (PST) David Miller wrote:
> From: Brian Haley <brian.haley@hp.com>
> Date: Mon, 25 Jan 2010 12:28:15 -0500
>
> > I guess Documentation/kernel-parameters.txt is where such things
> > live, can I send you a patch for that or does it need to go
> > through someone else?
>
> I think lkml is a suitable place to submit something like
> that.
> --
Sure, but if it's networking parameters, you (David) could still merge it...
---
~Randy
^ permalink raw reply
* Re: [PATCH] IPv6: Update documentation for better built-in help with params
From: David Miller @ 2010-01-25 21:21 UTC (permalink / raw)
To: brian.haley; +Cc: greg, nhorman, netdev
In-Reply-To: <4B5DD4AF.8050800@hp.com>
From: Brian Haley <brian.haley@hp.com>
Date: Mon, 25 Jan 2010 12:28:15 -0500
> I guess Documentation/kernel-parameters.txt is where such things
> live, can I send you a patch for that or does it need to go
> through someone else?
I think lkml is a suitable place to submit something like
that.
^ permalink raw reply
* [PATCH net-next-2.6] net: Handle vlan packets in skb_gso_segment()
From: Sridhar Samudrala @ 2010-01-25 21:16 UTC (permalink / raw)
To: David Miller, Herbert Xu; +Cc: netdev
Handle VLAN packets in skb_gso_segment(). Currently, when large
VLAN packets are sent via virtio_net on guest and tun on host,
skb_gso_segment() fails with EPROTONOSUPPORT.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
diff --git a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1672,6 +1672,12 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
skb_reset_mac_header(skb);
skb->mac_len = skb->network_header - skb->mac_header;
+ if (ntohs(type) == ETH_P_8021Q) {
+ skb->protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+ type = skb->protocol;
+ skb->mac_len += VLAN_HLEN;
+ skb_set_network_header(skb, skb->mac_len);
+ }
__skb_pull(skb, skb->mac_len);
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
^ permalink raw reply
* [PATCH net-next-2.6] virtio_net: Set vlan_features to enable offloads on vlan devices
From: Sridhar Samudrala @ 2010-01-25 21:16 UTC (permalink / raw)
To: David Miller, Herbert Xu, rusty; +Cc: netdev
Set vlan_features in virtnet_probe() so that all the available offloads
are enabled on vlan devices attached to virtio_net devices.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -872,6 +872,8 @@ static int virtnet_probe(struct virtio_device *vdev)
dev->features |= NETIF_F_UFO;
}
+ dev->vlan_features = dev->features;
+
/* Configuration may specify what MAC to use. Otherwise random. */
if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) {
vdev->config->get(vdev,
^ permalink raw reply
* [PATCH net-next-2.6] net: use helpers to access uc list V2
From: Jiri Pirko @ 2010-01-25 21:05 UTC (permalink / raw)
To: netdev; +Cc: davem
This patch introduces three macros to work with uc list from net drivers.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d83512d..a7b6b12 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -48,7 +48,6 @@
#include <linux/cache.h>
#include <linux/firmware.h>
#include <linux/log2.h>
-#include <linux/list.h>
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
#define BCM_CNIC 1
@@ -3579,14 +3578,14 @@ bnx2_set_rx_mode(struct net_device *dev)
sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN;
}
- if (dev->uc.count > BNX2_MAX_UNICAST_ADDRESSES) {
+ if (netdev_uc_count(dev) > BNX2_MAX_UNICAST_ADDRESSES) {
rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN |
BNX2_RPM_SORT_USER0_PROM_VLAN;
} else if (!(dev->flags & IFF_PROMISC)) {
/* Add all entries into to the match filter list */
i = 0;
- list_for_each_entry(ha, &dev->uc.list, list) {
+ netdev_for_each_uc_addr(ha, dev) {
bnx2_set_mac_addr(bp, ha->addr,
i + BNX2_START_UNICAST_ADDRESS_INDEX);
sort_mode |= (1 <<
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 87f575c..2ce88c5 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2139,7 +2139,7 @@ static void e1000_set_rx_mode(struct net_device *netdev)
rctl |= E1000_RCTL_VFE;
}
- if (netdev->uc.count > rar_entries - 1) {
+ if (netdev_uc_count(netdev) > rar_entries - 1) {
rctl |= E1000_RCTL_UPE;
} else if (!(netdev->flags & IFF_PROMISC)) {
rctl &= ~E1000_RCTL_UPE;
@@ -2162,7 +2162,7 @@ static void e1000_set_rx_mode(struct net_device *netdev)
*/
i = 1;
if (use_uc)
- list_for_each_entry(ha, &netdev->uc.list, list) {
+ netdev_for_each_uc_addr(ha, netdev) {
if (i == rar_entries)
break;
e1000_rar_set(hw, ha->addr, i++);
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index d967949..01cc294 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -2905,12 +2905,13 @@ static int igb_write_uc_addr_list(struct net_device *netdev)
int count = 0;
/* return ENOMEM indicating insufficient memory for addresses */
- if (netdev->uc.count > rar_entries)
+ if (netdev_uc_count(netdev) > rar_entries)
return -ENOMEM;
- if (netdev->uc.count && rar_entries) {
+ if (!netdev_uc_empty(netdev) && rar_entries) {
struct netdev_hw_addr *ha;
- list_for_each_entry(ha, &netdev->uc.list, list) {
+
+ netdev_for_each_uc_addr(ha, netdev) {
if (!rar_entries)
break;
igb_rar_set_qsel(adapter, ha->addr,
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 276c2aa..eb49020 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -28,7 +28,6 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/sched.h>
-#include <linux/list.h>
#include <linux/netdevice.h>
#include "ixgbe.h"
@@ -1347,7 +1346,7 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
/**
* ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
* @hw: pointer to hardware structure
- * @uc_list: the list of new addresses
+ * @netdev: pointer to net device structure
*
* The given list replaces any existing list. Clears the secondary addrs from
* receive address registers. Uses unused receive address registers for the
@@ -1357,7 +1356,7 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
* manually putting the device into promiscuous mode.
**/
s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
- struct list_head *uc_list)
+ struct net_device *netdev)
{
u32 i;
u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
@@ -1381,7 +1380,7 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
}
/* Add the new addresses */
- list_for_each_entry(ha, uc_list, list) {
+ netdev_for_each_uc_addr(ha, netdev) {
hw_dbg(hw, " Adding the secondary addresses:\n");
ixgbe_add_uc_addr(hw, ha->addr, 0);
}
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index dfff0ff..13606d4 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -60,7 +60,7 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
u32 mc_addr_count,
ixgbe_mc_addr_itr func);
s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
- struct list_head *uc_list);
+ struct net_device *netdev);
s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index ee41d33..439645d 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -2568,7 +2568,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
/* reprogram secondary unicast list */
- hw->mac.ops.update_uc_addr_list(hw, &netdev->uc.list);
+ hw->mac.ops.update_uc_addr_list(hw, netdev);
/* reprogram multicast list */
addr_count = netdev->mc_count;
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index b4caa70..0db67c1 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -30,7 +30,7 @@
#include <linux/types.h>
#include <linux/mdio.h>
-#include <linux/list.h>
+#include <linux/netdevice.h>
/* Vendor ID */
#define IXGBE_INTEL_VENDOR_ID 0x8086
@@ -2405,7 +2405,7 @@ struct ixgbe_mac_operations {
s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32);
s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32);
s32 (*init_rx_addrs)(struct ixgbe_hw *);
- s32 (*update_uc_addr_list)(struct ixgbe_hw *, struct list_head *);
+ s32 (*update_uc_addr_list)(struct ixgbe_hw *, struct net_device *);
s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32,
ixgbe_mc_addr_itr);
s32 (*enable_mc)(struct ixgbe_hw *);
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index af67af5..e24072a 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -55,7 +55,6 @@
#include <linux/types.h>
#include <linux/inet_lro.h>
#include <asm/system.h>
-#include <linux/list.h>
static char mv643xx_eth_driver_name[] = "mv643xx_eth";
static char mv643xx_eth_driver_version[] = "1.4";
@@ -1697,7 +1696,7 @@ static u32 uc_addr_filter_mask(struct net_device *dev)
return 0;
nibbles = 1 << (dev->dev_addr[5] & 0x0f);
- list_for_each_entry(ha, &dev->uc.list, list) {
+ netdev_for_each_uc_addr(ha, dev) {
if (memcmp(dev->dev_addr, ha->addr, 5))
return 0;
if ((dev->dev_addr[5] ^ ha->addr[5]) & 0xf0)
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 0e260cf..af9a864 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -6372,7 +6372,7 @@ static void niu_set_rx_mode(struct net_device *dev)
if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 0))
np->flags |= NIU_FLAGS_MCAST;
- alt_cnt = dev->uc.count;
+ alt_cnt = netdev_uc_count(dev);
if (alt_cnt > niu_num_alt_addr(np)) {
alt_cnt = 0;
np->flags |= NIU_FLAGS_PROMISC;
@@ -6381,7 +6381,7 @@ static void niu_set_rx_mode(struct net_device *dev)
if (alt_cnt) {
int index = 0;
- list_for_each_entry(ha, &dev->uc.list, list) {
+ netdev_for_each_uc_addr(ha, dev) {
err = niu_set_alt_mac(np, index, ha->addr);
if (err)
printk(KERN_WARNING PFX "%s: Error %d "
diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c
index 928eac0..d812e9c 100644
--- a/drivers/net/stmmac/dwmac1000_core.c
+++ b/drivers/net/stmmac/dwmac1000_core.c
@@ -83,7 +83,7 @@ static void dwmac1000_set_filter(struct net_device *dev)
unsigned int value = 0;
DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
- __func__, dev->mc_count, dev->uc.count);
+ __func__, dev->mc_count, netdev_uc_count(dev));
if (dev->flags & IFF_PROMISC)
value = GMAC_FRAME_FILTER_PR;
@@ -117,7 +117,7 @@ static void dwmac1000_set_filter(struct net_device *dev)
}
/* Handle multiple unicast addresses (perfect filtering)*/
- if (dev->uc.count > GMAC_MAX_UNICAST_ADDRESSES)
+ if (netdev_uc_count(dev) > GMAC_MAX_UNICAST_ADDRESSES)
/* Switch to promiscuous mode is more than 16 addrs
are required */
value |= GMAC_FRAME_FILTER_PR;
@@ -125,9 +125,9 @@ static void dwmac1000_set_filter(struct net_device *dev)
int reg = 1;
struct netdev_hw_addr *ha;
- list_for_each_entry(ha, &dev->uc.list, list) {
- dwmac1000_set_umac_addr(ioaddr, ha->addr, reg);
- reg++;
+ netdev_for_each_uc_addr(ha, dev) {
+ dwmac1000_set_umac_addr(ioaddr, ha->addr, reg);
+ reg++;
}
}
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c708ecc..088332a 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -675,6 +675,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
struct virtio_net_ctrl_mac *mac_data;
struct dev_addr_list *addr;
struct netdev_hw_addr *ha;
+ int uc_count;
void *buf;
int i;
@@ -701,8 +702,9 @@ static void virtnet_set_rx_mode(struct net_device *dev)
dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
allmulti ? "en" : "dis");
+ uc_count = netdev_uc_count(dev);
/* MAC filter - use one buffer for both lists */
- mac_data = buf = kzalloc(((dev->uc.count + dev->mc_count) * ETH_ALEN) +
+ mac_data = buf = kzalloc(((uc_count + dev->mc_count) * ETH_ALEN) +
(2 * sizeof(mac_data->entries)), GFP_ATOMIC);
if (!buf) {
dev_warn(&dev->dev, "No memory for MAC address buffer\n");
@@ -712,16 +714,16 @@ static void virtnet_set_rx_mode(struct net_device *dev)
sg_init_table(sg, 2);
/* Store the unicast list and count in the front of the buffer */
- mac_data->entries = dev->uc.count;
+ mac_data->entries = uc_count;
i = 0;
- list_for_each_entry(ha, &dev->uc.list, list)
+ netdev_for_each_uc_addr(ha, dev)
memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN);
sg_set_buf(&sg[0], mac_data,
- sizeof(mac_data->entries) + (dev->uc.count * ETH_ALEN));
+ sizeof(mac_data->entries) + (uc_count * ETH_ALEN));
/* multicast list and count fill the end */
- mac_data = (void *)&mac_data->macs[dev->uc.count][0];
+ mac_data = (void *)&mac_data->macs[uc_count][0];
mac_data->entries = dev->mc_count;
addr = dev->mc_list;
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index c3258b0..51fde6f 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -622,7 +622,7 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
for (dm = dev->mc_list; dm; dm = dm->next)
qeth_l2_add_mc(card, dm->da_addr, 0);
- list_for_each_entry(ha, &dev->uc.list, list)
+ netdev_for_each_uc_addr(ha, dev)
qeth_l2_add_mc(card, ha->addr, 1);
spin_unlock_bh(&card->mclock);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b5fb51d..93a32a5 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -263,6 +263,11 @@ struct netdev_hw_addr_list {
int count;
};
+#define netdev_uc_count(dev) ((dev)->uc.count)
+#define netdev_uc_empty(dev) ((dev)->uc.count == 0)
+#define netdev_for_each_uc_addr(ha, dev) \
+ list_for_each_entry(ha, &dev->uc.list, list)
+
struct hh_cache {
struct hh_cache *hh_next; /* Next entry */
atomic_t hh_refcnt; /* number of users */
diff --git a/net/core/dev.c b/net/core/dev.c
index 4fad9db..2cba5c5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3665,10 +3665,10 @@ void __dev_set_rx_mode(struct net_device *dev)
/* Unicast addresses changes may only happen under the rtnl,
* therefore calling __dev_set_promiscuity here is safe.
*/
- if (dev->uc.count > 0 && !dev->uc_promisc) {
+ if (!netdev_uc_empty(dev) && !dev->uc_promisc) {
__dev_set_promiscuity(dev, 1);
dev->uc_promisc = 1;
- } else if (dev->uc.count == 0 && dev->uc_promisc) {
+ } else if (netdev_uc_empty(dev) && dev->uc_promisc) {
__dev_set_promiscuity(dev, -1);
dev->uc_promisc = 0;
}
^ permalink raw reply related
* [PATCH 4/4] netns xfrm: ipcomp6 support
From: Alexey Dobriyan @ 2010-01-25 20:39 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
net/ipv6/ipcomp6.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -53,6 +53,7 @@
static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info)
{
+ struct net *net = dev_net(skb->dev);
__be32 spi;
struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
struct ip_comp_hdr *ipcomph =
@@ -63,7 +64,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return;
spi = htonl(ntohs(ipcomph->cpi));
- x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6);
+ x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6);
if (!x)
return;
@@ -74,14 +75,15 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
{
+ struct net *net = xs_net(x);
struct xfrm_state *t = NULL;
- t = xfrm_state_alloc(&init_net);
+ t = xfrm_state_alloc(net);
if (!t)
goto out;
t->id.proto = IPPROTO_IPV6;
- t->id.spi = xfrm6_tunnel_alloc_spi(&init_net, (xfrm_address_t *)&x->props.saddr);
+ t->id.spi = xfrm6_tunnel_alloc_spi(net, (xfrm_address_t *)&x->props.saddr);
if (!t->id.spi)
goto error;
@@ -108,13 +110,14 @@ error:
static int ipcomp6_tunnel_attach(struct xfrm_state *x)
{
+ struct net *net = xs_net(x);
int err = 0;
struct xfrm_state *t = NULL;
__be32 spi;
- spi = xfrm6_tunnel_spi_lookup(&init_net, (xfrm_address_t *)&x->props.saddr);
+ spi = xfrm6_tunnel_spi_lookup(net, (xfrm_address_t *)&x->props.saddr);
if (spi)
- t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr,
+ t = xfrm_state_lookup(net, (xfrm_address_t *)&x->id.daddr,
spi, IPPROTO_IPV6, AF_INET6);
if (!t) {
t = ipcomp6_tunnel_create(x);
^ permalink raw reply
* [PATCH 3/4] netns xfrm: ipcomp support
From: Alexey Dobriyan @ 2010-01-25 20:38 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
net/ipv4/ipcomp.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -25,6 +25,7 @@
static void ipcomp4_err(struct sk_buff *skb, u32 info)
{
+ struct net *net = dev_net(skb->dev);
__be32 spi;
struct iphdr *iph = (struct iphdr *)skb->data;
struct ip_comp_hdr *ipch = (struct ip_comp_hdr *)(skb->data+(iph->ihl<<2));
@@ -35,7 +36,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
return;
spi = htonl(ntohs(ipch->cpi));
- x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr,
+ x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr,
spi, IPPROTO_COMP, AF_INET);
if (!x)
return;
@@ -47,9 +48,10 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
/* We always hold one tunnel user reference to indicate a tunnel */
static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
{
+ struct net *net = xs_net(x);
struct xfrm_state *t;
- t = xfrm_state_alloc(&init_net);
+ t = xfrm_state_alloc(net);
if (t == NULL)
goto out;
@@ -82,10 +84,11 @@ error:
*/
static int ipcomp_tunnel_attach(struct xfrm_state *x)
{
+ struct net *net = xs_net(x);
int err = 0;
struct xfrm_state *t;
- t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr.a4,
+ t = xfrm_state_lookup(net, (xfrm_address_t *)&x->id.daddr.a4,
x->props.saddr.a4, IPPROTO_IPIP, AF_INET);
if (!t) {
t = ipcomp_tunnel_create(x);
^ permalink raw reply
* [PATCH 2/4] netns xfrm: xfrm6_tunnel in netns
From: Alexey Dobriyan @ 2010-01-25 20:37 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert
I'm not sure about rcu stuff near kmem cache destruction:
* checks for non-empty hashes look bogus, they're done _before_
rcu_berrier()
* unregistering netns ops is done before kmem_cache destoy
(as it should), and unregistering involves rcu barriers by itself
So it looks nothing should be done.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
include/net/xfrm.h | 6 +-
net/ipv6/ipcomp6.c | 4 -
net/ipv6/xfrm6_tunnel.c | 140 ++++++++++++++++++++++++++++--------------------
3 files changed, 88 insertions(+), 62 deletions(-)
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1408,9 +1408,9 @@ extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
xfrm_address_t *saddr, u8 proto);
extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
-extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
-extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);
-extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);
+extern __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
+extern void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr);
+extern __be32 xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr);
extern int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb);
extern int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
extern int xfrm6_output(struct sk_buff *skb);
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -81,7 +81,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
goto out;
t->id.proto = IPPROTO_IPV6;
- t->id.spi = xfrm6_tunnel_alloc_spi((xfrm_address_t *)&x->props.saddr);
+ t->id.spi = xfrm6_tunnel_alloc_spi(&init_net, (xfrm_address_t *)&x->props.saddr);
if (!t->id.spi)
goto error;
@@ -112,7 +112,7 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x)
struct xfrm_state *t = NULL;
__be32 spi;
- spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr);
+ spi = xfrm6_tunnel_spi_lookup(&init_net, (xfrm_address_t *)&x->props.saddr);
if (spi)
t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr,
spi, IPPROTO_IPV6, AF_INET6);
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -30,6 +30,25 @@
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
#include <linux/mutex.h>
+#include <net/netns/generic.h>
+
+#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
+#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256
+
+#define XFRM6_TUNNEL_SPI_MIN 1
+#define XFRM6_TUNNEL_SPI_MAX 0xffffffff
+
+struct xfrm6_tunnel_net {
+ struct hlist_head spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
+ struct hlist_head spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
+ u32 spi;
+};
+
+static int xfrm6_tunnel_net_id __read_mostly;
+static inline struct xfrm6_tunnel_net *xfrm6_tunnel_pernet(struct net *net)
+{
+ return net_generic(net, xfrm6_tunnel_net_id);
+}
/*
* xfrm_tunnel_spi things are for allocating unique id ("spi")
@@ -46,19 +65,8 @@ struct xfrm6_tunnel_spi {
static DEFINE_SPINLOCK(xfrm6_tunnel_spi_lock);
-static u32 xfrm6_tunnel_spi;
-
-#define XFRM6_TUNNEL_SPI_MIN 1
-#define XFRM6_TUNNEL_SPI_MAX 0xffffffff
-
static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly;
-#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
-#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256
-
-static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
-static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
-
static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
{
unsigned h;
@@ -77,49 +85,30 @@ static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi)
}
-static int xfrm6_tunnel_spi_init(void)
+static int __init xfrm6_tunnel_spi_init(void)
{
- int i;
-
- xfrm6_tunnel_spi = 0;
xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
sizeof(struct xfrm6_tunnel_spi),
0, SLAB_HWCACHE_ALIGN,
NULL);
if (!xfrm6_tunnel_spi_kmem)
return -ENOMEM;
-
- for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
- INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byaddr[i]);
- for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++)
- INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byspi[i]);
return 0;
}
static void xfrm6_tunnel_spi_fini(void)
{
- int i;
-
- for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) {
- if (!hlist_empty(&xfrm6_tunnel_spi_byaddr[i]))
- return;
- }
- for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++) {
- if (!hlist_empty(&xfrm6_tunnel_spi_byspi[i]))
- return;
- }
- rcu_barrier();
kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
- xfrm6_tunnel_spi_kmem = NULL;
}
-static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
+static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr)
{
+ struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
struct xfrm6_tunnel_spi *x6spi;
struct hlist_node *pos;
hlist_for_each_entry_rcu(x6spi, pos,
- &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
+ &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
list_byaddr) {
if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0)
return x6spi;
@@ -128,13 +117,13 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
return NULL;
}
-__be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
+__be32 xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr)
{
struct xfrm6_tunnel_spi *x6spi;
u32 spi;
rcu_read_lock_bh();
- x6spi = __xfrm6_tunnel_spi_lookup(saddr);
+ x6spi = __xfrm6_tunnel_spi_lookup(net, saddr);
spi = x6spi ? x6spi->spi : 0;
rcu_read_unlock_bh();
return htonl(spi);
@@ -142,14 +131,15 @@ __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup);
-static int __xfrm6_tunnel_spi_check(u32 spi)
+static int __xfrm6_tunnel_spi_check(struct net *net, u32 spi)
{
+ struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
struct xfrm6_tunnel_spi *x6spi;
int index = xfrm6_tunnel_spi_hash_byspi(spi);
struct hlist_node *pos;
hlist_for_each_entry(x6spi, pos,
- &xfrm6_tunnel_spi_byspi[index],
+ &xfrm6_tn->spi_byspi[index],
list_byspi) {
if (x6spi->spi == spi)
return -1;
@@ -157,32 +147,33 @@ static int __xfrm6_tunnel_spi_check(u32 spi)
return index;
}
-static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
+static u32 __xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr)
{
+ struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
u32 spi;
struct xfrm6_tunnel_spi *x6spi;
int index;
- if (xfrm6_tunnel_spi < XFRM6_TUNNEL_SPI_MIN ||
- xfrm6_tunnel_spi >= XFRM6_TUNNEL_SPI_MAX)
- xfrm6_tunnel_spi = XFRM6_TUNNEL_SPI_MIN;
+ if (xfrm6_tn->spi < XFRM6_TUNNEL_SPI_MIN ||
+ xfrm6_tn->spi >= XFRM6_TUNNEL_SPI_MAX)
+ xfrm6_tn->spi = XFRM6_TUNNEL_SPI_MIN;
else
- xfrm6_tunnel_spi++;
+ xfrm6_tn->spi++;
- for (spi = xfrm6_tunnel_spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) {
- index = __xfrm6_tunnel_spi_check(spi);
+ for (spi = xfrm6_tn->spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) {
+ index = __xfrm6_tunnel_spi_check(net, spi);
if (index >= 0)
goto alloc_spi;
}
- for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tunnel_spi; spi++) {
- index = __xfrm6_tunnel_spi_check(spi);
+ for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tn->spi; spi++) {
+ index = __xfrm6_tunnel_spi_check(net, spi);
if (index >= 0)
goto alloc_spi;
}
spi = 0;
goto out;
alloc_spi:
- xfrm6_tunnel_spi = spi;
+ xfrm6_tn->spi = spi;
x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC);
if (!x6spi)
goto out;
@@ -192,26 +183,26 @@ alloc_spi:
x6spi->spi = spi;
atomic_set(&x6spi->refcnt, 1);
- hlist_add_head_rcu(&x6spi->list_byspi, &xfrm6_tunnel_spi_byspi[index]);
+ hlist_add_head_rcu(&x6spi->list_byspi, &xfrm6_tn->spi_byspi[index]);
index = xfrm6_tunnel_spi_hash_byaddr(saddr);
- hlist_add_head_rcu(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]);
+ hlist_add_head_rcu(&x6spi->list_byaddr, &xfrm6_tn->spi_byaddr[index]);
out:
return spi;
}
-__be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
+__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr)
{
struct xfrm6_tunnel_spi *x6spi;
u32 spi;
spin_lock_bh(&xfrm6_tunnel_spi_lock);
- x6spi = __xfrm6_tunnel_spi_lookup(saddr);
+ x6spi = __xfrm6_tunnel_spi_lookup(net, saddr);
if (x6spi) {
atomic_inc(&x6spi->refcnt);
spi = x6spi->spi;
} else
- spi = __xfrm6_tunnel_alloc_spi(saddr);
+ spi = __xfrm6_tunnel_alloc_spi(net, saddr);
spin_unlock_bh(&xfrm6_tunnel_spi_lock);
return htonl(spi);
@@ -225,15 +216,16 @@ static void x6spi_destroy_rcu(struct rcu_head *head)
container_of(head, struct xfrm6_tunnel_spi, rcu_head));
}
-void xfrm6_tunnel_free_spi(xfrm_address_t *saddr)
+void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr)
{
+ struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
struct xfrm6_tunnel_spi *x6spi;
struct hlist_node *pos, *n;
spin_lock_bh(&xfrm6_tunnel_spi_lock);
hlist_for_each_entry_safe(x6spi, pos, n,
- &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
+ &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
list_byaddr)
{
if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
@@ -263,10 +255,11 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm6_tunnel_rcv(struct sk_buff *skb)
{
+ struct net *net = dev_net(skb->dev);
struct ipv6hdr *iph = ipv6_hdr(skb);
__be32 spi;
- spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
+ spi = xfrm6_tunnel_spi_lookup(net, (xfrm_address_t *)&iph->saddr);
return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0;
}
@@ -326,7 +319,9 @@ static int xfrm6_tunnel_init_state(struct xfrm_state *x)
static void xfrm6_tunnel_destroy(struct xfrm_state *x)
{
- xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr);
+ struct net *net = xs_net(x);
+
+ xfrm6_tunnel_free_spi(net, (xfrm_address_t *)&x->props.saddr);
}
static const struct xfrm_type xfrm6_tunnel_type = {
@@ -351,6 +346,31 @@ static struct xfrm6_tunnel xfrm46_tunnel_handler = {
.priority = 2,
};
+static int __net_init xfrm6_tunnel_net_init(struct net *net)
+{
+ struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
+ unsigned int i;
+
+ for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
+ INIT_HLIST_HEAD(&xfrm6_tn->spi_byaddr[i]);
+ for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++)
+ INIT_HLIST_HEAD(&xfrm6_tn->spi_byspi[i]);
+ xfrm6_tn->spi = 0;
+
+ return 0;
+}
+
+static void __net_exit xfrm6_tunnel_net_exit(struct net *net)
+{
+}
+
+static struct pernet_operations xfrm6_tunnel_net_ops = {
+ .init = xfrm6_tunnel_net_init,
+ .exit = xfrm6_tunnel_net_exit,
+ .id = &xfrm6_tunnel_net_id,
+ .size = sizeof(struct xfrm6_tunnel_net),
+};
+
static int __init xfrm6_tunnel_init(void)
{
int rv;
@@ -367,8 +387,13 @@ static int __init xfrm6_tunnel_init(void)
rv = xfrm6_tunnel_spi_init();
if (rv < 0)
goto dereg46;
+ rv = register_pernet_subsys(&xfrm6_tunnel_net_ops);
+ if (rv < 0)
+ goto deregspi;
return 0;
+deregspi:
+ xfrm6_tunnel_spi_fini();
dereg46:
xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
dereg6:
@@ -381,6 +406,7 @@ err:
static void __exit xfrm6_tunnel_fini(void)
{
+ unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
xfrm6_tunnel_spi_fini();
xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
^ permalink raw reply
* [PATCH 1/4] netns xfrm: fixup xfrm6_tunnel error propagation
From: Alexey Dobriyan @ 2010-01-25 20:28 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
net/ipv6/xfrm6_tunnel.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -353,13 +353,19 @@ static struct xfrm6_tunnel xfrm46_tunnel_handler = {
static int __init xfrm6_tunnel_init(void)
{
- if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0)
+ int rv;
+
+ rv = xfrm_register_type(&xfrm6_tunnel_type, AF_INET6);
+ if (rv < 0)
goto err;
- if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6))
+ rv = xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6);
+ if (rv < 0)
goto unreg;
- if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET))
+ rv = xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET);
+ if (rv < 0)
goto dereg6;
- if (xfrm6_tunnel_spi_init() < 0)
+ rv = xfrm6_tunnel_spi_init();
+ if (rv < 0)
goto dereg46;
return 0;
@@ -370,7 +376,7 @@ dereg6:
unreg:
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
err:
- return -EAGAIN;
+ return rv;
}
static void __exit xfrm6_tunnel_fini(void)
^ permalink raw reply
* Re: [PATCH 2/2] sfc: Use fixed-size buffers for MCDI NVRAM requests
From: Ben Hutchings @ 2010-01-25 19:41 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
In-Reply-To: <1264447852.2793.4.camel@achroite.uk.solarflarecom.com>
On Mon, 2010-01-25 at 19:30 +0000, Ben Hutchings wrote:
> The low-level MCDI code always uses 32-bit MMIO operations, and
> callers must pad input and output buffers to multiples of 4 bytes.
> The MCDI NVRAM functions are not doing this. Also, their buffers are
> declared as variable-length arrays with no explicit maximum length.
>
> Switch to a fixed buffer size based on the chunk size used by the
> MTD driver (which is a multiple of 4).
This is also meant for net-2.6. Reading or writing lengths that are not
multiples of 4 will BUG() while holding the device's MCDI lock, which
will lead to a system hang sooner or later.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH 1/2] sfc: Add workspace for GMAC bug workaround to MCDI MAC_STATS buffer
From: Ben Hutchings @ 2010-01-25 19:36 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
In-Reply-To: <1264447680.2793.0.camel@achroite.uk.solarflarecom.com>
On Mon, 2010-01-25 at 19:28 +0000, Ben Hutchings wrote:
> From: Guido Barzini <gbarzini@solarflare.com>
>
> Due to a hardware bug in the SFC9000 family, the firmware must
> transfer raw GMAC statistics to host memory before aggregating them
> into the cooked (speed-independent) MAC statistics. Extend the stats
> buffer to support this.
>
> The length of the buffer is explicit in the MAC_STATS command, so this
> change is backward-compatible on both sides.
David,
I forgot to note that this is meant for net-2.6.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [PATCH 2/2] sfc: Use fixed-size buffers for MCDI NVRAM requests
From: Ben Hutchings @ 2010-01-25 19:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
The low-level MCDI code always uses 32-bit MMIO operations, and
callers must pad input and output buffers to multiples of 4 bytes.
The MCDI NVRAM functions are not doing this. Also, their buffers are
declared as variable-length arrays with no explicit maximum length.
Switch to a fixed buffer size based on the chunk size used by the
MTD driver (which is a multiple of 4).
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/mcdi.c | 7 ++++---
drivers/net/sfc/mcdi.h | 1 +
drivers/net/sfc/mtd.c | 5 ++---
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c
index 0d4eba7..9f035b9 100644
--- a/drivers/net/sfc/mcdi.c
+++ b/drivers/net/sfc/mcdi.c
@@ -804,7 +804,7 @@ int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
loff_t offset, u8 *buffer, size_t length)
{
u8 inbuf[MC_CMD_NVRAM_READ_IN_LEN];
- u8 outbuf[MC_CMD_NVRAM_READ_OUT_LEN(length)];
+ u8 outbuf[MC_CMD_NVRAM_READ_OUT_LEN(EFX_MCDI_NVRAM_LEN_MAX)];
size_t outlen;
int rc;
@@ -828,7 +828,7 @@ fail:
int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
loff_t offset, const u8 *buffer, size_t length)
{
- u8 inbuf[MC_CMD_NVRAM_WRITE_IN_LEN(length)];
+ u8 inbuf[MC_CMD_NVRAM_WRITE_IN_LEN(EFX_MCDI_NVRAM_LEN_MAX)];
int rc;
MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_TYPE, type);
@@ -838,7 +838,8 @@ int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
BUILD_BUG_ON(MC_CMD_NVRAM_WRITE_OUT_LEN != 0);
- rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf, sizeof(inbuf),
+ rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf,
+ ALIGN(MC_CMD_NVRAM_WRITE_IN_LEN(length), 4),
NULL, 0, NULL);
if (rc)
goto fail;
diff --git a/drivers/net/sfc/mcdi.h b/drivers/net/sfc/mcdi.h
index de91672..10ce98f 100644
--- a/drivers/net/sfc/mcdi.h
+++ b/drivers/net/sfc/mcdi.h
@@ -111,6 +111,7 @@ extern int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
extern int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
loff_t offset, const u8 *buffer,
size_t length);
+#define EFX_MCDI_NVRAM_LEN_MAX 128
extern int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type,
loff_t offset, size_t length);
extern int efx_mcdi_nvram_update_finish(struct efx_nic *efx,
diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c
index 3a46452..407bbad 100644
--- a/drivers/net/sfc/mtd.c
+++ b/drivers/net/sfc/mtd.c
@@ -23,7 +23,6 @@
#include "mcdi_pcol.h"
#define EFX_SPI_VERIFY_BUF_LEN 16
-#define EFX_MCDI_CHUNK_LEN 128
struct efx_mtd_partition {
struct mtd_info mtd;
@@ -428,7 +427,7 @@ static int siena_mtd_read(struct mtd_info *mtd, loff_t start,
int rc = 0;
while (offset < end) {
- chunk = min_t(size_t, end - offset, EFX_MCDI_CHUNK_LEN);
+ chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
rc = efx_mcdi_nvram_read(efx, part->mcdi.nvram_type, offset,
buffer, chunk);
if (rc)
@@ -491,7 +490,7 @@ static int siena_mtd_write(struct mtd_info *mtd, loff_t start,
}
while (offset < end) {
- chunk = min_t(size_t, end - offset, EFX_MCDI_CHUNK_LEN);
+ chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
rc = efx_mcdi_nvram_write(efx, part->mcdi.nvram_type, offset,
buffer, chunk);
if (rc)
--
1.5.5
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 1/2] sfc: Add workspace for GMAC bug workaround to MCDI MAC_STATS buffer
From: Ben Hutchings @ 2010-01-25 19:28 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
From: Guido Barzini <gbarzini@solarflare.com>
Due to a hardware bug in the SFC9000 family, the firmware must
transfer raw GMAC statistics to host memory before aggregating them
into the cooked (speed-independent) MAC statistics. Extend the stats
buffer to support this.
The length of the buffer is explicit in the MAC_STATS command, so this
change is backward-compatible on both sides.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/mcdi_pcol.h | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/net/sfc/mcdi_pcol.h b/drivers/net/sfc/mcdi_pcol.h
index 2a85360..73e71f4 100644
--- a/drivers/net/sfc/mcdi_pcol.h
+++ b/drivers/net/sfc/mcdi_pcol.h
@@ -1090,8 +1090,10 @@
#define MC_CMD_MAC_RX_LANES01_DISP_ERR 57
#define MC_CMD_MAC_RX_LANES23_DISP_ERR 58
#define MC_CMD_MAC_RX_MATCH_FAULT 59
+#define MC_CMD_GMAC_DMABUF_START 64
+#define MC_CMD_GMAC_DMABUF_END 95
/* Insert new members here. */
-#define MC_CMD_MAC_GENERATION_END 60
+#define MC_CMD_MAC_GENERATION_END 96
#define MC_CMD_MAC_NSTATS (MC_CMD_MAC_GENERATION_END+1)
/* MC_CMD_MAC_STATS:
--
1.5.5
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* Re: [PATCH 01/25 v2] mlx4_core: identify function as pf or vf
From: Roland Dreier @ 2010-01-25 19:20 UTC (permalink / raw)
To: Yevgeny Petrilin
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
liranl-VPRAkNaXOzVS1MOuV/RT9w, tziporet-VPRAkNaXOzVS1MOuV/RT9w
In-Reply-To: <4AF3930E.90904-VPRAkNaXOzVS1MOuV/RT9w@public.gmane.org>
> enum {
> MLX4_FLAG_MSI_X = 1 << 0,
> MLX4_FLAG_OLD_PORT_CMDS = 1 << 1,
> + MLX4_FLAG_MASTER = 1 << 2,
> + MLX4_FLAG_SLAVE = 1 << 3,
> + MLX4_FLAG_SRIOV = 1 << 4,
> };
I'm a bit confused by these flags. As far as I can tell, the SRIOV flag
will be set if and only if MASTER is set too... so in other words we
might as well just have the MASTER and SLAVE flags and not have the
SRIOV flag at all.
- R.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 2.6.33 1/3] net: Micrel KSZ8841/2 PCI Ethernet driver
From: Jens Rottmann @ 2010-01-25 18:14 UTC (permalink / raw)
To: Tristram Ha; +Cc: netdev
In ksz884x.c: read_other_addr(struct ksz_hw *hw)
"u16 data[3]" instead of "u16 data[4]" is sufficient.
And when checking if the 2nd MAC is actually stored in EEPROM or if it's only
all empty (only FF) you overlooked that you're doing it wordwise, so you'll
have to check "data[0] != 0xffff" instead of "data[0] != 0xff".
Best regards,
Jens Rottmann
^ permalink raw reply
* Re: [PATCH] IPv6: Update documentation for better built-in help with params
From: Brian Haley @ 2010-01-25 17:28 UTC (permalink / raw)
To: David Miller; +Cc: greg, nhorman, netdev
In-Reply-To: <20100122.183223.197255353.davem@davemloft.net>
David Miller wrote:
> From: Brian Haley <brian.haley@hp.com>
> Date: Fri, 22 Jan 2010 15:24:49 -0500
>
>> Update IPv6 documentation to describe how to set parameters when it's
>> built-into the kernel. Reported by <greg@enjellic.com>.
>>
>> Signed-off-by: Brian Haley <brian.haley@hp.com>
>
> So are you going to also add a mention of this fact to every single
> place in the documentation that talks about some arbitrary module
> option?
>
> That doesn't make any sense, and neither does this patch.
>
> It's better to make it more apparent that module options can
> be set on the kernel command line when something is compiled
> statically into the kernel.
>
> That way it only needs to be explained in one place, not in
> several.
I guess Documentation/kernel-parameters.txt is where such things
live, can I send you a patch for that or does it need to go
through someone else?
-Brian
^ permalink raw reply
* Re: [PATCH 1/1 V4] net: Add Aeroflex Gaisler 10/100/1G Ethernet MAC driver
From: Stephen Hemminger @ 2010-01-25 16:39 UTC (permalink / raw)
To: Kristoffer Glembo; +Cc: netdev, davem, Kristoffer Glembo
In-Reply-To: <1264417272-3800-2-git-send-email-kristoffer@gaisler.com>
On Mon, 25 Jan 2010 12:01:12 +0100
Kristoffer Glembo <kristoffer@gaisler.com> wrote:
> Adds device driver for Aeroflex Gaisler 10/100 and 10/100/1G Ethernet MAC IP cores.
>
> Signed-off-by: Kristoffer Glembo <kristoffer@gaisler.com>
Please consider adding ethtool support for things like settings (speed, duplex);
info, get_link, and checksum offload control
--
^ permalink raw reply
* Re: [PATCH 1/1 V4] net: Add Aeroflex Gaisler 10/100/1G Ethernet MAC driver
From: Stephen Hemminger @ 2010-01-25 16:37 UTC (permalink / raw)
To: Kristoffer Glembo; +Cc: netdev, davem, Kristoffer Glembo
In-Reply-To: <1264417272-3800-2-git-send-email-kristoffer@gaisler.com>
On Mon, 25 Jan 2010 12:01:12 +0100
Kristoffer Glembo <kristoffer@gaisler.com> wrote:
> +/* Wait for a register change with a timeout, jiffies used has time reference */
> +#define wait_loop(wait_statement, timeout, label_on_timeout, arg_on_timeout) \
> + { \
> + unsigned long _timeout = jiffies + HZ/100*timeout; \
> + while (wait_statement) { \
> + if (time_after(jiffies, _timeout)) { \
> + arg_on_timeout; \
> +goto label_on_timeout; \
> + } \
> + } \
> + }
Ugly macro used with same arguments, just write a single function
--
^ permalink raw reply
* Re: [PATCH 1/1 V4] net: Add Aeroflex Gaisler 10/100/1G Ethernet MAC driver
From: Stephen Hemminger @ 2010-01-25 16:36 UTC (permalink / raw)
To: Kristoffer Glembo; +Cc: netdev, davem, Kristoffer Glembo
In-Reply-To: <1264417272-3800-2-git-send-email-kristoffer@gaisler.com>
On Mon, 25 Jan 2010 12:01:12 +0100
Kristoffer Glembo <kristoffer@gaisler.com> wrote:
> +
> +static struct net_device_stats *greth_get_stats(struct net_device *dev)
> +{
> + struct greth_private *greth = netdev_priv(dev);
> + return &greth->stats;
> +}
If you used dev->stats instead of own private structure, then you
could also avoid having this handle. The default function for
.ndo_get_stats is to return dev->stats.
--
^ permalink raw reply
* Re: [PATCH 1/1 V4] net: Add Aeroflex Gaisler 10/100/1G Ethernet MAC driver
From: Stephen Hemminger @ 2010-01-25 16:33 UTC (permalink / raw)
To: Kristoffer Glembo; +Cc: netdev, davem, Kristoffer Glembo
In-Reply-To: <1264417272-3800-2-git-send-email-kristoffer@gaisler.com>
On Mon, 25 Jan 2010 12:01:12 +0100
Kristoffer Glembo <kristoffer@gaisler.com> wrote:
> +static int greth_start_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> + struct greth_private *greth = netdev_priv(dev);
> + struct greth_bd *bdp;
> + int err = NETDEV_TX_OK;
> + u32 status, dma_addr;
> +
> + bdp = greth->tx_bd_base + greth->tx_next;
> +
> + if (unlikely(greth->tx_free <= 0)) {
> + netif_stop_queue(dev);
> + err = NETDEV_TX_BUSY;
> + goto out;
> + }
...
> +
> +out:
> + dev_kfree_skb(skb);
> + return err;
> +}
> +
Wrong, if device is busy; then skb must NOT be freed.
--
^ permalink raw reply
* Re: [PATCH 1/1 V4] net: Add Aeroflex Gaisler 10/100/1G Ethernet MAC driver
From: Stephen Hemminger @ 2010-01-25 16:31 UTC (permalink / raw)
To: Kristoffer Glembo; +Cc: netdev, davem, Kristoffer Glembo
In-Reply-To: <1264417272-3800-2-git-send-email-kristoffer@gaisler.com>
On Mon, 25 Jan 2010 12:01:12 +0100
Kristoffer Glembo <kristoffer@gaisler.com> wrote:
> +/* Accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
> +static int macaddr[6];
> +module_param_array(macaddr, int, NULL, 0);
> +MODULE_PARM_DESC(macaddr, "GRETH Ethernet MAC address");
Don't you want an array of uchar here not int?
--
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox