Netdev List
 help / color / mirror / Atom feed
* VLAN HW accel, performance advantage?
From: Joakim Tjernlund @ 2013-09-03  9:05 UTC (permalink / raw)
  To: netdev

I am considering impl. VLAN HW acceleration in Freescales ucc_geth driver 
to improve
performance, primarily for bridged interfaces.
 I am hoping the community has some insights as to what performance gains 
one
could expect?

   Jocke

^ permalink raw reply

* Re: Is fallback vhost_net to qemu for live migrate available?
From: Wei Liu @ 2013-09-03  9:15 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Wei Liu, Qin Chuanyu, Anthony Liguori, jasowang, KVM list, netdev,
	qianhuibin, xen-devel@lists.xen.org, wangfuhai, likunyun,
	liuyongan, liuyingdong
In-Reply-To: <20130903085556.GD18901@redhat.com>

On Tue, Sep 03, 2013 at 11:55:56AM +0300, Michael S. Tsirkin wrote:
> On Tue, Sep 03, 2013 at 09:40:48AM +0100, Wei Liu wrote:
> > On Tue, Sep 03, 2013 at 09:28:11AM +0800, Qin Chuanyu wrote:
> > > On 2013/9/2 15:57, Wei Liu wrote:
> > > >On Sat, Aug 31, 2013 at 12:45:11PM +0800, Qin Chuanyu wrote:
> > > >>On 2013/8/30 0:08, Anthony Liguori wrote:
> > > >>>Hi Qin,
> > > >>
> > > >>>>By change the memory copy and notify mechanism ,currently virtio-net with
> > > >>>>vhost_net could run on Xen with good performance。
> > > >>>
> > > >>>I think the key in doing this would be to implement a property
> > > >>>ioeventfd and irqfd interface in the driver domain kernel.  Just
> > > >>>hacking vhost_net with Xen specific knowledge would be pretty nasty
> > > >>>IMHO.
> > > >>>
> > > >>Yes, I add a kernel module which persist virtio-net pio_addr and
> > > >>msix address as what kvm module did. Guest wake up vhost thread by
> > > >>adding a hook func in evtchn_interrupt.
> > > >>
> > > >>>Did you modify the front end driver to do grant table mapping or is
> > > >>>this all being done by mapping the domain's memory?
> > > >>>
> > > >>There is nothing changed in front end driver. Currently I use
> > > >>alloc_vm_area to get address space, and map the domain's memory as
> > > >>what what qemu did.
> > > >>
> > > >
> > > >You mean you're using xc_map_foreign_range and friends in the backend to
> > > >map guest memory? That's not very desirable as it violates Xen's
> > > >security model. It would not be too hard to pass grant references
> > > >instead of guest physical memory address IMHO.
> > > >
> > > In fact, I did what virtio-net have done in Qemu. I think security
> > > is a pseudo question because Dom0 is under control.
> > > 
> > 
> > Consider that you might have driver domains. Not every domain is under
> > control or trusted.
> 
> I don't see anything that will prevent using driver domains here.
> 

There is nothing technically stopping driver domains to work. It's about
the boundary of trust.

> > Also consider that security model like XSM can be
> > used to audit operations to enhance security so your foreign mapping
> > approach might not always work.
> 
> It could be nice to have as an option, sure.
> XSM is disabled by default though so I don't think lack of support for
> that makes it a prototype.
> 

XSM is there already, someone in a while might just want to give it a
shot despite it's not well supported. Then all of a sudden they find out
something works before (the foreign mapping backend) would not work
anymore. That would just lead to confusion. It's like a cycle of bad
things. Users try something lack of support -> it doesn't work -> users
won't use it anymore -> less support because nobody seems to be
interested.

> > In short term foreign mapping can save you some time implementing the
> > prototype.
> > In long term using grant table is the proper way to go. And
> > IMHO the benifit outweights the cost.
> > 
> > Wei.
> 
> I'm guessing direct access could be quite a bit faster.
> But someone would have to implement your idea in order to
> do a cost/benefit analysis.
> 

I'm not sure direct access will be faster. Either way hypervisor is
involved to update guest's page table.

Anyway, my point is, switching to grant table is not as hard as you
think - pass along grant refs instead of guest pseudo address in the
ring and use grant table API instead of foreign mapping API in the
backend.

Wei.

> > > Host could access memory of guest in KVM much easier than Xen,
> > > but I hadn't heard someone said KVM is un-secret.
> > > 
> > > Regards
> > > Qin chuanyu
> > > 
> > > 
> > > --
> > > To unsubscribe from this list: send the line "unsubscribe netdev" in
> > > the body of a message to majordomo@vger.kernel.org
> > > More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH net-next 1/1] qlcnic: Fix sparse warning.
From: Sucheta Chakraborty @ 2013-09-03  9:07 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept-HSGLinuxNICDev

This patch fixes warning "warning: symbol 'qlcnic_set_dcb_ops' was
not declared. Should it be static?"

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
index 2e10e79..d62d5ce 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
@@ -248,7 +248,7 @@ static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter *adapter)
 		adapter->netdev->dcbnl_ops = &qlcnic_dcbnl_ops;
 }
 
