* Re: DMA-API warning from sunhme - unchecked dma_map_single error
From: David Miller @ 2014-10-31 17:43 UTC (permalink / raw)
To: mroos; +Cc: netdev, sparclinux
In-Reply-To: <alpine.SOC.1.00.1311291036050.3807@math.ut.ee>
From: Meelis Roos <mroos@linux.ee>
Date: Fri, 29 Nov 2013 10:40:40 +0200 (EET)
> It seems to be correct warning - dma_map_single is used unchecked in
> sunhme.c. I can try fixing it - the error handling will be the only
> problem. Is it considered worthwile?
Can you test this patch?
====================
sunhme: Add DMA mapping error checks.
Reported-by: Meelis Roos <mroos@linux.ee>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/sun/sunhme.c | 62 +++++++++++++++++++++++++++++++++++----
1 file changed, 57 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index 72c8525..9c01480 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -1262,6 +1262,7 @@ static void happy_meal_init_rings(struct happy_meal *hp)
HMD(("init rxring, "));
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
+ u32 mapping;
skb = happy_meal_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
if (!skb) {
@@ -1272,10 +1273,16 @@ static void happy_meal_init_rings(struct happy_meal *hp)
/* Because we reserve afterwards. */
skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
+ mapping = dma_map_single(hp->dma_dev, skb->data, RX_BUF_ALLOC_SIZE,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(hp->dma_dev, mapping)) {
+ dev_kfree_skb_any(skb);
+ hme_write_rxd(hp, &hb->happy_meal_rxd[i], 0, 0);
+ continue;
+ }
hme_write_rxd(hp, &hb->happy_meal_rxd[i],
(RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16)),
- dma_map_single(hp->dma_dev, skb->data, RX_BUF_ALLOC_SIZE,
- DMA_FROM_DEVICE));
+ mapping);
skb_reserve(skb, RX_OFFSET);
}
@@ -2020,6 +2027,7 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
skb = hp->rx_skbs[elem];
if (len > RX_COPY_THRESHOLD) {
struct sk_buff *new_skb;
+ u32 mapping;
/* Now refill the entry, if we can. */
new_skb = happy_meal_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
@@ -2027,13 +2035,21 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
drops++;
goto drop_it;
}
+ skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
+ mapping = dma_map_single(hp->dma_dev, new_skb->data,
+ RX_BUF_ALLOC_SIZE,
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(hp->dma_dev, mapping))) {
+ dev_kfree_skb_any(new_skb);
+ drops++;
+ goto drop_it;
+ }
+
dma_unmap_single(hp->dma_dev, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROM_DEVICE);
hp->rx_skbs[elem] = new_skb;
- skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
hme_write_rxd(hp, this,
(RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
- dma_map_single(hp->dma_dev, new_skb->data, RX_BUF_ALLOC_SIZE,
- DMA_FROM_DEVICE));
+ mapping);
skb_reserve(new_skb, RX_OFFSET);
/* Trim the original skb for the netif. */
@@ -2248,6 +2264,25 @@ static void happy_meal_tx_timeout(struct net_device *dev)
netif_wake_queue(dev);
}
+static void unmap_partial_tx_skb(struct happy_meal *hp, u32 first_mapping,
+ u32 first_len, u32 first_entry, u32 entry)
+{
+ struct happy_meal_txd *txbase = &hp->happy_block->happy_meal_txd[0];
+
+ dma_unmap_single(hp->dma_dev, first_mapping, first_len, DMA_TO_DEVICE);
+
+ first_entry = NEXT_TX(first_entry);
+ while (first_entry != entry) {
+ struct happy_meal_txd *this = &txbase[first_entry];
+ u32 addr, len;
+
+ addr = hme_read_desc32(hp, &this->tx_addr);
+ len = hme_read_desc32(hp, &this->tx_flags);
+ len &= TXFLAG_SIZE;
+ dma_unmap_page(hp->dma_dev, addr, len, DMA_TO_DEVICE);
+ }
+}
+
static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
@@ -2284,6 +2319,8 @@ static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb,
len = skb->len;
mapping = dma_map_single(hp->dma_dev, skb->data, len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(hp->dma_dev, mapping)))
+ goto out_dma_error;
tx_flags |= (TXFLAG_SOP | TXFLAG_EOP);
hme_write_txd(hp, &hp->happy_block->happy_meal_txd[entry],
(tx_flags | (len & TXFLAG_SIZE)),
@@ -2299,6 +2336,8 @@ static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb,
first_len = skb_headlen(skb);
first_mapping = dma_map_single(hp->dma_dev, skb->data, first_len,
DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(hp->dma_dev, first_mapping)))
+ goto out_dma_error;
entry = NEXT_TX(entry);
for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
@@ -2308,6 +2347,11 @@ static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb,
len = skb_frag_size(this_frag);
mapping = skb_frag_dma_map(hp->dma_dev, this_frag,
0, len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(hp->dma_dev, mapping))) {
+ unmap_partial_tx_skb(hp, first_mapping, first_len,
+ first_entry, entry);
+ goto out_dma_error;
+ }
this_txflags = tx_flags;
if (frag == skb_shinfo(skb)->nr_frags - 1)
this_txflags |= TXFLAG_EOP;
@@ -2333,6 +2377,14 @@ static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb,
tx_add_log(hp, TXLOG_ACTION_TXMIT, 0);
return NETDEV_TX_OK;
+
+out_dma_error:
+ hp->tx_skbs[hp->tx_new] = NULL;
+ spin_unlock_irq(&hp->happy_lock);
+
+ dev_kfree_skb_any(skb);
+ dev->stats.tx_dropped++;
+ return NETDEV_TX_OK;
}
static struct net_device_stats *happy_meal_get_stats(struct net_device *dev)
--
1.9.3
^ permalink raw reply related
* Re: [PATCH net] r8152: stop submitting intr for -EPROTO
From: David Miller @ 2014-10-31 17:56 UTC (permalink / raw)
To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb
In-Reply-To: <1394712342-15778-74-Taiwan-albertk@realtek.com>
From: Hayes Wang <hayeswang@realtek.com>
Date: Fri, 31 Oct 2014 13:35:57 +0800
> For Renesas USB 3.0 host controller, when unplugging the usb hub which
> has the RTL8153 plugged, the driver would get -EPROTO for interrupt
> transfer. There is high probability to get the information of "HC died;
> cleaning up", if the driver continues to submit the interrupt transfer
> before the disconnect() is called.
...
> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Applied, thanks.
^ permalink raw reply
* vxlan: error handling and error messages during vxlan_init
From: Marcelo Ricardo Leitner @ 2014-10-31 18:11 UTC (permalink / raw)
To: stephen, pshelar; +Cc: netdev
Hi Stephen, Pravin,
Before Stephen's commit 1c51a9159ddefa5119724a4c7da3fd3ef44b68d5 (vxlan: fix
race caused by dropping rtnl_unlock), if we failed to create the UDP socket
for any reason, for example, the user would be informed right away. After that
commit, the only option is to delete the vxlan and create it again, right?
Because by simply calling ip link set vxlanX up is not enough:
/* Setup stats when device is created */
static int vxlan_init(struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
struct vxlan_sock *vs;
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
if (!dev->tstats)
return -ENOMEM;
spin_lock(&vn->sock_lock);
vs = vxlan_find_sock(vxlan->net, (vxlan->flags & VXLAN_F_IPV6) ? AF_INET6
: AF_INET, vxlan->dst_port);
if (vs) {
/* If we have a socket with same port already, reuse it */
atomic_inc(&vs->refcnt);
vxlan_vs_add_dev(vs, vxlan);
} else {
/* otherwise make new socket outside of RTNL */
dev_hold(dev);
queue_work(vxlan_wq, &vxlan->sock_work); <--
}
spin_unlock(&vn->sock_lock);
return 0;
}
Error is just ignored:
/* Scheduled at device creation to bind to a socket */
static void vxlan_sock_work(struct work_struct *work)
{
struct vxlan_dev *vxlan = container_of(work, struct vxlan_dev, sock_work);
struct net *net = vxlan->net;
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
__be16 port = vxlan->dst_port;
struct vxlan_sock *nvs;
nvs = vxlan_sock_add(net, port, vxlan_rcv, NULL, false, vxlan->flags);
spin_lock(&vn->sock_lock);
if (!IS_ERR(nvs))
vxlan_vs_add_dev(nvs, vxlan);
spin_unlock(&vn->sock_lock);
dev_put(vxlan->dev);
}
And we can't bring it up:
/* Start ageing timer and join group when device is brought up */
static int vxlan_open(struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_sock *vs = vxlan->vn_sock;
/* socket hasn't been created */
if (!vs)
return -ENOTCONN; <---
And making this to retry the initialization doesn't seem a good idea.
Can we improve that error handling, somehow? As far as I could track, VXLAN is
the only one that currently defers some initialization code during ndo_init.
Together with that, that initial commit did put some good error messages on
this part of the code, like:
+ nvs = vxlan_socket_create(net, port);
+ if (IS_ERR(nvs)) {
+ netdev_err(vxlan->dev, "Can not create UDP socket, %ld\n",
+ PTR_ERR(nvs));
+ goto out;
+ }
But Pravin's 9c2e24e16fbccf6cc1102442acc4a629f79615a7 commit removed them all.
The only error message that is currently available is:
[root@localhost ~]# ip link set vxlan7 up
RTNETLINK answers: Transport endpoint is not connected
Nothing else is logged, dmesg or anywhere. (The actual error on this case was
that it failed to create the UDP socket because the port was already in use..)
May we put them back? :) doesn't seem it would hurt OVS..
Thanks,
Marcelo
^ permalink raw reply
* [PATCH 1/2] staging: lustre: lnet: lnet: do not initialise statics to 0 or NULL
From: Balavasu @ 2014-10-31 18:18 UTC (permalink / raw)
To: netdev, linux-kernel; +Cc: greg, andreas.dilger, oleg.drokin
This patch fixes the checkpatch.pl issue
Error: do not initialise statics to 0 or NULL for time
Signed-off-by: Balavasu <kp.balavasu@gmail.com>
---
drivers/staging/lustre/lnet/lnet/do not instalise 0 | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c
index b5b8fb5..cdeb246 100644
--- a/drivers/staging/lustre/lnet/lnet/router.c
+++ b/drivers/staging/lustre/lnet/lnet/router.c
@@ -46,7 +46,7 @@ MODULE_PARM_DESC(small_router_buffers, "# of small (1 page) messages to buffer i
static int large_router_buffers;
module_param(large_router_buffers, int, 0444);
MODULE_PARM_DESC(large_router_buffers, "# of large messages to buffer in the router");
-static int peer_buffer_credits = 0;
+static int peer_buffer_credits;
module_param(peer_buffer_credits, int, 0444);
MODULE_PARM_DESC(peer_buffer_credits, "# router buffer credits per peer");
@@ -80,7 +80,7 @@ lnet_peer_buffer_credits(lnet_ni_t *ni)
#endif
-static int check_routers_before_use = 0;
+static int check_routers_before_use;
module_param(check_routers_before_use, int, 0444);
MODULE_PARM_DESC(check_routers_before_use, "Assume routers are down and ping them before use");
@@ -245,7 +245,7 @@ lnet_find_net_locked (__u32 net)
static void lnet_shuffle_seed(void)
{
- static int seeded = 0;
+ static int seeded;
int lnd_type, seed[2];
struct timeval tv;
lnet_ni_t *ni;
@@ -1584,8 +1584,8 @@ lnet_notify (lnet_ni_t *ni, lnet_nid_t nid, int alive, unsigned long when)
void
lnet_router_checker (void)
{
- static time_t last = 0;
- static int running = 0;
+ static time_t last;
+ static int running;
time_t now = get_seconds();
int interval = now - last;
--
1.9.1
^ permalink raw reply related
* [PATCH 2/2] staging: lustre: lnet: lnet: trailing statements should be on next line
From: Balavasu @ 2014-10-31 18:20 UTC (permalink / raw)
To: netdev, linux-kernel; +Cc: greg, andreas.dilger, oleg.drokin
This patch fixes the checkpatch.pl issue
Error: trailing statements should be on next line
Signed-off-by: Balavasu <kp.balavasu@gmail.com>
---
drivers/staging/lustre/lnet/lnet/router.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c
index cdeb246..0f569a0 100644
--- a/drivers/staging/lustre/lnet/lnet/router.c
+++ b/drivers/staging/lustre/lnet/lnet/router.c
@@ -1670,13 +1670,16 @@ lnet_get_tunables (void)
char *s;
s = getenv("LNET_ROUTER_PING_TIMEOUT");
- if (s != NULL) router_ping_timeout = atoi(s);
+ if (s != NULL)
+ router_ping_timeout = atoi(s);
s = getenv("LNET_LIVE_ROUTER_CHECK_INTERVAL");
- if (s != NULL) live_router_check_interval = atoi(s);
+ if (s != NULL)
+ live_router_check_interval = atoi(s);
s = getenv("LNET_DEAD_ROUTER_CHECK_INTERVAL");
- if (s != NULL) dead_router_check_interval = atoi(s);
+ if (s != NULL)
+ dead_router_check_interval = atoi(s);
/* This replaces old lnd_notify mechanism */
check_routers_before_use = 1;
--
1.9.1
^ permalink raw reply related
* [PATCH net-next] bonding: add bond_tx_drop() helper
From: Eric Dumazet @ 2014-10-31 18:47 UTC (permalink / raw)
To: David Miller
Cc: netdev, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
Mahesh Bandewar
From: Eric Dumazet <edumazet@google.com>
Because bonding stats are usually sum of slave stats, it was
not easy to account for tx drops at bonding layer.
We can use dev->tx_dropped for this, as this counter is later
added to the device stats (in dev_get_stats())
This extends the idea we had in commit ee6377147409a ("bonding: Simplify
the xmit function for modes that use xmit_hash") for bond_3ad_xor_xmit()
to other bonding modes.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Mahesh Bandewar <maheshb@google.com>
---
drivers/net/bonding/bond_alb.c | 2 +-
drivers/net/bonding/bond_main.c | 15 +++++++--------
drivers/net/bonding/bonding.h | 6 ++++++
3 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index d2eadab787c55d8fc0f361755409a880d64abfb3..baa58e79256a8b804e6ab683af6665f0730b86de 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1326,7 +1326,7 @@ static int bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond,
}
/* no suitable interface, frame not sent */
- dev_kfree_skb_any(skb);
+ bond_tx_drop(bond->dev, skb);
out:
return NETDEV_TX_OK;
}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c9ac06cfe6b7b3a8f62568b70a6ad6d7ca9b44d0..c7520082fb0d7bfbc34ac00b4f4186a30197ad74 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3522,7 +3522,7 @@ static void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int sl
}
}
/* no slave that can tx has been found */
- dev_kfree_skb_any(skb);
+ bond_tx_drop(bond->dev, skb);
}
/**
@@ -3584,7 +3584,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
slave_id = bond_rr_gen_slave_id(bond);
bond_xmit_slave_id(bond, skb, slave_id % slave_cnt);
} else {
- dev_kfree_skb_any(skb);
+ bond_tx_drop(bond_dev, skb);
}
}
@@ -3603,7 +3603,7 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
if (slave)
bond_dev_queue_xmit(bond, skb, slave->dev);
else
- dev_kfree_skb_any(skb);
+ bond_tx_drop(bond_dev, skb);
return NETDEV_TX_OK;
}
@@ -3747,8 +3747,7 @@ int bond_3ad_xor_xmit(struct sk_buff *skb, struct net_device *dev)
slave = slaves->arr[bond_xmit_hash(bond, skb) % count];
bond_dev_queue_xmit(bond, skb, slave->dev);
} else {
- dev_kfree_skb_any(skb);
- atomic_long_inc(&dev->tx_dropped);
+ bond_tx_drop(dev, skb);
}
return NETDEV_TX_OK;
@@ -3778,7 +3777,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
if (slave && bond_slave_is_up(slave) && slave->link == BOND_LINK_UP)
bond_dev_queue_xmit(bond, skb, slave->dev);
else
- dev_kfree_skb_any(skb);
+ bond_tx_drop(bond_dev, skb);
return NETDEV_TX_OK;
}
@@ -3858,7 +3857,7 @@ static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev
/* Should never happen, mode already checked */
netdev_err(dev, "Unknown bonding mode %d\n", BOND_MODE(bond));
WARN_ON_ONCE(1);
- dev_kfree_skb_any(skb);
+ bond_tx_drop(dev, skb);
return NETDEV_TX_OK;
}
}
@@ -3878,7 +3877,7 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (bond_has_slaves(bond))
ret = __bond_start_xmit(skb, dev);
else
- dev_kfree_skb_any(skb);
+ bond_tx_drop(dev, skb);
rcu_read_unlock();
return ret;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 10920f0686e2f0222203359751581d1b728c6617..bfb0b51c081a27fbbbe64deda058f70860aac49d 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -645,4 +645,10 @@ extern struct bond_parm_tbl ad_select_tbl[];
/* exported from bond_netlink.c */
extern struct rtnl_link_ops bond_link_ops;
+static inline void bond_tx_drop(struct net_device *dev, struct sk_buff *skb)
+{
+ atomic_long_inc(&dev->tx_dropped);
+ dev_kfree_skb_any(skb);
+}
+
#endif /* _LINUX_BONDING_H */
^ permalink raw reply related
* Re: [PATCH net-next v4 0/4] netns: allow to identify peer netns
From: Eric W. Biederman @ 2014-10-31 19:14 UTC (permalink / raw)
To: nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, luto-kltTT9wpgjJwATOyAt5JVQ,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
cwang-xCSkyg8dI+0RB7SZvlqPiA, linux-api-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <54535B00.5090708-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
> Le 30/10/2014 19:41, Eric W. Biederman a écrit :
>> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>>
>>> The goal of this serie is to be able to multicast netlink messages with an
>>> attribute that identify a peer netns.
>>> This is needed by the userland to interpret some informations contained in
>>> netlink messages (like IFLA_LINK value, but also some other attributes in case
>>> of x-netns netdevice (see also
>>> http://thread.gmane.org/gmane.linux.network/315933/focus=316064 and
>>> http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239)).
>>>
>>> Ids of peer netns are set by userland via a new genl messages. These ids are
>>> stored per netns and are local (ie only valid in the netns where they are set).
>>> To avoid allocating an int for each peer netns, I use idr_for_each() to retrieve
>>> the id of a peer netns. Note that it will be possible to add a table (struct net
>>> -> id) later to optimize this lookup if needed.
>>>
>>> Patch 1/4 introduces the netlink API mechanism to set and get these ids.
>>> Patch 2/4 and 3/4 implements an example of how to use these ids in rtnetlink
>>> messages. And patch 4/4 shows that the netlink messages can be symetric between
>>> a GET and a SET.
>>>
>>> iproute2 patches are available, I can send them on demand.
>>
>> A quick reply. I think this patchset is in the right general direction.
>> There are some oddball details that seem odd/awkward to me such as using
>> genetlink instead of rtnetlink to get and set the ids, and not having
>> ids if they are not set (that feels like a maintenance/usability challenge).
> No problem to use rtnetlink, in fact, I hesitated.
>
> For the second point, I'm not sure to follow you: how to have an id, which will
> not break migration, without asking the user to set it?
We have that situtation with ifindex already. Basically the thought is
to allow an id to be set, but also allow an id to be auto-generated if
we use an namespace without an id being set.
My gut says if we can figure that out we will have an interface with
much more utility.
> Note that if the user does not provide an id, you still have a magic value to
> say "it's a peer netns but we don't know which one".
That is certainly an improvement in clarity over where we are today.
>> I would like to give your patches a deep review, but I won't be able to
>> do that for a couple of weeks. I am deep in the process of moving,
>> and will be mostly offline until about the Nov 11th.
>
> No problem, I will wait.
> I would be great to get a final version for the 3.19 ;-)
Eric
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers
^ permalink raw reply
* Re: [PATCH net-next] bonding: add bond_tx_drop() helper
From: Nikolay Aleksandrov @ 2014-10-31 19:25 UTC (permalink / raw)
To: Eric Dumazet, David Miller
Cc: netdev, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
Mahesh Bandewar
In-Reply-To: <1414781274.27538.32.camel@edumazet-glaptop2.roam.corp.google.com>
On 10/31/2014 07:47 PM, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> Because bonding stats are usually sum of slave stats, it was
> not easy to account for tx drops at bonding layer.
>
> We can use dev->tx_dropped for this, as this counter is later
> added to the device stats (in dev_get_stats())
>
> This extends the idea we had in commit ee6377147409a ("bonding: Simplify
> the xmit function for modes that use xmit_hash") for bond_3ad_xor_xmit()
> to other bonding modes.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Mahesh Bandewar <maheshb@google.com>
> ---
> drivers/net/bonding/bond_alb.c | 2 +-
> drivers/net/bonding/bond_main.c | 15 +++++++--------
> drivers/net/bonding/bonding.h | 6 ++++++
> 3 files changed, 14 insertions(+), 9 deletions(-)
>
Nice,
Reviewed-by: Nikolay Aleksandrov <nikolay@redhat.com>
^ permalink raw reply
* Re: [PATCH net-next] bonding: add bond_tx_drop() helper
From: Mahesh Bandewar @ 2014-10-31 19:30 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, netdev, Jay Vosburgh, Veaceslav Falico,
Andy Gospodarek
In-Reply-To: <1414781274.27538.32.camel@edumazet-glaptop2.roam.corp.google.com>
On Fri, Oct 31, 2014 at 11:47 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> From: Eric Dumazet <edumazet@google.com>
>
> Because bonding stats are usually sum of slave stats, it was
> not easy to account for tx drops at bonding layer.
>
> We can use dev->tx_dropped for this, as this counter is later
> added to the device stats (in dev_get_stats())
>
> This extends the idea we had in commit ee6377147409a ("bonding: Simplify
> the xmit function for modes that use xmit_hash") for bond_3ad_xor_xmit()
> to other bonding modes.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Mahesh Bandewar <maheshb@google.com>
>
> ---
> drivers/net/bonding/bond_alb.c | 2 +-
> drivers/net/bonding/bond_main.c | 15 +++++++--------
> drivers/net/bonding/bonding.h | 6 ++++++
> 3 files changed, 14 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
> index d2eadab787c55d8fc0f361755409a880d64abfb3..baa58e79256a8b804e6ab683af6665f0730b86de 100644
> --- a/drivers/net/bonding/bond_alb.c
> +++ b/drivers/net/bonding/bond_alb.c
> @@ -1326,7 +1326,7 @@ static int bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond,
> }
>
> /* no suitable interface, frame not sent */
> - dev_kfree_skb_any(skb);
> + bond_tx_drop(bond->dev, skb);
> out:
> return NETDEV_TX_OK;
> }
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index c9ac06cfe6b7b3a8f62568b70a6ad6d7ca9b44d0..c7520082fb0d7bfbc34ac00b4f4186a30197ad74 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -3522,7 +3522,7 @@ static void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int sl
> }
> }
> /* no slave that can tx has been found */
> - dev_kfree_skb_any(skb);
> + bond_tx_drop(bond->dev, skb);
> }
>
> /**
> @@ -3584,7 +3584,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
> slave_id = bond_rr_gen_slave_id(bond);
> bond_xmit_slave_id(bond, skb, slave_id % slave_cnt);
> } else {
> - dev_kfree_skb_any(skb);
> + bond_tx_drop(bond_dev, skb);
> }
> }
>
> @@ -3603,7 +3603,7 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
> if (slave)
> bond_dev_queue_xmit(bond, skb, slave->dev);
> else
> - dev_kfree_skb_any(skb);
> + bond_tx_drop(bond_dev, skb);
>
> return NETDEV_TX_OK;
> }
> @@ -3747,8 +3747,7 @@ int bond_3ad_xor_xmit(struct sk_buff *skb, struct net_device *dev)
> slave = slaves->arr[bond_xmit_hash(bond, skb) % count];
> bond_dev_queue_xmit(bond, skb, slave->dev);
> } else {
> - dev_kfree_skb_any(skb);
> - atomic_long_inc(&dev->tx_dropped);
> + bond_tx_drop(dev, skb);
> }
>
> return NETDEV_TX_OK;
> @@ -3778,7 +3777,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
> if (slave && bond_slave_is_up(slave) && slave->link == BOND_LINK_UP)
> bond_dev_queue_xmit(bond, skb, slave->dev);
> else
> - dev_kfree_skb_any(skb);
> + bond_tx_drop(bond_dev, skb);
>
> return NETDEV_TX_OK;
> }
> @@ -3858,7 +3857,7 @@ static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev
> /* Should never happen, mode already checked */
> netdev_err(dev, "Unknown bonding mode %d\n", BOND_MODE(bond));
> WARN_ON_ONCE(1);
> - dev_kfree_skb_any(skb);
> + bond_tx_drop(dev, skb);
> return NETDEV_TX_OK;
> }
> }
> @@ -3878,7 +3877,7 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
> if (bond_has_slaves(bond))
> ret = __bond_start_xmit(skb, dev);
> else
> - dev_kfree_skb_any(skb);
> + bond_tx_drop(dev, skb);
> rcu_read_unlock();
>
> return ret;
> diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
> index 10920f0686e2f0222203359751581d1b728c6617..bfb0b51c081a27fbbbe64deda058f70860aac49d 100644
> --- a/drivers/net/bonding/bonding.h
> +++ b/drivers/net/bonding/bonding.h
> @@ -645,4 +645,10 @@ extern struct bond_parm_tbl ad_select_tbl[];
> /* exported from bond_netlink.c */
> extern struct rtnl_link_ops bond_link_ops;
>
> +static inline void bond_tx_drop(struct net_device *dev, struct sk_buff *skb)
> +{
> + atomic_long_inc(&dev->tx_dropped);
> + dev_kfree_skb_any(skb);
> +}
> +
> #endif /* _LINUX_BONDING_H */
>
Nice and simple. Thanks Eric
Acked-by: Mahesh Bandewar <maheshb@google.com>
^ permalink raw reply
* Re: [PATCH v3 1/1] ip-link: add switch to show human readable output
From: Stephen Hemminger @ 2014-10-31 19:31 UTC (permalink / raw)
To: Christian Hesse; +Cc: netdev
In-Reply-To: <20141031111753.2b524ebb@leda.localdomain>
On Fri, 31 Oct 2014 11:17:53 +0100
Christian Hesse <mail@eworm.de> wrote:
> Stephen Hemminger <stephen@networkplumber.org> on Wed, 2014/10/29 22:47:
> > I like the idea as a concept
>
> Great! ;)
>
> > but there are two issues:
> > 1. The IEC suffix is a rarely used thing and is non-standard
> > for communications where K = 1000 M = 1000000 etc.
> > Please just use standard suffices
>
> Removed the suffix in patch v3. Not sure if it is correct, though. I do use a
> base of 2, so K = 1024, M = 1048576, ...
No must be 1000 for communications (SI)
http://en.wikipedia.org/wiki/Binary_prefix
^ permalink raw reply
* Re: suspend/resume broken on 3.18-rc2
From: Fabio Estevam @ 2014-10-31 19:35 UTC (permalink / raw)
To: fugang.duan@freescale.com
Cc: Anson.Huang@freescale.com, Frank.Li@freescale.com, Russell King,
Shawn Guo, netdev@vger.kernel.org
In-Reply-To: <69f3cd5a2961445ebab0f2652ffa60bd@BLUPR03MB373.namprd03.prod.outlook.com>
Andy,
On Thu, Oct 30, 2014 at 1:11 AM, fugang.duan@freescale.com
<fugang.duan@freescale.com> wrote:
> I tried it yesterday with FEC close, resume cannot back.
> I will try it again.
We have a regression in 3.18-rc1: if I use the imx6sx-sdb.dtb from
3.17.1 then I get:
root@freescale /$ echo enabled > /sys/class/tty/ttymxc0/power/wakeup
root@freescale /$ echo mem > /sys/power/state
[ 13.883094] PM: Syncing filesystems ... done.
[ 13.932184] Freezing user space processes ... (elapsed 0.003 seconds) done.
[ 13.942928] Freezing remaining freezable tasks ... (elapsed 0.003 seconds) d.
[ 14.014823] PM: suspend of devices complete after 54.572 msecs
[ 14.020730] PM: suspend devices took 0.060 seconds
[ 14.035241] PM: late suspend of devices complete after 9.545 msecs
[ 14.050901] PM: noirq suspend of devices complete after 9.383 msecs
[ 14.057626] Disabling non-boot CPUs ...
[ 14.071514] PM: noirq resume of devices complete after 8.338 msecs
[ 14.085645] PM: early resume of devices complete after 6.417 msecs
[ 14.097720] fec 2188000.ethernet eth0: rcv is not +last
[ 14.187491] PM: resume of devices complete after 95.494 msecs
[ 14.199039] PM: resume devices took 0.100 seconds
[ 14.203831] Restarting tasks ... done.
[ 15.892318] fec 2188000.ethernet eth0: rcv is not +last
[ 15.897688] fec 2188000.ethernet eth0: rcv is not +last
[ 15.903010] fec 2188000.ethernet eth0: rcv is not +last
[ 15.908326] fec 2188000.ethernet eth0: rcv is not +last
[ 15.913635] fec 2188000.ethernet eth0: rcv is not +last
[ 15.918945] fec 2188000.ethernet eth0: rcv is not +last
So fec suspend/resume is broken for mx6sx.
Please take a look at it.
^ permalink raw reply
* Re: [PATCH net 1/2] mpls: Fix mpls_gso handler.
From: David Miller @ 2014-10-31 19:47 UTC (permalink / raw)
To: pshelar; +Cc: netdev, simon.horman
In-Reply-To: <1414655397-1541-1-git-send-email-pshelar@nicira.com>
From: Pravin B Shelar <pshelar@nicira.com>
Date: Thu, 30 Oct 2014 00:49:57 -0700
> mpls gso handler needs to pull skb after segmenting skb.
>
> CC: Simon Horman <simon.horman@netronome.com>
> Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Applied.
^ permalink raw reply
* Re: [PATCH net 2/2] mpls: Allow mpls_gso to be built as module
From: David Miller @ 2014-10-31 19:48 UTC (permalink / raw)
To: pshelar; +Cc: netdev, simon.horman
In-Reply-To: <1414655404-1572-1-git-send-email-pshelar@nicira.com>
From: Pravin B Shelar <pshelar@nicira.com>
Date: Thu, 30 Oct 2014 00:50:04 -0700
> Kconfig already allows mpls to be built as module. Following patch
> fixes Makefile to do same.
>
> CC: Simon Horman <simon.horman@netronome.com>
> Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Applied.
^ permalink raw reply
* pull request: wireless 2014-10-31
From: John W. Linville @ 2014-10-31 19:58 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 15517 bytes --]
Dave,
Please pull this small batch of spooky fixes intended for the 3.18
stream...boo!
Cyril Brulebois adds an rt2x00 device ID.
Dan Carpenter provides a one-line masking fix for an ath9k debugfs
entry.
Larry Finger gives us a package of small rtlwifi fixes which add some
bits that were left out of some feature updates that were included
in the merge window. Hopefully this isn't a sign that the rtlwifi
base is getting too big...
Marc Yang brings a fix for a temporary mwifiex stall when doing 11n
RX reordering.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit 99c814066e75d09e6a38574c6c395f022a04b730:
Merge tag 'mac80211-for-john-2014-10-23' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211 (2014-10-27 13:38:15 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git tags/master-2014-10-30
for you to fetch changes up to 75a916e1944fea8347d2245c62567187e4eff9dd:
rtlwifi: rtl8192se: Fix firmware loading (2014-10-30 15:00:23 -0400)
----------------------------------------------------------------
Cyril Brulebois (1):
wireless: rt2x00: add new rt2800usb device
Dan Carpenter (1):
ath9k: fix some debugfs output
Larry Finger (5):
rtlwifi: rtl8192ce: rtl8192de: rtl8192se: Fix handling for missing get_btc_status
rtlwifi: rtl8192se: Fix duplicate calls to ieee80211_register_hw()
rtlwifi: rtl8192se: Add missing section to read descriptor setting
rtlwifi: rtl8192ce: Add missing section to read descriptor setting
rtlwifi: rtl8192se: Fix firmware loading
Marc Yang (1):
mwifiex: restart rxreorder timer correctly
drivers/net/wireless/ath/ath9k/debug.c | 2 +-
drivers/net/wireless/mwifiex/11n_rxreorder.c | 52 +++++++++++++++++++++-------
drivers/net/wireless/mwifiex/11n_rxreorder.h | 2 ++
drivers/net/wireless/mwifiex/main.h | 1 +
drivers/net/wireless/rt2x00/rt2800usb.c | 1 +
drivers/net/wireless/rtlwifi/core.c | 6 ++++
drivers/net/wireless/rtlwifi/core.h | 1 +
drivers/net/wireless/rtlwifi/rtl8192ce/def.h | 2 ++
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 1 +
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 3 ++
drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 1 +
drivers/net/wireless/rtlwifi/rtl8192se/def.h | 2 ++
drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 22 ++----------
drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 3 ++
14 files changed, 67 insertions(+), 32 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 46f20a309b5f..5c45e787814e 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -455,7 +455,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
"%2d %2x %1x %2x %2x\n",
i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
(*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
- val[2] & (0x7 << (i * 3)) >> (i * 3),
+ (val[2] & (0x7 << (i * 3))) >> (i * 3),
(*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
}
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 40057079ffb9..5ef5a0eeba50 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -196,6 +196,7 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, start_win);
del_timer_sync(&tbl->timer_context.timer);
+ tbl->timer_context.timer_is_set = false;
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
list_del(&tbl->list);
@@ -297,6 +298,7 @@ mwifiex_flush_data(unsigned long context)
(struct reorder_tmr_cnxt *) context;
int start_win, seq_num;
+ ctx->timer_is_set = false;
seq_num = mwifiex_11n_find_last_seq_num(ctx);
if (seq_num < 0)
@@ -385,6 +387,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
new_node->timer_context.ptr = new_node;
new_node->timer_context.priv = priv;
+ new_node->timer_context.timer_is_set = false;
init_timer(&new_node->timer_context.timer);
new_node->timer_context.timer.function = mwifiex_flush_data;
@@ -399,6 +402,22 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
}
+static void
+mwifiex_11n_rxreorder_timer_restart(struct mwifiex_rx_reorder_tbl *tbl)
+{
+ u32 min_flush_time;
+
+ if (tbl->win_size >= MWIFIEX_BA_WIN_SIZE_32)
+ min_flush_time = MIN_FLUSH_TIMER_15_MS;
+ else
+ min_flush_time = MIN_FLUSH_TIMER_MS;
+
+ mod_timer(&tbl->timer_context.timer,
+ jiffies + msecs_to_jiffies(min_flush_time * tbl->win_size));
+
+ tbl->timer_context.timer_is_set = true;
+}
+
/*
* This function prepares command for adding a BA request.
*
@@ -523,31 +542,31 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
u8 *ta, u8 pkt_type, void *payload)
{
struct mwifiex_rx_reorder_tbl *tbl;
- int start_win, end_win, win_size;
+ int prev_start_win, start_win, end_win, win_size;
u16 pkt_index;
bool init_window_shift = false;
+ int ret = 0;
tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
if (!tbl) {
if (pkt_type != PKT_TYPE_BAR)
mwifiex_11n_dispatch_pkt(priv, payload);
- return 0;
+ return ret;
}
if ((pkt_type == PKT_TYPE_AMSDU) && !tbl->amsdu) {
mwifiex_11n_dispatch_pkt(priv, payload);
- return 0;
+ return ret;
}
start_win = tbl->start_win;
+ prev_start_win = start_win;
win_size = tbl->win_size;
end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
if (tbl->flags & RXREOR_INIT_WINDOW_SHIFT) {
init_window_shift = true;
tbl->flags &= ~RXREOR_INIT_WINDOW_SHIFT;
}
- mod_timer(&tbl->timer_context.timer,
- jiffies + msecs_to_jiffies(MIN_FLUSH_TIMER_MS * win_size));
if (tbl->flags & RXREOR_FORCE_NO_DROP) {
dev_dbg(priv->adapter->dev,
@@ -568,11 +587,14 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {
if (seq_num >= ((start_win + TWOPOW11) &
(MAX_TID_VALUE - 1)) &&
- seq_num < start_win)
- return -1;
+ seq_num < start_win) {
+ ret = -1;
+ goto done;
+ }
} else if ((seq_num < start_win) ||
- (seq_num > (start_win + TWOPOW11))) {
- return -1;
+ (seq_num >= (start_win + TWOPOW11))) {
+ ret = -1;
+ goto done;
}
}
@@ -601,8 +623,10 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
else
pkt_index = (seq_num+MAX_TID_VALUE) - start_win;
- if (tbl->rx_reorder_ptr[pkt_index])
- return -1;
+ if (tbl->rx_reorder_ptr[pkt_index]) {
+ ret = -1;
+ goto done;
+ }
tbl->rx_reorder_ptr[pkt_index] = payload;
}
@@ -613,7 +637,11 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
*/
mwifiex_11n_scan_and_dispatch(priv, tbl);
- return 0;
+done:
+ if (!tbl->timer_context.timer_is_set ||
+ prev_start_win != tbl->start_win)
+ mwifiex_11n_rxreorder_timer_restart(tbl);
+ return ret;
}
/*
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
index 3a87bb0e3a62..63ecea89b4ab 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -21,6 +21,8 @@
#define _MWIFIEX_11N_RXREORDER_H_
#define MIN_FLUSH_TIMER_MS 50
+#define MIN_FLUSH_TIMER_15_MS 15
+#define MWIFIEX_BA_WIN_SIZE_32 32
#define PKT_TYPE_BAR 0xE7
#define MAX_TID_VALUE (2 << 11)
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index e2635747d966..f55658d15c60 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -592,6 +592,7 @@ struct reorder_tmr_cnxt {
struct timer_list timer;
struct mwifiex_rx_reorder_tbl *ptr;
struct mwifiex_private *priv;
+ u8 timer_is_set;
};
struct mwifiex_rx_reorder_tbl {
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 573897b8e878..8444313eabe2 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1111,6 +1111,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Ovislink */
{ USB_DEVICE(0x1b75, 0x3071) },
{ USB_DEVICE(0x1b75, 0x3072) },
+ { USB_DEVICE(0x1b75, 0xa200) },
/* Para */
{ USB_DEVICE(0x20b8, 0x8888) },
/* Pegatron */
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index f6179bc06086..07dae0d44abc 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -1828,3 +1828,9 @@ const struct ieee80211_ops rtl_ops = {
.flush = rtl_op_flush,
};
EXPORT_SYMBOL_GPL(rtl_ops);
+
+bool rtl_btc_status_false(void)
+{
+ return false;
+}
+EXPORT_SYMBOL_GPL(rtl_btc_status_false);
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
index 59cd3b9dca25..624e1dc16d31 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -42,5 +42,6 @@ void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
u32 mask, u32 data);
void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data);
bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
+bool rtl_btc_status_false(void);
#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
index 831df101d7b7..9b660df6fd71 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
@@ -114,6 +114,8 @@
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
+#define GET_RX_STATUS_DESC_BUFF_ADDR(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 24, 0, 32)
#define CHIP_VER_B BIT(4)
#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index d86b5b566444..46ea07605eb4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -244,6 +244,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {
.phy_lc_calibrate = _rtl92ce_phy_lc_calibrate,
.phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback,
.dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower,
+ .get_btc_status = rtl_btc_status_false,
};
static struct rtl_mod_params rtl92ce_mod_params = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index 2fb9c7acb76a..dc3d20b17a26 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -728,6 +728,9 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
case HW_DESC_RXPKT_LEN:
ret = GET_RX_DESC_PKT_LEN(pdesc);
break;
+ case HW_DESC_RXBUFF_ADDR:
+ ret = GET_RX_STATUS_DESC_BUFF_ADDR(pdesc);
+ break;
default:
RT_ASSERT(false, "ERR rxdesc :%d not process\n",
desc_name);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
index edab5a5351b5..a0aba088259a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -251,6 +251,7 @@ static struct rtl_hal_ops rtl8192de_hal_ops = {
.get_rfreg = rtl92d_phy_query_rf_reg,
.set_rfreg = rtl92d_phy_set_rf_reg,
.linked_set_reg = rtl92d_linked_set_reg,
+ .get_btc_status = rtl_btc_status_false,
};
static struct rtl_mod_params rtl92de_mod_params = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
index 83c98674bfd3..6e7a70b43949 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
@@ -446,6 +446,8 @@
/* DWORD 6 */
#define SET_RX_STATUS__DESC_BUFF_ADDR(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc + 24, 0, 32, __val)
+#define GET_RX_STATUS_DESC_BUFF_ADDR(__pdesc) \
+ SHIFT_AND_MASK_LE(__pdesc + 24, 0, 32)
#define SE_RX_HAL_IS_CCK_RATE(_pdesc)\
(GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE1M || \
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
index 1bff2a0f7600..aadba29c167a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -87,11 +87,8 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
static void rtl92se_fw_cb(const struct firmware *firmware, void *context)
{
struct ieee80211_hw *hw = context;
- struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
struct rt_firmware *pfirmware = NULL;
- int err;
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"Firmware callback routine entered!\n");
@@ -112,20 +109,6 @@ static void rtl92se_fw_cb(const struct firmware *firmware, void *context)
memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
pfirmware->sz_fw_tmpbufferlen = firmware->size;
release_firmware(firmware);
-
- err = ieee80211_register_hw(hw);
- if (err) {
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- "Can't register mac80211 hw\n");
- return;
- } else {
- rtlpriv->mac80211.mac80211_registered = 1;
- }
- rtlpci->irq_alloc = 1;
- set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
-
- /*init rfkill */
- rtl_init_rfkill(hw);
}
static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
@@ -226,8 +209,8 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
if (!rtlpriv->rtlhal.pfirmware)
return 1;
- rtlpriv->max_fw_size = RTL8190_MAX_RAW_FIRMWARE_CODE_SIZE;
-
+ rtlpriv->max_fw_size = RTL8190_MAX_FIRMWARE_CODE_SIZE*2 +
+ sizeof(struct fw_hdr);
pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n"
"Loading firmware %s\n", rtlpriv->cfg->fw_name);
/* request fw */
@@ -294,6 +277,7 @@ static struct rtl_hal_ops rtl8192se_hal_ops = {
.set_bbreg = rtl92s_phy_set_bb_reg,
.get_rfreg = rtl92s_phy_query_rf_reg,
.set_rfreg = rtl92s_phy_set_rf_reg,
+ .get_btc_status = rtl_btc_status_false,
};
static struct rtl_mod_params rtl92se_mod_params = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index b358ebce8942..672fd3b02835 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -640,6 +640,9 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
case HW_DESC_RXPKT_LEN:
ret = GET_RX_STATUS_DESC_PKT_LEN(desc);
break;
+ case HW_DESC_RXBUFF_ADDR:
+ ret = GET_RX_STATUS_DESC_BUFF_ADDR(desc);
+ break;
default:
RT_ASSERT(false, "ERR rxdesc :%d not process\n",
desc_name);
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply related
* Re: [PATCH net-next] bonding: add bond_tx_drop() helper
From: David Miller @ 2014-10-31 20:09 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, j.vosburgh, vfalico, andy, maheshb
In-Reply-To: <1414781274.27538.32.camel@edumazet-glaptop2.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 31 Oct 2014 11:47:54 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> Because bonding stats are usually sum of slave stats, it was
> not easy to account for tx drops at bonding layer.
>
> We can use dev->tx_dropped for this, as this counter is later
> added to the device stats (in dev_get_stats())
>
> This extends the idea we had in commit ee6377147409a ("bonding: Simplify
> the xmit function for modes that use xmit_hash") for bond_3ad_xor_xmit()
> to other bonding modes.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Mahesh Bandewar <maheshb@google.com>
Applied, thanks Eric.
^ permalink raw reply
* Re: [PATCH v2] stmmac: pci: set default of the filter bins
From: David Miller @ 2014-10-31 20:10 UTC (permalink / raw)
To: andriy.shevchenko
Cc: peppe.cavallaro, netdev, hock.leong.kweh, vbridgers2013, stable
In-Reply-To: <1414772883-29503-1-git-send-email-andriy.shevchenko@linux.intel.com>
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Date: Fri, 31 Oct 2014 18:28:03 +0200
> The commit 3b57de958e2a brought the support for a different amount of the
> filter bins, but didn't update the PCI driver accordingly. This patch appends
> the default values when the device is enumerated via PCI bus.
>
> Fixes: 3b57de958e2a (net: stmmac: Support devicetree configs for mcast and ucast filter entries)
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: stable@vger.kernel.org
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next] ethernet: mvneta: Use PHY status standard message
From: David Miller @ 2014-10-31 20:11 UTC (permalink / raw)
To: ezequiel.garcia
Cc: thomas.petazzoni, gregory.clement, nadavh, tawfik, alior, netdev
In-Reply-To: <1414771040-7789-1-git-send-email-ezequiel.garcia@free-electrons.com>
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Fri, 31 Oct 2014 12:57:20 -0300
> Use phy_print_status() to report a change in the PHY status.
> The current message is not verbose enough, so this commit improves
> it by using the generic status message.
>
> After this change, the kernel reports PHY status down and up events as:
>
> mvneta f1070000.ethernet eth0: Link is Down
> mvneta f1070000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/tx
>
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] net: ethtool: Return -EOPNOTSUPP if user space tries to read EEPROM with lengh 0
From: David Miller @ 2014-10-31 20:13 UTC (permalink / raw)
To: andrew; +Cc: linux, netdev, linux-kernel
In-Reply-To: <20141031035635.GC4082@lunn.ch>
From: Andrew Lunn <andrew@lunn.ch>
Date: Fri, 31 Oct 2014 04:56:35 +0100
> On Thu, Oct 30, 2014 at 08:50:15PM -0700, Guenter Roeck wrote:
>> If a driver supports reading EEPROM but no EEPROM is installed in the system,
>> the driver's get_eeprom_len function returns 0. ethtool will subsequently
>> try to read that zero-length EEPROM anyway. If the driver does not support
>> EEPROM access at all, this operation will return -EOPNOTSUPP. If the driver
>> does support EEPROM access but no EEPROM is installed, the operation will
>> return -EINVAL. Return -EOPNOTSUPP in both cases for consistency.
>>
>> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
>
> root@dir665:~# ethtool -e lan4
> Cannot get EEPROM data: Operation not supported
>
> Tested-by: Andrew Lunn <andrew@lunn.ch>
Applied, thanks everyone.
^ permalink raw reply
* Re: [PATCH net-next v2 2/3] r8152: clear the flag of SCHEDULE_TASKLET in tasklet
From: David Miller @ 2014-10-31 20:15 UTC (permalink / raw)
To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb
In-Reply-To: <1394712342-15778-81-Taiwan-albertk@realtek.com>
From: Hayes Wang <hayeswang@realtek.com>
Date: Fri, 31 Oct 2014 17:56:41 +0800
> Clear the flag of SCHEDULE_TASKLET in bottom_half() to avoid
> re-schedule the tasklet again by workqueue.
>
> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
> ---
> drivers/net/usb/r8152.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index ff54098..670279a 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
> @@ -1798,6 +1798,9 @@ static void bottom_half(unsigned long data)
> if (!netif_carrier_ok(tp->netdev))
> return;
>
> + if (test_bit(SCHEDULE_TASKLET, &tp->flags))
> + clear_bit(SCHEDULE_TASKLET, &tp->flags);
This is racey.
If another thread of control sets the bit between the test and the
clear, you will lose an event.
It really never makes sense to work with atomic bitops in a non-atomic
test-and-whatever manner like this, it's always a red flag and
indicates you're doing something very wrong.
^ permalink raw reply
* Re: drivers: net: cpsw: Fix broken loop condition in switch mode
From: David Miller @ 2014-10-31 20:17 UTC (permalink / raw)
To: lsorense; +Cc: linux-kernel, hs, mugunthanvnm, netdev
In-Reply-To: <20141031172854.GJ24110@csclub.uwaterloo.ca>
From: "Lennart Sorensen" <lsorense@csclub.uwaterloo.ca>
Date: Fri, 31 Oct 2014 13:28:54 -0400
> 0d961b3b52f566f823070ce2366511a7f64b928c (drivers: net: cpsw: fix buggy
> loop condition) accidentally fixed a loop comparison in too many places
> while fixing a real bug.
>
> It was correct to fix the dual_emac mode section since there 'i' is used
> as an index into priv->slaves which is a 0 based array.
>
> However the other two changes (which are only used in switch mode)
> are wrong since there 'i' is actually the ALE port number, and port 0
> is the host port, while port 1 and up are the slave ports.
>
> Putting the loop condition back in the switch mode section fixes it.
>
> A comment has been added to point out the intent clearly to avoid future
> confusion. Also a comment is fixed that said the opposite of what was
> actually happening.
>
> Signed-off-by: Len Sorensen <lsorense@csclub.uwaterloo.ca>
> Acked-by: Heiko Schocher <hs@denx.de>
Applied.
^ permalink raw reply
* Re: drivers: net: cpsw: Support ALLMULTI and fix IFF_PROMISC in switch mode
From: David Miller @ 2014-10-31 20:17 UTC (permalink / raw)
To: lsorense; +Cc: linux-kernel, mugunthanvnm, netdev
In-Reply-To: <20141031173852.GK24110@csclub.uwaterloo.ca>
From: "Lennart Sorensen" <lsorense@csclub.uwaterloo.ca>
Date: Fri, 31 Oct 2014 13:38:52 -0400
> The cpsw driver did not support the IFF_ALLMULTI flag which makes dynamic
> multicast routing not work. Related to this, when enabling IFF_PROMISC
> in switch mode, all registered multicast addresses are flushed, resulting
> in only broadcast and unicast traffic being received.
>
> A new cpsw_ale_set_allmulti function now scans through the ALE entry
> table and adds/removes the host port from the unregistered multicast
> port mask of each vlan entry depending on the state of IFF_ALLMULTI.
> In promiscious mode, cpsw_ale_set_allmulti is used to force reception
> of all multicast traffic in addition to the unicast and broadcast traffic.
>
> With this change dynamic multicast and promiscious mode both work in
> switch mode.
>
> Signed-off-by: Len Sorensen <lsorense@csclub.uwaterloo.ca>
Applied.
^ permalink raw reply
* Re: pull request: wireless 2014-10-31
From: David Miller @ 2014-10-31 20:18 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20141031195817.GC3768@tuxdriver.com>
From: "John W. Linville" <linville@tuxdriver.com>
Date: Fri, 31 Oct 2014 15:58:17 -0400
> Please pull this small batch of spooky fixes intended for the 3.18
> stream...boo!
Scary... but pulled.
Thanks a lot!
^ permalink raw reply
* [PATCH] smc91x: retrieve IRQ and trigger flags in a modern way
From: Linus Walleij @ 2014-10-31 20:32 UTC (permalink / raw)
To: netdev, Nicolas Pitre, David S. Miller; +Cc: Linus Walleij
The SMC91x is written to explicitly look up the IRQ resource
from the platform device and extract the IRQ and flags, however
the platform_get_irq() does additional things, like call
of_irq_get() in the device tree case, which will translate
the IRQ using the irqdomain and defer the probe if the
IRQ host cannot be found.
As we're not looking up the resource, this will not retrieve
the IRQ flags, but that is better done using
irqd_get_trigger_type(), as the trigger is what the driver
wants to modify. We take care to preserve the semantics that
will make the trigger type provided from the resource
override any local specifier.
Tested on the Nomadik NHK15 which has its SMC91x IRQ line
connected to a STMPE2401 GPIO expander on I2C.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/net/ethernet/smsc/smc91x.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index 5e94d00b96b3..7747d506646a 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -2207,9 +2207,10 @@ static int smc_drv_probe(struct platform_device *pdev)
const struct of_device_id *match = NULL;
struct smc_local *lp;
struct net_device *ndev;
- struct resource *res, *ires;
+ struct resource *res;
unsigned int __iomem *addr;
unsigned long irq_flags = SMC_IRQ_FLAGS;
+ unsigned long irq_resflags;
int ret;
ndev = alloc_etherdev(sizeof(struct smc_local));
@@ -2279,16 +2280,19 @@ static int smc_drv_probe(struct platform_device *pdev)
goto out_free_netdev;
}
- ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!ires) {
+ ndev->irq = platform_get_irq(pdev, 0);
+ if (ndev->irq <= 0) {
ret = -ENODEV;
goto out_release_io;
}
-
- ndev->irq = ires->start;
-
- if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK)
- irq_flags = ires->flags & IRQF_TRIGGER_MASK;
+ /*
+ * If this platform does not specify any special irqflags, or if
+ * the resource supplies a trigger, override the irqflags with
+ * the trigger flags from the resource.
+ */
+ irq_resflags = irqd_get_trigger_type(irq_get_irq_data(ndev->irq));
+ if (irq_flags == -1 || irq_resflags & IRQF_TRIGGER_MASK)
+ irq_flags = irq_resflags & IRQF_TRIGGER_MASK;
ret = smc_request_attrib(pdev, ndev);
if (ret)
--
1.9.3
^ permalink raw reply related
* [Patch net-next] neigh: remove dynamic neigh table registration support
From: Cong Wang @ 2014-10-31 20:34 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Cong Wang
Currently there are only three neigh tables in the whole kernel:
arp table, ndisc table and decnet neigh table. What's more,
we don't support registering multiple tables per family.
Therefore we can just make these tables statically built-in.
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
include/net/neighbour.h | 9 +-
net/core/neighbour.c | 249 ++++++++++++++++++++++--------------------------
net/decnet/dn_neigh.c | 2 +-
net/ipv4/arp.c | 2 +-
net/ipv6/ndisc.c | 2 +-
5 files changed, 126 insertions(+), 138 deletions(-)
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index dedfb18..1e65c68 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -220,6 +220,13 @@ struct neigh_table {
struct pneigh_entry **phash_buckets;
};
+enum {
+ NEIGH_ARP_TABLE = 0,
+ NEIGH_ND_TABLE = 1,
+ NEIGH_DN_TABLE = 2,
+ NEIGH_NR_TABLES,
+};
+
static inline int neigh_parms_family(struct neigh_parms *p)
{
return p->tbl->family;
@@ -240,7 +247,7 @@ static inline void *neighbour_priv(const struct neighbour *n)
#define NEIGH_UPDATE_F_ISROUTER 0x40000000
#define NEIGH_UPDATE_F_ADMIN 0x80000000
-void neigh_table_init(struct neigh_table *tbl);
+void neigh_table_init(int index, struct neigh_table *tbl);
int neigh_table_clear(struct neigh_table *tbl);
struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
struct net_device *dev);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index edd0411..de6831c 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -56,7 +56,6 @@ static void __neigh_notify(struct neighbour *n, int type, int flags);
static void neigh_update_notify(struct neighbour *neigh);
static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
-static struct neigh_table *neigh_tables;
#ifdef CONFIG_PROC_FS
static const struct file_operations neigh_stat_seq_fops;
#endif
@@ -87,13 +86,8 @@ static const struct file_operations neigh_stat_seq_fops;
the most complicated procedure, which we allow is dev->hard_header.
It is supposed, that dev->hard_header is simplistic and does
not make callbacks to neighbour tables.
-
- The last lock is neigh_tbl_lock. It is pure SMP lock, protecting
- list of neighbour tables. This list is used only in process context,
*/
-static DEFINE_RWLOCK(neigh_tbl_lock);
-
static int neigh_blackhole(struct neighbour *neigh, struct sk_buff *skb)
{
kfree_skb(skb);
@@ -1520,11 +1514,15 @@ static void neigh_parms_destroy(struct neigh_parms *parms)
static struct lock_class_key neigh_table_proxy_queue_class;
-static void neigh_table_init_no_netlink(struct neigh_table *tbl)
+static struct neigh_table *neigh_tables[NEIGH_NR_TABLES] __read_mostly;
+
+void neigh_table_init(int index, struct neigh_table *tbl)
{
unsigned long now = jiffies;
unsigned long phsize;
+ neigh_tables[index] = tbl;
+
INIT_LIST_HEAD(&tbl->parms_list);
list_add(&tbl->parms.list, &tbl->parms_list);
write_pnet(&tbl->parms.net, &init_net);
@@ -1566,34 +1564,12 @@ static void neigh_table_init_no_netlink(struct neigh_table *tbl)
tbl->last_flush = now;
tbl->last_rand = now + tbl->parms.reachable_time * 20;
-}
-void neigh_table_init(struct neigh_table *tbl)
-{
- struct neigh_table *tmp;
-
- neigh_table_init_no_netlink(tbl);
- write_lock(&neigh_tbl_lock);
- for (tmp = neigh_tables; tmp; tmp = tmp->next) {
- if (tmp->family == tbl->family)
- break;
- }
- tbl->next = neigh_tables;
- neigh_tables = tbl;
- write_unlock(&neigh_tbl_lock);
-
- if (unlikely(tmp)) {
- pr_err("Registering multiple tables for family %d\n",
- tbl->family);
- dump_stack();
- }
}
EXPORT_SYMBOL(neigh_table_init);
int neigh_table_clear(struct neigh_table *tbl)
{
- struct neigh_table **tp;
-
/* It is not clean... Fix it to unload IPv6 module safely */
cancel_delayed_work_sync(&tbl->gc_work);
del_timer_sync(&tbl->proxy_timer);
@@ -1601,14 +1577,6 @@ int neigh_table_clear(struct neigh_table *tbl)
neigh_ifdown(tbl, NULL);
if (atomic_read(&tbl->entries))
pr_crit("neighbour leakage\n");
- write_lock(&neigh_tbl_lock);
- for (tp = &neigh_tables; *tp; tp = &(*tp)->next) {
- if (*tp == tbl) {
- *tp = tbl->next;
- break;
- }
- }
- write_unlock(&neigh_tbl_lock);
call_rcu(&rcu_dereference_protected(tbl->nht, 1)->rcu,
neigh_hash_free_rcu);
@@ -1626,12 +1594,36 @@ int neigh_table_clear(struct neigh_table *tbl)
}
EXPORT_SYMBOL(neigh_table_clear);
+static struct neigh_table *neigh_find_table(int family)
+{
+ struct neigh_table *tbl = NULL;
+
+ switch (family) {
+ case AF_INET:
+ tbl = neigh_tables[NEIGH_ARP_TABLE];
+ break;
+#if IS_ENABLED(CONFIG_IPV6)
+ case AF_INET6:
+ tbl = neigh_tables[NEIGH_ND_TABLE];
+ break;
+#endif
+#if IS_ENABLED(CONFIG_DECNET)
+ case AF_DECnet:
+ tbl = neigh_tables[NEIGH_DN_TABLE];
+ break;
+#endif
+ }
+
+ return tbl;
+}
+
static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh)
{
struct net *net = sock_net(skb->sk);
struct ndmsg *ndm;
struct nlattr *dst_attr;
struct neigh_table *tbl;
+ struct neighbour *neigh;
struct net_device *dev = NULL;
int err = -EINVAL;
@@ -1652,39 +1644,31 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh)
}
}
- read_lock(&neigh_tbl_lock);
- for (tbl = neigh_tables; tbl; tbl = tbl->next) {
- struct neighbour *neigh;
+ tbl = neigh_find_table(ndm->ndm_family);
+ if (tbl == NULL)
+ return -EAFNOSUPPORT;
- if (tbl->family != ndm->ndm_family)
- continue;
- read_unlock(&neigh_tbl_lock);
-
- if (nla_len(dst_attr) < tbl->key_len)
- goto out;
-
- if (ndm->ndm_flags & NTF_PROXY) {
- err = pneigh_delete(tbl, net, nla_data(dst_attr), dev);
- goto out;
- }
+ if (nla_len(dst_attr) < tbl->key_len)
+ goto out;
- if (dev == NULL)
- goto out;
+ if (ndm->ndm_flags & NTF_PROXY) {
+ err = pneigh_delete(tbl, net, nla_data(dst_attr), dev);
+ goto out;
+ }
- neigh = neigh_lookup(tbl, nla_data(dst_attr), dev);
- if (neigh == NULL) {
- err = -ENOENT;
- goto out;
- }
+ if (dev == NULL)
+ goto out;
- err = neigh_update(neigh, NULL, NUD_FAILED,
- NEIGH_UPDATE_F_OVERRIDE |
- NEIGH_UPDATE_F_ADMIN);
- neigh_release(neigh);
+ neigh = neigh_lookup(tbl, nla_data(dst_attr), dev);
+ if (neigh == NULL) {
+ err = -ENOENT;
goto out;
}
- read_unlock(&neigh_tbl_lock);
- err = -EAFNOSUPPORT;
+
+ err = neigh_update(neigh, NULL, NUD_FAILED,
+ NEIGH_UPDATE_F_OVERRIDE |
+ NEIGH_UPDATE_F_ADMIN);
+ neigh_release(neigh);
out:
return err;
@@ -1692,11 +1676,14 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh)
static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh)
{
+ int flags = NEIGH_UPDATE_F_ADMIN | NEIGH_UPDATE_F_OVERRIDE;
struct net *net = sock_net(skb->sk);
struct ndmsg *ndm;
struct nlattr *tb[NDA_MAX+1];
struct neigh_table *tbl;
struct net_device *dev = NULL;
+ struct neighbour *neigh;
+ void *dst, *lladdr;
int err;
ASSERT_RTNL();
@@ -1720,70 +1707,60 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh)
goto out;
}
- read_lock(&neigh_tbl_lock);
- for (tbl = neigh_tables; tbl; tbl = tbl->next) {
- int flags = NEIGH_UPDATE_F_ADMIN | NEIGH_UPDATE_F_OVERRIDE;
- struct neighbour *neigh;
- void *dst, *lladdr;
+ tbl = neigh_find_table(ndm->ndm_family);
+ if (tbl == NULL)
+ return -EAFNOSUPPORT;
- if (tbl->family != ndm->ndm_family)
- continue;
- read_unlock(&neigh_tbl_lock);
+ if (nla_len(tb[NDA_DST]) < tbl->key_len)
+ goto out;
+ dst = nla_data(tb[NDA_DST]);
+ lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL;
- if (nla_len(tb[NDA_DST]) < tbl->key_len)
- goto out;
- dst = nla_data(tb[NDA_DST]);
- lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL;
+ if (ndm->ndm_flags & NTF_PROXY) {
+ struct pneigh_entry *pn;
- if (ndm->ndm_flags & NTF_PROXY) {
- struct pneigh_entry *pn;
+ err = -ENOBUFS;
+ pn = pneigh_lookup(tbl, net, dst, dev, 1);
+ if (pn) {
+ pn->flags = ndm->ndm_flags;
+ err = 0;
+ }
+ goto out;
+ }
- err = -ENOBUFS;
- pn = pneigh_lookup(tbl, net, dst, dev, 1);
- if (pn) {
- pn->flags = ndm->ndm_flags;
- err = 0;
- }
+ if (dev == NULL)
+ goto out;
+
+ neigh = neigh_lookup(tbl, dst, dev);
+ if (neigh == NULL) {
+ if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
+ err = -ENOENT;
goto out;
}
- if (dev == NULL)
+ neigh = __neigh_lookup_errno(tbl, dst, dev);
+ if (IS_ERR(neigh)) {
+ err = PTR_ERR(neigh);
+ goto out;
+ }
+ } else {
+ if (nlh->nlmsg_flags & NLM_F_EXCL) {
+ err = -EEXIST;
+ neigh_release(neigh);
goto out;
-
- neigh = neigh_lookup(tbl, dst, dev);
- if (neigh == NULL) {
- if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
- err = -ENOENT;
- goto out;
- }
-
- neigh = __neigh_lookup_errno(tbl, dst, dev);
- if (IS_ERR(neigh)) {
- err = PTR_ERR(neigh);
- goto out;
- }
- } else {
- if (nlh->nlmsg_flags & NLM_F_EXCL) {
- err = -EEXIST;
- neigh_release(neigh);
- goto out;
- }
-
- if (!(nlh->nlmsg_flags & NLM_F_REPLACE))
- flags &= ~NEIGH_UPDATE_F_OVERRIDE;
}
- if (ndm->ndm_flags & NTF_USE) {
- neigh_event_send(neigh, NULL);
- err = 0;
- } else
- err = neigh_update(neigh, lladdr, ndm->ndm_state, flags);
- neigh_release(neigh);
- goto out;
+ if (!(nlh->nlmsg_flags & NLM_F_REPLACE))
+ flags &= ~NEIGH_UPDATE_F_OVERRIDE;
}
- read_unlock(&neigh_tbl_lock);
- err = -EAFNOSUPPORT;
+ if (ndm->ndm_flags & NTF_USE) {
+ neigh_event_send(neigh, NULL);
+ err = 0;
+ } else
+ err = neigh_update(neigh, lladdr, ndm->ndm_state, flags);
+ neigh_release(neigh);
+
out:
return err;
}
@@ -1982,7 +1959,8 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
struct neigh_table *tbl;
struct ndtmsg *ndtmsg;
struct nlattr *tb[NDTA_MAX+1];
- int err;
+ bool found = false;
+ int err, tidx;
err = nlmsg_parse(nlh, sizeof(*ndtmsg), tb, NDTA_MAX,
nl_neightbl_policy);
@@ -1995,19 +1973,21 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
}
ndtmsg = nlmsg_data(nlh);
- read_lock(&neigh_tbl_lock);
- for (tbl = neigh_tables; tbl; tbl = tbl->next) {
+
+ for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) {
+ tbl = neigh_tables[tidx];
+ if (!tbl)
+ continue;
if (ndtmsg->ndtm_family && tbl->family != ndtmsg->ndtm_family)
continue;
-
- if (nla_strcmp(tb[NDTA_NAME], tbl->id) == 0)
+ if (nla_strcmp(tb[NDTA_NAME], tbl->id) == 0) {
+ found = true;
break;
+ }
}
- if (tbl == NULL) {
- err = -ENOENT;
- goto errout_locked;
- }
+ if (!found)
+ return -ENOENT;
/*
* We acquire tbl->lock to be nice to the periodic timers and
@@ -2118,8 +2098,6 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
errout_tbl_lock:
write_unlock_bh(&tbl->lock);
-errout_locked:
- read_unlock(&neigh_tbl_lock);
errout:
return err;
}
@@ -2134,10 +2112,13 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family;
- read_lock(&neigh_tbl_lock);
- for (tbl = neigh_tables, tidx = 0; tbl; tbl = tbl->next, tidx++) {
+ for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) {
struct neigh_parms *p;
+ tbl = neigh_tables[tidx];
+ if (!tbl)
+ continue;
+
if (tidx < tbl_skip || (family && tbl->family != family))
continue;
@@ -2168,7 +2149,6 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
neigh_skip = 0;
}
out:
- read_unlock(&neigh_tbl_lock);
cb->args[0] = tidx;
cb->args[1] = nidx;
@@ -2351,7 +2331,6 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
int proxy = 0;
int err;
- read_lock(&neigh_tbl_lock);
family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family;
/* check for full ndmsg structure presence, family member is
@@ -2363,8 +2342,11 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
s_t = cb->args[0];
- for (tbl = neigh_tables, t = 0; tbl;
- tbl = tbl->next, t++) {
+ for (t = 0; t < NEIGH_NR_TABLES; t++) {
+ tbl = neigh_tables[t];
+
+ if (!tbl)
+ continue;
if (t < s_t || (family && tbl->family != family))
continue;
if (t > s_t)
@@ -2377,7 +2359,6 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
if (err < 0)
break;
}
- read_unlock(&neigh_tbl_lock);
cb->args[0] = t;
return skb->len;
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index c8121ce..845957a 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -591,7 +591,7 @@ static const struct file_operations dn_neigh_seq_fops = {
void __init dn_neigh_init(void)
{
- neigh_table_init(&dn_neigh_table);
+ neigh_table_init(NEIGH_DN_TABLE, &dn_neigh_table);
proc_create("decnet_neigh", S_IRUGO, init_net.proc_net,
&dn_neigh_seq_fops);
}
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 16acb59..205e147 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1292,7 +1292,7 @@ static int arp_proc_init(void);
void __init arp_init(void)
{
- neigh_table_init(&arp_tbl);
+ neigh_table_init(NEIGH_ARP_TABLE, &arp_tbl);
dev_add_pack(&arp_packet_type);
arp_proc_init();
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 4cb45c1..c67f339 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1763,7 +1763,7 @@ int __init ndisc_init(void)
/*
* Initialize the neighbour table
*/
- neigh_table_init(&nd_tbl);
+ neigh_table_init(NEIGH_ND_TABLE, &nd_tbl);
#ifdef CONFIG_SYSCTL
err = neigh_sysctl_register(NULL, &nd_tbl.parms,
^ permalink raw reply related
* Re: [Patch net-next] neigh: remove dynamic neigh table registration support
From: Cong Wang @ 2014-10-31 20:39 UTC (permalink / raw)
To: Cong Wang; +Cc: netdev, David S. Miller
In-Reply-To: <1414787651-8499-1-git-send-email-xiyou.wangcong@gmail.com>
On Fri, Oct 31, 2014 at 1:34 PM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> + switch (family) {
> + case AF_INET:
> + tbl = neigh_tables[NEIGH_ARP_TABLE];
> + break;
> +#if IS_ENABLED(CONFIG_IPV6)
> + case AF_INET6:
> + tbl = neigh_tables[NEIGH_ND_TABLE];
> + break;
> +#endif
> +#if IS_ENABLED(CONFIG_DECNET)
> + case AF_DECnet:
> + tbl = neigh_tables[NEIGH_DN_TABLE];
> + break;
> +#endif
These #ifdef's are not necessary, I will update it after getting other
feedbacks.
^ 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