-void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
+static void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
 {
 	if (qlcnic_82xx_check(adapter))
 		adapter->dcb->ops = &qlcnic_82xx_dcb_ops;
-- 
1.8.1.4

^ permalink raw reply related

* Re: [PATCH net-next 5/6] bonding: restructure and simplify bond_for_each_slave_next()
From: Nikolay Aleksandrov @ 2013-09-03 10:22 UTC (permalink / raw)
  To: Ding Tianhong
  Cc: Jay Vosburgh, Andy Gospodarek, David S. Miller, Veaceslav Falico,
	Netdev
In-Reply-To: <52206E4E.6010507@huawei.com>

On 08/30/2013 12:05 PM, Ding Tianhong wrote:
> remove the wordy int and add bond_for_each_slave_next_rcu() for future use.
> 
> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
> Cc: Nikolay Aleksandrov <nikolay@redhat.com>
> ---
>  drivers/net/bonding/bond_alb.c  |  3 +--
>  drivers/net/bonding/bond_main.c |  6 ++----
>  drivers/net/bonding/bonding.h   | 19 +++++++++++++++----
>  3 files changed, 18 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
> index 3a5db7b..d266c56 100644
> --- a/drivers/net/bonding/bond_alb.c
> +++ b/drivers/net/bonding/bond_alb.c
> @@ -383,7 +383,6 @@ static struct slave *rlb_next_rx_slave(struct bonding *bond)
>  {
>  	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
>  	struct slave *rx_slave, *slave, *start_at;
> -	int i = 0;
>  
>  	if (bond_info->next_rx_slave)
>  		start_at = bond_info->next_rx_slave;
> @@ -392,7 +391,7 @@ static struct slave *rlb_next_rx_slave(struct bonding *bond)
>  
>  	rx_slave = NULL;
>  
> -	bond_for_each_slave_from(bond, slave, i, start_at) {
> +	bond_for_each_slave_from(bond, slave, start_at) {
>  		if (SLAVE_IS_OK(slave)) {
>  			if (!rx_slave) {
>  				rx_slave = slave;
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index 4264a76..8c9902a 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -904,7 +904,6 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
>  	struct slave *new_active, *old_active;
>  	struct slave *bestslave = NULL;
>  	int mintime = bond->params.updelay;
> -	int i;
>  
>  	new_active = bond->curr_active_slave;
>  
> @@ -923,7 +922,7 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
>  	/* remember where to stop iterating over the slaves */
>  	old_active = new_active;
>  
> -	bond_for_each_slave_from(bond, new_active, i, old_active) {
> +	bond_for_each_slave_from(bond, new_active, old_active) {
>  		if (new_active->link == BOND_LINK_UP) {
>  			return new_active;
>  		} else if (new_active->link == BOND_LINK_BACK &&
> @@ -2891,7 +2890,6 @@ do_failover:
>  static void bond_ab_arp_probe(struct bonding *bond)
>  {
>  	struct slave *slave, *next_slave;
> -	int i;
>  
>  	read_lock(&bond->curr_slave_lock);
>  
> @@ -2923,7 +2921,7 @@ static void bond_ab_arp_probe(struct bonding *bond)
>  
>  	/* search for next candidate */
>  	next_slave = bond_next_slave(bond, bond->current_arp_slave);
> -	bond_for_each_slave_from(bond, slave, i, next_slave) {
> +	bond_for_each_slave_from(bond, slave, next_slave) {
>  		if (IS_UP(slave->dev)) {
>  			slave->link = BOND_LINK_BACK;
>  			bond_set_slave_active_flags(slave);
> diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
> index 9898493..a3ab47f 100644
> --- a/drivers/net/bonding/bonding.h
> +++ b/drivers/net/bonding/bonding.h
> @@ -119,14 +119,25 @@
>   * bond_for_each_slave_from - iterate the slaves list from a starting point
>   * @bond:	the bond holding this list.
>   * @pos:	current slave.
> - * @cnt:	counter for max number of moves
>   * @start:	starting point.
>   *
>   * Caller must hold bond->lock
>   */
> -#define bond_for_each_slave_from(bond, pos, cnt, start) \
> -	for (cnt = 0, pos = start; pos && cnt < (bond)->slave_cnt; \
> -	     cnt++, pos = bond_next_slave(bond, pos))
> +#define bond_for_each_slave_from(bond, pos, start) \
> +	for (int cnt = 0, pos = start; pos && cnt < (bond)->slave_cnt; \
> +	    cnt++, pos = bond_next_slave(bond, pos))
> +
Please read below the argument against using the nested cnt definition.

> +/**
> + * bond_for_each_slave_from_rcu - iterate the slaves list from a starting point
> + * @bond:	the bond holding this list.
> + * @pos:	current slave.
> + * @start:	starting point.
> + *
> + * Caller must hold rcu_read_lock
> + */
> +#define bond_for_each_slave_from_rcu(bond, pos, start) \
> +	for (int cnt = 0, pos = start; pos && cnt < (bond)->slave_cnt; \
> +	    cnt++, pos = bond_next_slave_rcu(bond, pos))
>  
I don't think you can rely on slave_cnt in RCU, you may go overboard and pass
twice over the same slave if a slave gets removed, or the opposite. Also this
definition of cnt is troublesome because the name is quite common, I don't know
if it's accepted, but it if it is at least change the name to something like
__cnt or anything that is less likely to be defined.
The cnt argument goes for bond_for_each_slave_from as well.

>  /**
>   * bond_for_each_slave - iterate over all slaves
> 

^ permalink raw reply

* Re: [PATCH net-next 6/6] bonding: use RCU protection for alb xmit path
From: Nikolay Aleksandrov @ 2013-09-03 10:22 UTC (permalink / raw)
  To: Ding Tianhong
  Cc: Jay Vosburgh, Andy Gospodarek, David S. Miller, Veaceslav Falico,
	Netdev, Hideaki YOSHIFUJI
In-Reply-To: <52206E54.4040001@huawei.com>

On 08/30/2013 12:05 PM, Ding Tianhong wrote:
> The commit 278b20837511776dc9d5f6ee1c7fabd5479838bb
> (bonding: initial RCU conversion) has convert the roundrobin, active-backup,
> broadcast and xor xmit path to rcu protection, the performance will be better
> for these mode, so this time, convert xmit path for alb mode.
> 
> Suggested-by: Nikolay Aleksandrov <nikolay@redhat.com>
> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
> Cc: Nikolay Aleksandrov <nikolay@redhat.com>
> Cc: Veaceslav Falico <vfalico@redhat.com>
> ---
>  drivers/net/bonding/bond_alb.c | 20 +++++++++-----------
>  drivers/net/bonding/bonding.h  |  2 +-
>  2 files changed, 10 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
> index d266c56..e94a5d0 100644
> --- a/drivers/net/bonding/bond_alb.c
> +++ b/drivers/net/bonding/bond_alb.c
> @@ -229,7 +229,7 @@ static struct slave *tlb_get_least_loaded_slave(struct bonding *bond)
>  	max_gap = LLONG_MIN;
>  
>  	/* Find the slave with the largest gap */
> -	bond_for_each_slave(bond, slave) {
> +	bond_for_each_slave_rcu(bond, slave) {
>  		if (SLAVE_IS_OK(slave)) {
>  			long long gap = compute_gap(slave);
>  
> @@ -625,10 +625,12 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
>  {
>  	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
>  	struct arp_pkt *arp = arp_pkt(skb);
> -	struct slave *assigned_slave;
> +	struct slave *assigned_slave, *curr_active_slave;
>  	struct rlb_client_info *client_info;
>  	u32 hash_index = 0;
>  
> +	curr_active_slave = rcu_dereference(bond->curr_active_slave);
> +
I think this code is prone to a race condition with the slave removal, because
without the lock __bond_release_one() may think that it has done the LB release
(bond_alb_deinit_slave) and cleared the slave while you may set it after locking.
I guess you should move the dereference after the lock so to make sure that the
LB release hasn't passed (or it has and it'll be different).

>  	_lock_rx_hashtbl(bond);
>  
>  	hash_index = _simple_hash((u8 *)&arp->ip_dst, sizeof(arp->ip_dst));
> @@ -654,9 +656,9 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
>  			 * move the old client to primary (curr_active_slave) so
>  			 * that the new client can be assigned to this entry.
>  			 */
> -			if (bond->curr_active_slave &&
> -			    client_info->slave != bond->curr_active_slave) {
> -				client_info->slave = bond->curr_active_slave;
> +			if (curr_active_slave &&
> +			    client_info->slave != curr_active_slave) {
> +				client_info->slave = curr_active_slave;
>  				rlb_update_client(client_info);
>  			}
>  		}
> @@ -1336,8 +1338,6 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
>  
>  	/* make sure that the curr_active_slave do not change during tx
>  	 */
> -	read_lock(&bond->lock);
> -	read_lock(&bond->curr_slave_lock);
>  
>  	switch (ntohs(skb->protocol)) {
>  	case ETH_P_IP: {
> @@ -1420,12 +1420,12 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
>  
>  	if (!tx_slave) {
>  		/* unbalanced or unassigned, send through primary */
> -		tx_slave = bond->curr_active_slave;
> +		tx_slave = rcu_dereference(bond->curr_active_slave);
>  		bond_info->unbalanced_load += skb->len;
>  	}
>  
>  	if (tx_slave && SLAVE_IS_OK(tx_slave)) {
> -		if (tx_slave != bond->curr_active_slave) {
> +		if (tx_slave != rcu_dereference(bond->curr_active_slave)) {
>  			memcpy(eth_data->h_source,
>  			       tx_slave->dev->dev_addr,
>  			       ETH_ALEN);
> @@ -1440,8 +1440,6 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
>  		}
>  	}
>  
> -	read_unlock(&bond->curr_slave_lock);
> -	read_unlock(&bond->lock);
>  	if (res) {
>  		/* no suitable interface, frame not sent */
>  		kfree_skb(skb);
> diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
> index a3ab47f..9bc3af0 100644
> --- a/drivers/net/bonding/bonding.h
> +++ b/drivers/net/bonding/bonding.h
> @@ -536,7 +536,7 @@ static inline struct slave *bond_slave_has_mac(struct bonding *bond,
>  {
>  	struct slave *tmp;
>  
> -	bond_for_each_slave(bond, tmp)
> +	bond_for_each_slave_rcu(bond, tmp)
>  		if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
>  			return tmp;
>  
> 

^ permalink raw reply

* [PATCH net-next 0/2] net_random_N, reciprocal_divide helper updates
From: Daniel Borkmann @ 2013-09-03 10:26 UTC (permalink / raw)
  To: davem; +Cc: netdev

Introduce a net_random_N() helper instead of reimplementing it over and
over, plus use reciprocal_divide() helper instead of reimplementing it
as well.

Daniel Borkmann (2):
  net: introduce generic net_random_N helper
  net: use reciprocal_divide instead of reimplementing it

 drivers/net/team/team_mode_random.c | 7 +------
 include/linux/net.h                 | 7 +++++++
 include/net/red.h                   | 2 +-
 net/802/garp.c                      | 2 +-
 net/802/mrp.c                       | 2 +-
 net/core/dev.c                      | 2 +-
 net/core/flow_dissector.c           | 5 ++---
 net/ipv4/inet_hashtables.c          | 2 +-
 net/ipv4/netfilter/ipt_CLUSTERIP.c  | 2 +-
 net/ipv4/udp.c                      | 6 +++---
 net/ipv6/inet6_hashtables.c         | 2 +-
 net/ipv6/udp.c                      | 4 ++--
 net/netfilter/nf_conntrack_core.c   | 2 +-
 net/netfilter/nf_conntrack_expect.c | 2 +-
 net/netfilter/nf_nat_core.c         | 4 ++--
 net/netfilter/xt_HMARK.c            | 2 +-
 net/netfilter/xt_NFQUEUE.c          | 4 ++--
 net/netfilter/xt_cluster.c          | 2 +-
 net/netfilter/xt_hashlimit.c        | 2 +-
 net/packet/af_packet.c              | 2 +-
 net/sched/sch_choke.c               | 8 +-------
 net/sched/sch_fq_codel.c            | 2 +-
 22 files changed, 34 insertions(+), 39 deletions(-)

-- 
1.7.11.7

^ permalink raw reply

* [PATCH net-next 1/2] net: introduce generic net_random_N helper
From: Daniel Borkmann @ 2013-09-03 10:26 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <1378204010-27050-1-git-send-email-dborkman@redhat.com>

We have implemented the same function over and over, so introduce a
generic helper net_random_N() that unifies these implementations.
It internally used net_random() which eventually resolves to
prandom_u32(). Explicit include of reciprocal_div.h is not necessary.

Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 drivers/net/team/team_mode_random.c | 7 +------
 include/linux/net.h                 | 7 +++++++
 include/net/red.h                   | 2 +-
 net/802/garp.c                      | 2 +-
 net/802/mrp.c                       | 2 +-
 net/packet/af_packet.c              | 2 +-
 net/sched/sch_choke.c               | 8 +-------
 7 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/drivers/net/team/team_mode_random.c b/drivers/net/team/team_mode_random.c
index 7f032e2..b2294f8 100644
--- a/drivers/net/team/team_mode_random.c
+++ b/drivers/net/team/team_mode_random.c
@@ -16,17 +16,12 @@
 #include <linux/reciprocal_div.h>
 #include <linux/if_team.h>
 
-static u32 random_N(unsigned int N)
-{
-	return reciprocal_divide(prandom_u32(), N);
-}
-
 static bool rnd_transmit(struct team *team, struct sk_buff *skb)
 {
 	struct team_port *port;
 	int port_index;
 
-	port_index = random_N(team->en_port_count);
+	port_index = net_random_N(team->en_port_count);
 	port = team_get_port_by_index_rcu(team, port_index);
 	if (unlikely(!port))
 		goto drop;
diff --git a/include/linux/net.h b/include/linux/net.h
index 4f27575..86ffce7 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -24,6 +24,7 @@
 #include <linux/fcntl.h>	/* For O_CLOEXEC and O_NONBLOCK */
 #include <linux/kmemcheck.h>
 #include <linux/rcupdate.h>
+#include <linux/reciprocal_div.h>
 #include <uapi/linux/net.h>
 
 struct poll_table_struct;
@@ -243,6 +244,12 @@ do {								\
 #define net_random()		prandom_u32()
 #define net_srandom(seed)	prandom_seed((__force u32)(seed))
 
+/* deliver a random number between 0 and N - 1 */
+static inline u32 net_random_N(u32 N)
+{
+	return reciprocal_divide(net_random(), N);
+}
+
 extern int   	     kernel_sendmsg(struct socket *sock, struct msghdr *msg,
 				    struct kvec *vec, size_t num, size_t len);
 extern int   	     kernel_recvmsg(struct socket *sock, struct msghdr *msg,
diff --git a/include/net/red.h b/include/net/red.h
index ef46058..b17ed60 100644
--- a/include/net/red.h
+++ b/include/net/red.h
@@ -303,7 +303,7 @@ static inline unsigned long red_calc_qavg(const struct red_parms *p,
 
 static inline u32 red_random(const struct red_parms *p)
 {
-	return reciprocal_divide(net_random(), p->max_P_reciprocal);
+	return net_random_N(p->max_P_reciprocal);
 }
 
 static inline int red_mark_probability(const struct red_parms *p,
diff --git a/net/802/garp.c b/net/802/garp.c
index 5d9630a..c6fe7ca 100644
--- a/net/802/garp.c
+++ b/net/802/garp.c
@@ -397,7 +397,7 @@ static void garp_join_timer_arm(struct garp_applicant *app)
 {
 	unsigned long delay;
 
-	delay = (u64)msecs_to_jiffies(garp_join_time) * net_random() >> 32;
+	delay = net_random_N(msecs_to_jiffies(garp_join_time));
 	mod_timer(&app->join_timer, jiffies + delay);
 }
 
diff --git a/net/802/mrp.c b/net/802/mrp.c
index 1eb05d8..7338a7c 100644
--- a/net/802/mrp.c
+++ b/net/802/mrp.c
@@ -578,7 +578,7 @@ static void mrp_join_timer_arm(struct mrp_applicant *app)
 {
 	unsigned long delay;
 
-	delay = (u64)msecs_to_jiffies(mrp_join_time) * net_random() >> 32;
+	delay = net_random_N(msecs_to_jiffies(mrp_join_time));
 	mod_timer(&app->join_timer, jiffies + delay);
 }
 
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 2e8286b..7ac669e 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1162,7 +1162,7 @@ static unsigned int fanout_demux_rnd(struct packet_fanout *f,
 				     struct sk_buff *skb,
 				     unsigned int num)
 {
-	return reciprocal_divide(prandom_u32(), num);
+	return net_random_N(num);
 }
 
 static unsigned int fanout_demux_rollover(struct packet_fanout *f,
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
index ef53ab8..e19b20be 100644
--- a/net/sched/sch_choke.c
+++ b/net/sched/sch_choke.c
@@ -77,12 +77,6 @@ struct choke_sched_data {
 	struct sk_buff **tab;
 };
 
-/* deliver a random number between 0 and N - 1 */
-static u32 random_N(unsigned int N)
-{
-	return reciprocal_divide(prandom_u32(), N);
-}
-
 /* number of elements in queue including holes */
 static unsigned int choke_len(const struct choke_sched_data *q)
 {
@@ -233,7 +227,7 @@ static struct sk_buff *choke_peek_random(const struct choke_sched_data *q,
 	int retrys = 3;
 
 	do {
-		*pidx = (q->head + random_N(choke_len(q))) & q->tab_mask;
+		*pidx = (q->head + net_random_N(choke_len(q))) & q->tab_mask;
 		skb = q->tab[*pidx];
 		if (skb)
 			return skb;
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH net-next 2/2] net: use reciprocal_divide instead of reimplementing it
From: Daniel Borkmann @ 2013-09-03 10:26 UTC (permalink / raw)
  To: davem; +Cc: netdev, netfilter-devel
In-Reply-To: <1378204010-27050-1-git-send-email-dborkman@redhat.com>

Replace these places with reciprocal_divide() inline function instead of
reimplementing it each time, thus it will become easier to read. We do not
need to explicitly include its header as it's pulled in from linux/net.h
anyway.

Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Cc: netfilter-devel@vger.kernel.org
---
 net/core/dev.c                      | 2 +-
 net/core/flow_dissector.c           | 5 ++---
 net/ipv4/inet_hashtables.c          | 2 +-
 net/ipv4/netfilter/ipt_CLUSTERIP.c  | 2 +-
 net/ipv4/udp.c                      | 6 +++---
 net/ipv6/inet6_hashtables.c         | 2 +-
 net/ipv6/udp.c                      | 4 ++--
 net/netfilter/nf_conntrack_core.c   | 2 +-
 net/netfilter/nf_conntrack_expect.c | 2 +-
 net/netfilter/nf_nat_core.c         | 4 ++--
 net/netfilter/xt_HMARK.c            | 2 +-
 net/netfilter/xt_NFQUEUE.c          | 4 ++--
 net/netfilter/xt_cluster.c          | 2 +-
 net/netfilter/xt_hashlimit.c        | 2 +-
 net/sched/sch_fq_codel.c            | 2 +-
 15 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 6fbb0c9..bc7c839 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3040,7 +3040,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
 	}
 
 	if (map) {
-		tcpu = map->cpus[((u64) skb->rxhash * map->len) >> 32];
+		tcpu = map->cpus[reciprocal_divide(skb->rxhash, map->len)];
 
 		if (cpu_online(tcpu)) {
 			cpu = tcpu;
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 159737c..59521e0 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -233,7 +233,7 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb,
 		hash = (__force u16) skb->protocol;
 	hash = jhash_1word(hash, hashrnd);
 
-	return (u16) (((u64) hash * qcount) >> 32) + qoffset;
+	return (u16) reciprocal_divide(hash, qcount) + qoffset;
 }
 EXPORT_SYMBOL(__skb_tx_hash);
 
@@ -324,8 +324,7 @@ static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb)
 					hash = (__force u16) skb->protocol ^
 					    skb->rxhash;
 				hash = jhash_1word(hash, hashrnd);
-				queue_index = map->queues[
-				    ((u64)hash * map->len) >> 32];
+				queue_index = map->queues[reciprocal_divide(hash, map->len)];
 			}
 			if (unlikely(queue_index >= dev->real_num_tx_queues))
 				queue_index = -1;
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 7bd8983..731dcbf 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -204,7 +204,7 @@ begin:
 			}
 		} else if (score == hiscore && reuseport) {
 			matches++;
-			if (((u64)phash * matches) >> 32 == 0)
+			if (reciprocal_divide(phash, matches) == 0)
 				result = sk;
 			phash = next_pseudo_random32(phash);
 		}
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 0b732ef..0fede8b 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -273,7 +273,7 @@ clusterip_hashfn(const struct sk_buff *skb,
 	}
 
 	/* node numbers are 1..n, not 0..n */
-	return (((u64)hashval * config->num_total_nodes) >> 32) + 1;
+	return reciprocal_divide(hashval, config->num_total_nodes) + 1;
 }
 
 static inline int
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 74d2c95..5db0725 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -223,7 +223,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
 		remaining = (high - low) + 1;
 
 		rand = net_random();
-		first = (((u64)rand * remaining) >> 32) + low;
+		first = reciprocal_divide(rand, remaining) + low;
 		/*
 		 * force rand to be an odd multiple of UDP_HTABLE_SIZE
 		 */
@@ -435,7 +435,7 @@ begin:
 			}
 		} else if (score == badness && reuseport) {
 			matches++;
-			if (((u64)hash * matches) >> 32 == 0)
+			if (reciprocal_divide(hash, matches) == 0)
 				result = sk;
 			hash = next_pseudo_random32(hash);
 		}
@@ -516,7 +516,7 @@ begin:
 			}
 		} else if (score == badness && reuseport) {
 			matches++;
-			if (((u64)hash * matches) >> 32 == 0)
+			if (reciprocal_divide(hash, matches) == 0)
 				result = sk;
 			hash = next_pseudo_random32(hash);
 		}
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 32b4a16..d9d8908 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -187,7 +187,7 @@ begin:
 			}
 		} else if (score == hiscore && reuseport) {
 			matches++;
-			if (((u64)phash * matches) >> 32 == 0)
+			if (reciprocal_divide(phash, matches) == 0)
 				result = sk;
 			phash = next_pseudo_random32(phash);
 		}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index f405815..610013a 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -226,7 +226,7 @@ begin:
 				goto exact_match;
 		} else if (score == badness && reuseport) {
 			matches++;
-			if (((u64)hash * matches) >> 32 == 0)
+			if (reciprocal_divide(hash, matches) == 0)
 				result = sk;
 			hash = next_pseudo_random32(hash);
 		}
@@ -306,7 +306,7 @@ begin:
 			}
 		} else if (score == badness && reuseport) {
 			matches++;
-			if (((u64)hash * matches) >> 32 == 0)
+			if (reciprocal_divide(hash, matches) == 0)
 				result = sk;
 			hash = next_pseudo_random32(hash);
 		}
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 5d892fe..6378441 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -97,7 +97,7 @@ static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple, u16 zone)
 
 static u32 __hash_bucket(u32 hash, unsigned int size)
 {
-	return ((u64)hash * size) >> 32;
+	return reciprocal_divide(hash, size);
 }
 
 static u32 hash_bucket(u32 hash, const struct net *net)
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 4fd1ca9..c0865e6 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -83,7 +83,7 @@ static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple
 	hash = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
 		      (((tuple->dst.protonum ^ tuple->src.l3num) << 16) |
 		       (__force __u16)tuple->dst.u.all) ^ nf_conntrack_hash_rnd);
-	return ((u64)hash * nf_ct_expect_hsize) >> 32;
+	return reciprocal_divide(hash, nf_ct_expect_hsize);
 }
 
 struct nf_conntrack_expect *
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 6f0f4f7..ce9083e 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -126,7 +126,7 @@ hash_by_src(const struct net *net, u16 zone,
 	/* Original src, to ensure we map it consistently if poss. */
 	hash = jhash2((u32 *)&tuple->src, sizeof(tuple->src) / sizeof(u32),
 		      tuple->dst.protonum ^ zone ^ nf_conntrack_hash_rnd);
-	return ((u64)hash * net->ct.nat_htable_size) >> 32;
+	return reciprocal_divide(hash, net->ct.nat_htable_size);
 }
 
 /* Is this tuple already taken? (not by us) */
@@ -274,7 +274,7 @@ find_best_ips_proto(u16 zone, struct nf_conntrack_tuple *tuple,
 		}
 
 		var_ipp->all[i] = (__force __u32)
-			htonl(minip + (((u64)j * dist) >> 32));
+			htonl(minip + reciprocal_divide(j, dist));
 		if (var_ipp->all[i] != range->max_addr.all[i])
 			full_range = true;
 
diff --git a/net/netfilter/xt_HMARK.c b/net/netfilter/xt_HMARK.c
index 73b73f6..3dd05c4 100644
--- a/net/netfilter/xt_HMARK.c
+++ b/net/netfilter/xt_HMARK.c
@@ -126,7 +126,7 @@ hmark_hash(struct hmark_tuple *t, const struct xt_hmark_info *info)
 	hash = jhash_3words(src, dst, t->uports.v32, info->hashrnd);
 	hash = hash ^ (t->proto & info->proto_mask);
 
-	return (((u64)hash * info->hmodulus) >> 32) + info->hoffset;
+	return reciprocal_divide(hash, info->hmodulus) + info->hoffset;
 }
 
 static void
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c
index 1e2fae3..88443c1 100644
--- a/net/netfilter/xt_NFQUEUE.c
+++ b/net/netfilter/xt_NFQUEUE.c
@@ -83,10 +83,10 @@ nfqueue_hash(const struct sk_buff *skb, const struct xt_action_param *par)
 	u32 queue = info->queuenum;
 
 	if (par->family == NFPROTO_IPV4)
-		queue += ((u64) hash_v4(skb) * info->queues_total) >> 32;
+		queue += reciprocal_divide(hash_v4(skb), info->queues_total);
 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
 	else if (par->family == NFPROTO_IPV6)
-		queue += ((u64) hash_v6(skb) * info->queues_total) >> 32;
+		queue += reciprocal_divide(hash_v6(skb), info->queues_total);
 #endif
 
 	return queue;
diff --git a/net/netfilter/xt_cluster.c b/net/netfilter/xt_cluster.c
index f4af1bf..845fc16 100644
--- a/net/netfilter/xt_cluster.c
+++ b/net/netfilter/xt_cluster.c
@@ -55,7 +55,7 @@ xt_cluster_hash(const struct nf_conn *ct,
 		WARN_ON(1);
 		break;
 	}
-	return (((u64)hash * info->total_nodes) >> 32);
+	return reciprocal_divide(hash, info->total_nodes);
 }
 
 static inline bool
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 9ff035c..9af9021 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -135,7 +135,7 @@ hash_dst(const struct xt_hashlimit_htable *ht, const struct dsthash_dst *dst)
 	 * give results between [0 and cfg.size-1] and same hash distribution,
 	 * but using a multiply, less expensive than a divide
 	 */
-	return ((u64)hash * ht->cfg.size) >> 32;
+	return reciprocal_divide(hash, ht->cfg.size);
 }
 
 static struct dsthash_ent *
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index 5578628..4869671 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -77,7 +77,7 @@ static unsigned int fq_codel_hash(const struct fq_codel_sched_data *q,
 	hash = jhash_3words((__force u32)keys.dst,
 			    (__force u32)keys.src ^ keys.ip_proto,
 			    (__force u32)keys.ports, q->perturbation);
-	return ((u64)hash * q->flows_cnt) >> 32;
+	return reciprocal_divide(hash, q->flows_cnt);
 }
 
 static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch,
-- 
1.7.11.7

^ permalink raw reply related

* Re: [patch] caif: add a sanity check to the tty name
From: Dmitry Tarnyagin @ 2013-09-03 10:47 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: netdev, kernel-janitors
In-Reply-To: <20130903090232.GA4351@elgon.mountain>

Hi Dan,

Agree, thank you!

With best regards,
Dmitry

Den 03. sep. 2013 11:02, skrev Dan Carpenter:
> -	sprintf(name, "cf%s", tty->name);
> +	result = snprintf(name, sizeof(name), "cf%s", tty->name);
> +	if (result >= IFNAMSIZ)
> +		return -EINVAL;


^ permalink raw reply

* Re: [PATCH net-next 1/2] net: introduce generic net_random_N helper
From: Joe Perches @ 2013-09-03 11:00 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: davem, netdev, Theodore Ts'o
In-Reply-To: <1378204010-27050-2-git-send-email-dborkman@redhat.com>

On Tue, 2013-09-03 at 12:26 +0200, Daniel Borkmann wrote:
> We have implemented the same function over and over, so introduce a
> generic helper net_random_N() that unifies these implementations.
> It internally used net_random() which eventually resolves to
> prandom_u32(). Explicit include of reciprocal_div.h is not necessary.

Perhaps adding a generic helper to random.h like
	u32 prandom_u32_between(u32 low, u32 high);
or
	u32 prandom_u32_range(u32 bound1, u32 bound2)
would be better.

^ permalink raw reply

* [PATCH v2] ipv6: Don't depend on per socket memory for neighbour discovery messages
From: Thomas Graf @ 2013-09-03 11:37 UTC (permalink / raw)
  To: davem
  Cc: netdev, Eric Dumazet, Hannes Frederic Sowa, Stephen Warren,
	Fabio Estevam

Allocating skbs when sending out neighbour discovery messages
currently uses sock_alloc_send_skb() based on a per net namespace
socket and thus share a socket wmem buffer space.

If a netdevice is temporarily unable to transmit due to carrier
loss or for other reasons, the queued up ndisc messages will cosnume
all of the wmem space and will thus prevent from any more skbs to
be allocated even for netdevices that are able to transmit packets.

The number of neighbour discovery messages sent is very limited,
use of alloc_skb() bypasses the socket wmem buffer size enforcement
while the manual call to skb_set_owner_w() maintains the socket
reference needed for the IPv6 output path.

This patch has orginally been posted by Eric Dumazet in a modified
form.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Fabio Estevam <festevam@gmail.com>
---
 net/ipv6/ndisc.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

v2: Maintain socket reference to account for the IPv6 output path.
    Problem reported by Stephen Warren <swarren@wwwdotorg.org> and
    Fabio Estevam <festevam@gmail.com>.

    Tested on x86_64

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 04d31c2..78141fa 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -372,14 +372,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
 	int tlen = dev->needed_tailroom;
 	struct sock *sk = dev_net(dev)->ipv6.ndisc_sk;
 	struct sk_buff *skb;
-	int err;
 
-	skb = sock_alloc_send_skb(sk,
-				  hlen + sizeof(struct ipv6hdr) + len + tlen,
-				  1, &err);
+	skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC);
 	if (!skb) {
-		ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb, err=%d\n",
-			  __func__, err);
+		ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n",
+			  __func__);
 		return NULL;
 	}
 
@@ -389,6 +386,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
 	skb_reserve(skb, hlen + sizeof(struct ipv6hdr));
 	skb_reset_transport_header(skb);
 
+	/* Manually assign socket ownership as we avoid calling
+	 * sock_alloc_send_pskb() to bypass wmem buffer limits
+	 */
+	skb_set_owner_w(skb, sk);
+
 	return skb;
 }
 
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH net-next 1/2] net: introduce generic net_random_N helper
From: Daniel Borkmann @ 2013-09-03 11:40 UTC (permalink / raw)
  To: Joe Perches; +Cc: davem, netdev, Theodore Ts'o
In-Reply-To: <1378206045.2048.9.camel@joe-AO722>

On 09/03/2013 01:00 PM, Joe Perches wrote:
> On Tue, 2013-09-03 at 12:26 +0200, Daniel Borkmann wrote:
>> We have implemented the same function over and over, so introduce a
>> generic helper net_random_N() that unifies these implementations.
>> It internally used net_random() which eventually resolves to
>> prandom_u32(). Explicit include of reciprocal_div.h is not necessary.
>
> Perhaps adding a generic helper to random.h like
> 	u32 prandom_u32_between(u32 low, u32 high);
> or
> 	u32 prandom_u32_range(u32 bound1, u32 bound2)
> would be better.

Sure, this could be done as a follow-up. Once, we've migrated users to
the new API, follow-ups could go ahead to do the rest, and migration
will be easy. Note that the lower bound is 0 here.

^ permalink raw reply

* Re: [PATCH v2] ipv6: Don't depend on per socket memory for neighbour discovery messages
From: Hannes Frederic Sowa @ 2013-09-03 11:56 UTC (permalink / raw)
  To: Thomas Graf; +Cc: davem, netdev, Eric Dumazet, Stephen Warren, Fabio Estevam
In-Reply-To: <e4600dac657e1160da7a5e7758dcb973b616a10e.1378207925.git.tgraf@suug.ch>

Hi!

On Tue, Sep 03, 2013 at 01:37:01PM +0200, Thomas Graf wrote:
> @@ -389,6 +386,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
>  	skb_reserve(skb, hlen + sizeof(struct ipv6hdr));
>  	skb_reset_transport_header(skb);
>  
> +	/* Manually assign socket ownership as we avoid calling
> +	 * sock_alloc_send_pskb() to bypass wmem buffer limits
> +	 */
> +	skb_set_owner_w(skb, sk);
> +
>  	return skb;
>  }

Do you know why this is needed? From the report it seemed to me that we might
have a deadlock on idev->lock and I couldn't find the culprit.

When I tested your change on x86_64 I did not experience this.

Maybe someone with arm could try this patch with CONFIG_PROVE_LOCKING?

Thanks,

  Hannes

^ permalink raw reply

* [PATCH v2 1/2] atm: nicstar: re-use native mac_pton() helper
From: Andy Shevchenko @ 2013-09-03 12:13 UTC (permalink / raw)
  To: Chas Williams, linux-atm-general, inux Net Dev, David S . Miller
  Cc: Andy Shevchenko

From: Andy Shevchenko <andy.shevchenko@gmail.com>

There is a nice helper to parse MAC. Let's use it and remove custom
implementation.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/atm/nicstar.c | 26 +-------------------------
 1 file changed, 1 insertion(+), 25 deletions(-)

diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 6587dc2..409502a 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -153,7 +153,6 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg);
 static void which_list(ns_dev * card, struct sk_buff *skb);
 #endif
 static void ns_poll(unsigned long arg);
-static int ns_parse_mac(char *mac, unsigned char *esi);
 static void ns_phy_put(struct atm_dev *dev, unsigned char value,
 		       unsigned long addr);
 static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr);
@@ -779,7 +778,7 @@ static int ns_init_card(int i, struct pci_dev *pcidev)
 		return error;
 	}
 
-	if (ns_parse_mac(mac[i], card->atmdev->esi)) {
+	if (mac[i] == NULL || mac_pton(mac[i], card->atmdev->esi)) {
 		nicstar_read_eprom(card->membase, NICSTAR_EPROM_MAC_ADDR_OFFSET,
 				   card->atmdev->esi, 6);
 		if (memcmp(card->atmdev->esi, "\x00\x00\x00\x00\x00\x00", 6) ==
@@ -2802,29 +2801,6 @@ static void ns_poll(unsigned long arg)
 	PRINTK("nicstar: Leaving ns_poll().\n");
 }
 
-static int ns_parse_mac(char *mac, unsigned char *esi)
-{
-	int i, j;
-	short byte1, byte0;
-
-	if (mac == NULL || esi == NULL)
-		return -1;
-	j = 0;
-	for (i = 0; i < 6; i++) {
-		if ((byte1 = hex_to_bin(mac[j++])) < 0)
-			return -1;
-		if ((byte0 = hex_to_bin(mac[j++])) < 0)
-			return -1;
-		esi[i] = (unsigned char)(byte1 * 16 + byte0);
-		if (i < 5) {
-			if (mac[j++] != ':')
-				return -1;
-		}
-	}
-	return 0;
-}
-
-
 static void ns_phy_put(struct atm_dev *dev, unsigned char value,
 		       unsigned long addr)
 {
-- 
1.8.4.rc3

^ permalink raw reply related

* [PATCH v2 2/2] atm: he: print MAC via %pM
From: Andy Shevchenko @ 2013-09-03 12:13 UTC (permalink / raw)
  To: Chas Williams, linux-atm-general, inux Net Dev, David S . Miller
  Cc: Andy Shevchenko
In-Reply-To: <1378210424-14781-1-git-send-email-andriy.shevchenko@linux.intel.com>

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/atm/he.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 80f9743..c232dd3 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -1088,15 +1088,8 @@ static int he_start(struct atm_dev *dev)
 	for (i = 0; i < 6; ++i)
 		dev->esi[i] = read_prom_byte(he_dev, MAC_ADDR + i);
 
-	hprintk("%s%s, %x:%x:%x:%x:%x:%x\n",
-				he_dev->prod_id,
-					he_dev->media & 0x40 ? "SM" : "MM",
-						dev->esi[0],
-						dev->esi[1],
-						dev->esi[2],
-						dev->esi[3],
-						dev->esi[4],
-						dev->esi[5]);
+	hprintk("%s%s, %*pM\n", he_dev->prod_id,
+		he_dev->media & 0x40 ? "SM" : "MM", dev->esi);
 	he_dev->atm_dev->link_rate = he_is622(he_dev) ?
 						ATM_OC12_PCR : ATM_OC3_PCR;
 
-- 
1.8.4.rc3

^ permalink raw reply related

* Re: [PATCH net-next 1/2] net: introduce generic net_random_N helper
From: Joe Perches @ 2013-09-03 12:15 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: davem, netdev, Theodore Ts'o
In-Reply-To: <5225CAB1.7080402@redhat.com>

On Tue, 2013-09-03 at 13:40 +0200, Daniel Borkmann wrote:
> On 09/03/2013 01:00 PM, Joe Perches wrote:
> > On Tue, 2013-09-03 at 12:26 +0200, Daniel Borkmann wrote:
> >> We have implemented the same function over and over, so introduce a
> >> generic helper net_random_N() that unifies these implementations.
> >> It internally used net_random() which eventually resolves to
> >> prandom_u32(). Explicit include of reciprocal_div.h is not necessary.
> >
> > Perhaps adding a generic helper to random.h like
> > 	u32 prandom_u32_between(u32 low, u32 high);
> > or
> > 	u32 prandom_u32_range(u32 bound1, u32 bound2)
> > would be better.
> 
> Sure, this could be done as a follow-up. Once, we've migrated users to
> the new API, follow-ups could go ahead to do the rest, and migration
> will be easy. Note that the lower bound is 0 here.

Part of the reason I suggested this it to make the
API more readable/intelligible.

At first glance, I have no idea what net_random_N does.

I think #define net_random() prandom_u32()
should be removed eventually as well.

If gcc doesn't already do this optimization,
perhaps there are also some use of
	net_random() % non_const
that could be optimized a bit using this API.

$ git grep -E "(prandom_u32|net_random)\s*\(\s*\)\s*\%" net
net/batman-adv/bat_iv_ogm.c:	msecs += prandom_u32() % (2 * BATADV_JITTER);
net/batman-adv/bat_iv_ogm.c:	return jiffies + msecs_to_jiffies(prandom_u32() % (BATADV_JITTER / 2));
net/core/neighbour.c:	return base ? (net_random() % base) + (base >> 1) : 0;
net/core/neighbour.c:	unsigned long sched_next = now + (net_random() % p->proxy_delay);
net/core/pktgen.c:		flow = prandom_u32() % pkt_dev->cflows;
net/core/pktgen.c:			t = prandom_u32() %
net/core/pktgen.c:			mc = prandom_u32() % pkt_dev->src_mac_count;
net/core/pktgen.c:			mc = prandom_u32() % pkt_dev->dst_mac_count;
net/core/pktgen.c:			pkt_dev->cur_udp_src = prandom_u32() %
net/core/pktgen.c:			pkt_dev->cur_udp_dst = prandom_u32() %
net/core/pktgen.c:				t = prandom_u32() % (imx - imn) + imn;
net/core/pktgen.c:						t = prandom_u32() %
net/core/pktgen.c:			t = prandom_u32() %
net/core/stream.c:		current_timeo = vm_wait = (net_random() % (HZ / 5)) + 2;
net/ipv4/igmp.c:	int tv = net_random() % max_delay;
net/ipv4/igmp.c:	int tv = net_random() % in_dev->mr_maxdelay;
net/ipv4/igmp.c:	int tv = net_random() % delay;
net/ipv4/inet_connection_sock.c:		smallest_rover = rover = net_random() % remaining + low;
net/ipv6/addrconf.c:		rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1);
net/ipv6/mcast.c:	unsigned long tv = net_random() % idev->mc_maxdelay;
net/ipv6/mcast.c:	unsigned long tv = net_random() % delay;
net/ipv6/mcast.c:	unsigned long tv = net_random() % delay;
net/ipv6/mcast.c:			delay = net_random() % resptime;
net/ipv6/mcast.c:	delay = net_random() % unsolicited_report_interval(ma->idev);
net/netfilter/nf_conntrack_core.c:			(prandom_u32() % net->ct.sysctl_events_retry_timeout);
net/netfilter/nf_conntrack_core.c:		(prandom_u32() % net->ct.sysctl_events_retry_timeout);
net/sched/act_gact.c:	if (!gact->tcfg_pval || net_random() % gact->tcfg_pval)
net/sched/sch_netem.c:		skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8);
net/sctp/socket.c:		rover = net_random() % remaining + low;
net/sunrpc/xprtsock.c:	unsigned short rand = (unsigned short) net_random() % range;
net/xfrm/xfrm_state.c:			spi = low + net_random()%(high-low+1);

^ permalink raw reply

* [PATCH v2.1] atm: he: print MAC via %pM
From: Andy Shevchenko @ 2013-09-03 12:17 UTC (permalink / raw)
  To: Chas Williams, linux-atm-general, netdev, David S . Miller
  Cc: Andy Shevchenko
In-Reply-To: <1378210424-14781-2-git-send-email-andriy.shevchenko@linux.intel.com>

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/atm/he.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 80f9743..8557adc 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -1088,15 +1088,8 @@ static int he_start(struct atm_dev *dev)
 	for (i = 0; i < 6; ++i)
 		dev->esi[i] = read_prom_byte(he_dev, MAC_ADDR + i);
 
-	hprintk("%s%s, %x:%x:%x:%x:%x:%x\n",
-				he_dev->prod_id,
-					he_dev->media & 0x40 ? "SM" : "MM",
-						dev->esi[0],
-						dev->esi[1],
-						dev->esi[2],
-						dev->esi[3],
-						dev->esi[4],
-						dev->esi[5]);
+	hprintk("%s%s, %pM\n", he_dev->prod_id,
+		he_dev->media & 0x40 ? "SM" : "MM", dev->esi);
 	he_dev->atm_dev->link_rate = he_is622(he_dev) ?
 						ATM_OC12_PCR : ATM_OC3_PCR;
 
-- 
1.8.4.rc3

^ permalink raw reply related

* Re: [PATCH v2] ipv6: Don't depend on per socket memory for neighbour discovery messages
From: Fabio Estevam @ 2013-09-03 12:18 UTC (permalink / raw)
  To: Thomas Graf
  Cc: David S. Miller, netdev@vger.kernel.org, Eric Dumazet,
	Hannes Frederic Sowa, Stephen Warren
In-Reply-To: <e4600dac657e1160da7a5e7758dcb973b616a10e.1378207925.git.tgraf@suug.ch>

On Tue, Sep 3, 2013 at 8:37 AM, Thomas Graf <tgraf@suug.ch> wrote:
> Allocating skbs when sending out neighbour discovery messages
> currently uses sock_alloc_send_skb() based on a per net namespace
> socket and thus share a socket wmem buffer space.
>
> If a netdevice is temporarily unable to transmit due to carrier
> loss or for other reasons, the queued up ndisc messages will cosnume
> all of the wmem space and will thus prevent from any more skbs to
> be allocated even for netdevices that are able to transmit packets.
>
> The number of neighbour discovery messages sent is very limited,
> use of alloc_skb() bypasses the socket wmem buffer size enforcement
> while the manual call to skb_set_owner_w() maintains the socket
> reference needed for the IPv6 output path.
>
> This patch has orginally been posted by Eric Dumazet in a modified
> form.
>
> Signed-off-by: Thomas Graf <tgraf@suug.ch>
> Cc: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
> Cc: Stephen Warren <swarren@wwwdotorg.org>
> Cc: Fabio Estevam <festevam@gmail.com>

I don't get the system hang that I used to see with the previous
version on my ARM board, so

Tested-by: Fabio Estevam <fabio.estevam@freescale.com>

^ permalink raw reply

* Re: [PATCH v2 2/2] atm: he: print MAC via %pM
From: Joe Perches @ 2013-09-03 12:20 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Chas Williams, linux-atm-general, inux Net Dev, David S . Miller
In-Reply-To: <1378210424-14781-2-git-send-email-andriy.shevchenko@linux.intel.com>

On Tue, 2013-09-03 at 15:13 +0300, Andy Shevchenko wrote:
[]
> diff --git a/drivers/atm/he.c b/drivers/atm/he.c
[]
> @@ -1088,15 +1088,8 @@ static int he_start(struct atm_dev *dev)
>  	for (i = 0; i < 6; ++i)
>  		dev->esi[i] = read_prom_byte(he_dev, MAC_ADDR + i);
>  
> -	hprintk("%s%s, %x:%x:%x:%x:%x:%x\n",
> -				he_dev->prod_id,
> -					he_dev->media & 0x40 ? "SM" : "MM",
> -						dev->esi[0],
> -						dev->esi[1],
> -						dev->esi[2],
> -						dev->esi[3],
> -						dev->esi[4],
> -						dev->esi[5]);
> +	hprintk("%s%s, %*pM\n", he_dev->prod_id,
> +		he_dev->media & 0x40 ? "SM" : "MM", dev->esi);

%*pM?

Did this compile cleanly?

^ permalink raw reply

* Re: [PATCH v2 2/2] atm: he: print MAC via %pM
From: Andy Shevchenko @ 2013-09-03 12:25 UTC (permalink / raw)
  To: Joe Perches
  Cc: Chas Williams, linux-atm-general, inux Net Dev, David S . Miller
In-Reply-To: <1378210806.2048.23.camel@joe-AO722>

On Tue, 2013-09-03 at 05:20 -0700, Joe Perches wrote: 
> On Tue, 2013-09-03 at 15:13 +0300, Andy Shevchenko wrote:
> []
> > diff --git a/drivers/atm/he.c b/drivers/atm/he.c
> []
> > @@ -1088,15 +1088,8 @@ static int he_start(struct atm_dev *dev)
> >  	for (i = 0; i < 6; ++i)
> >  		dev->esi[i] = read_prom_byte(he_dev, MAC_ADDR + i);
> >  
> > -	hprintk("%s%s, %x:%x:%x:%x:%x:%x\n",
> > -				he_dev->prod_id,
> > -					he_dev->media & 0x40 ? "SM" : "MM",
> > -						dev->esi[0],
> > -						dev->esi[1],
> > -						dev->esi[2],
> > -						dev->esi[3],
> > -						dev->esi[4],
> > -						dev->esi[5]);
> > +	hprintk("%s%s, %*pM\n", he_dev->prod_id,
> > +		he_dev->media & 0x40 ? "SM" : "MM", dev->esi);
> 
> %*pM?
> 
> Did this compile cleanly?

See v2.1 of this patch, and sorry for this typo.

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply

* Re: [PATCH net-next 1/2] net: introduce generic net_random_N helper
From: Daniel Borkmann @ 2013-09-03 12:26 UTC (permalink / raw)
  To: Joe Perches; +Cc: davem, netdev, Theodore Ts'o
In-Reply-To: <1378210546.2048.20.camel@joe-AO722>

On 09/03/2013 02:15 PM, Joe Perches wrote:
> On Tue, 2013-09-03 at 13:40 +0200, Daniel Borkmann wrote:
>> On 09/03/2013 01:00 PM, Joe Perches wrote:
>>> On Tue, 2013-09-03 at 12:26 +0200, Daniel Borkmann wrote:
>>>> We have implemented the same function over and over, so introduce a
>>>> generic helper net_random_N() that unifies these implementations.
>>>> It internally used net_random() which eventually resolves to
>>>> prandom_u32(). Explicit include of reciprocal_div.h is not necessary.
>>>
>>> Perhaps adding a generic helper to random.h like
>>> 	u32 prandom_u32_between(u32 low, u32 high);
>>> or
>>> 	u32 prandom_u32_range(u32 bound1, u32 bound2)
>>> would be better.
>>
>> Sure, this could be done as a follow-up. Once, we've migrated users to
>> the new API, follow-ups could go ahead to do the rest, and migration
>> will be easy. Note that the lower bound is 0 here.
>
> Part of the reason I suggested this it to make the
> API more readable/intelligible.
>
> At first glance, I have no idea what net_random_N does.
>
> I think #define net_random() prandom_u32()
> should be removed eventually as well.

Why? Assume there could be different PRNGs in future that have different properties
(e.g. speed vs. period, etc). Then, changing net_random() to something else is way
easier and less error-prone than searching through the whole subtree of net and
replacing every occurrence of prandom_u32().

> If gcc doesn't already do this optimization,
> perhaps there are also some use of
> 	net_random() % non_const
> that could be optimized a bit using this API.

I agree with you, needs to be evaluated on a case by case basis for future work.

> $ git grep -E "(prandom_u32|net_random)\s*\(\s*\)\s*\%" net
> net/batman-adv/bat_iv_ogm.c:	msecs += prandom_u32() % (2 * BATADV_JITTER);
> net/batman-adv/bat_iv_ogm.c:	return jiffies + msecs_to_jiffies(prandom_u32() % (BATADV_JITTER / 2));
> net/core/neighbour.c:	return base ? (net_random() % base) + (base >> 1) : 0;
> net/core/neighbour.c:	unsigned long sched_next = now + (net_random() % p->proxy_delay);
> net/core/pktgen.c:		flow = prandom_u32() % pkt_dev->cflows;
> net/core/pktgen.c:			t = prandom_u32() %
> net/core/pktgen.c:			mc = prandom_u32() % pkt_dev->src_mac_count;
> net/core/pktgen.c:			mc = prandom_u32() % pkt_dev->dst_mac_count;
> net/core/pktgen.c:			pkt_dev->cur_udp_src = prandom_u32() %
> net/core/pktgen.c:			pkt_dev->cur_udp_dst = prandom_u32() %
> net/core/pktgen.c:				t = prandom_u32() % (imx - imn) + imn;
> net/core/pktgen.c:						t = prandom_u32() %
> net/core/pktgen.c:			t = prandom_u32() %
> net/core/stream.c:		current_timeo = vm_wait = (net_random() % (HZ / 5)) + 2;
> net/ipv4/igmp.c:	int tv = net_random() % max_delay;
> net/ipv4/igmp.c:	int tv = net_random() % in_dev->mr_maxdelay;
> net/ipv4/igmp.c:	int tv = net_random() % delay;
> net/ipv4/inet_connection_sock.c:		smallest_rover = rover = net_random() % remaining + low;
> net/ipv6/addrconf.c:		rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1);
> net/ipv6/mcast.c:	unsigned long tv = net_random() % idev->mc_maxdelay;
> net/ipv6/mcast.c:	unsigned long tv = net_random() % delay;
> net/ipv6/mcast.c:	unsigned long tv = net_random() % delay;
> net/ipv6/mcast.c:			delay = net_random() % resptime;
> net/ipv6/mcast.c:	delay = net_random() % unsolicited_report_interval(ma->idev);
> net/netfilter/nf_conntrack_core.c:			(prandom_u32() % net->ct.sysctl_events_retry_timeout);
> net/netfilter/nf_conntrack_core.c:		(prandom_u32() % net->ct.sysctl_events_retry_timeout);
> net/sched/act_gact.c:	if (!gact->tcfg_pval || net_random() % gact->tcfg_pval)
> net/sched/sch_netem.c:		skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8);
> net/sctp/socket.c:		rover = net_random() % remaining + low;
> net/sunrpc/xprtsock.c:	unsigned short rand = (unsigned short) net_random() % range;
> net/xfrm/xfrm_state.c:			spi = low + net_random()%(high-low+1);
>
>

^ permalink raw reply

* Re: [PATCH v2] ipv6: Don't depend on per socket memory for neighbour discovery messages
From: Thomas Graf @ 2013-09-03 12:11 UTC (permalink / raw)
  To: davem, netdev, Eric Dumazet, Stephen Warren, Fabio Estevam
In-Reply-To: <20130903115635.GA21729@order.stressinduktion.org>

On 09/03/13 at 01:56pm, Hannes Frederic Sowa wrote:
> Hi!
> 
> On Tue, Sep 03, 2013 at 01:37:01PM +0200, Thomas Graf wrote:
> > @@ -389,6 +386,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
> >  	skb_reserve(skb, hlen + sizeof(struct ipv6hdr));
> >  	skb_reset_transport_header(skb);
> >  
> > +	/* Manually assign socket ownership as we avoid calling
> > +	 * sock_alloc_send_pskb() to bypass wmem buffer limits
> > +	 */
> > +	skb_set_owner_w(skb, sk);
> > +
> >  	return skb;
> >  }
> 
> Do you know why this is needed? From the report it seemed to me that we might
> have a deadlock on idev->lock and I couldn't find the culprit.
> 
> When I tested your change on x86_64 I did not experience this.

I also didn't see any problems running v1 of the patch which
is confusing as the IPv6 output path assumes a socket reference
in various places as Dave pointed out correctly.

I don't see why the problem would be limited to ARM.

> Maybe someone with arm could try this patch with CONFIG_PROVE_LOCKING?

I would certainly welcome that.

^ permalink raw reply

* Re: [PATCH net-next 1/2] net: introduce generic net_random_N helper
From: Joe Perches @ 2013-09-03 12:41 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: davem, netdev, Theodore Ts'o
In-Reply-To: <5225D583.9090404@redhat.com>

On Tue, 2013-09-03 at 14:26 +0200, Daniel Borkmann wrote:
> On 09/03/2013 02:15 PM, Joe Perches wrote:
> > I think #define net_random() prandom_u32()
> > should be removed eventually as well.
> 
> Why? Assume there could be different PRNGs in future that have different properties
> (e.g. speed vs. period, etc). Then, changing net_random() to something else is way
> easier and less error-prone than searching through the whole subtree of net and
> replacing every occurrence of prandom_u32().

Maybe.  There are already instances of prandom_u32
in the net tree.  I don't find value in the indirection.

Akinobu Mita once posted a s/net_random/prandom_u32/
patch: https://lkml.org/lkml/2012/12/23/140

> > If gcc doesn't already do this optimization,
> > perhaps there are also some use of
> > 	net_random() % non_const
> > that could be optimized a bit using this API.
> 
> I agree with you, needs to be evaluated on a case by case basis for future work.

__builtin_constant_p is useful.

^ permalink raw reply

* [PATCH] rt2x00: Add WLI-UC-G300HP's Product ID
From: Masami Ichikawa @ 2013-09-03 12:51 UTC (permalink / raw)
  To: kvalo, IvDoorn, gwingerde, helmut.schaa, linville
  Cc: Masami Ichikawa, linux-wireless, users, netdev, linux-kernel

Support Bufallo WLI-UC-G300HP.

Signed-off-by: Masami Ichikawa <masami256@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800usb.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 840833b..518277d 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -977,6 +977,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
 	{ USB_DEVICE(0x0411, 0x016f) },
 	{ USB_DEVICE(0x0411, 0x01a2) },
 	{ USB_DEVICE(0x0411, 0x01ee) },
+	{ USB_DEVICE(0x0411, 0x01a8) },
 	/* Corega */
 	{ USB_DEVICE(0x07aa, 0x002f) },
 	{ USB_DEVICE(0x07aa, 0x003c) },
-- 
1.8.3.1

^ permalink raw reply related

* Re: VLAN HW accel, performance advantage?
From: Ben Hutchings @ 2013-09-03 13:50 UTC (permalink / raw)
  To: Joakim Tjernlund; +Cc: netdev
In-Reply-To: <OF00E35E7C.7482EC01-ONC1257BDB.00314AD0-C1257BDB.0031F6D0@transmode.se>

On Tue, 2013-09-03 at 11:05 +0200, Joakim Tjernlund wrote:
> I am considering impl. VLAN HW acceleration in Freescales ucc_geth driver 
> to improve
> performance, primarily for bridged interfaces.
>  I am hoping the community has some insights as to what performance gains 
> one
> could expect?

At the moment you need to do VLAN RX offload (or fake it in software) to
take advantage of GRO for VLAN-encapsulated packets.  Other than that, I
don't think it makes a lot of difference in most situations.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox