Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] sky2: set carrier off in probe
From: Herbert Xu @ 2009-10-30 18:16 UTC (permalink / raw)
  To: David Miller; +Cc: bphilips, shemminger, netdev
In-Reply-To: <20091030.111027.234994529.davem@davemloft.net>

On Fri, Oct 30, 2009 at 11:10:27AM -0700, David Miller wrote:
. 
> Because the driver must start in state with carrier off anyways,
> so that we get the transition event when the device comes up
> from link down to link up.

Well we want all drivers to start in state NOCARRIER.  However,
a freshly allocated netdev has the NOCARRIER bit off.  This means
every single driver has to set the NOCARRIER bit.

It would seem much easier to ensure that the NOCARRIER bit is set
in a newly allocated netdev.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH] sky2: set carrier off in probe
From: David Miller @ 2009-10-30 18:20 UTC (permalink / raw)
  To: herbert; +Cc: bphilips, shemminger, netdev
In-Reply-To: <20091030181632.GA9530@gondor.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri, 30 Oct 2009 14:16:32 -0400

> On Fri, Oct 30, 2009 at 11:10:27AM -0700, David Miller wrote:
> . 
>> Because the driver must start in state with carrier off anyways,
>> so that we get the transition event when the device comes up
>> from link down to link up.
> 
> Well we want all drivers to start in state NOCARRIER.  However,
> a freshly allocated netdev has the NOCARRIER bit off.  This means
> every single driver has to set the NOCARRIER bit.
> 
> It would seem much easier to ensure that the NOCARRIER bit is set
> in a newly allocated netdev.

Since many drivers (especially virtual software ones) do not manage
carrier state and therefore that's why we start in state carrier on.

We've had this discussion a few times before, most recently with
Rusty wrt. virtio :-)

^ permalink raw reply

* Re: RFC: netdev: allow ethtool physical id to drop rtnl_lock
From: Stephen Hemminger @ 2009-10-30 18:30 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <4AEB26BB.1050007@gmail.com>

On Fri, 30 Oct 2009 18:47:39 +0100
Eric Dumazet <eric.dumazet@gmail.com> wrote:

> Stephen Hemminger a écrit :
> > The ethtool operation to blink LED can take an indeterminately long time,
> > blocking out other operations (via rtnl_lock). This patch is an attempt
> > to work around the problem.
> > 
> > It does need more discussion, because it will mean that drivers that formerly
> > were protected from changes during blink aren't.  For example, user could
> > start device blinking, and then plug in cable causing change netlink event
> > to change state or pull cable and have device come down.
> > 
> > The other possibility is to do this on a driver by driver basis
> > which is more effort.
> > 
> > Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> > 
> > 
> > --- a/net/core/ethtool.c	2009-10-30 10:27:23.621917624 -0700
> > +++ b/net/core/ethtool.c	2009-10-30 10:35:53.787670774 -0700
> > @@ -17,6 +17,7 @@
> >  #include <linux/errno.h>
> >  #include <linux/ethtool.h>
> >  #include <linux/netdevice.h>
> > +#include <linux/rtnetlink.h>
> >  #include <asm/uaccess.h>
> >  
> >  /*
> > @@ -781,6 +782,8 @@ static int ethtool_get_strings(struct ne
> >  static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
> >  {
> >  	struct ethtool_value id;
> > +	int err;
> > +	static int busy;
> >  
> >  	if (!dev->ethtool_ops->phys_id)
> >  		return -EOPNOTSUPP;
> > @@ -788,7 +791,21 @@ static int ethtool_phys_id(struct net_de
> >  	if (copy_from_user(&id, useraddr, sizeof(id)))
> >  		return -EFAULT;
> >  
> > -	return dev->ethtool_ops->phys_id(dev, id.data);
> > +	if (busy)
> > +		return -EBUSY;
> > +
> > +	/* This operation may take a long time, drop lock */
> > +	busy = 1;
> > +	dev_hold(dev);
> > +	rtnl_unlock();
> > +
> > +	err = dev->ethtool_ops->phys_id(dev, id.data);
> > +
> > +	rtnl_lock();
> > +	dev_put(dev);
> > +	busy = 0;
> > +
> > +	return err;
> >  }
> >  
> 
> It seems reasonable, but why have a global 'busy' flag, and not
> private to each netdev ?
> 

Because that is what old behaviour was (one blink at a time).


-- 

^ permalink raw reply

* [PATCH 3/5] RDS: Fix panic on unload
From: Andy Grover @ 2009-10-30 18:51 UTC (permalink / raw)
  To: netdev; +Cc: rds-devel
In-Reply-To: <1256928717-17757-1-git-send-email-andy.grover@oracle.com>

Remove explicit destruction of passive connection when destroying
active end of the connection. The passive end is also on the
device's connection list, and will thus be cleaned up properly.
Panic was caused by trying to clean it up twice.

Signed-off-by: Andy Grover <andy.grover@oracle.com>
---
 net/rds/ib_rdma.c |    5 +----
 net/rds/iw_rdma.c |    5 +----
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c
index ef3ab5b..c5e9165 100644
--- a/net/rds/ib_rdma.c
+++ b/net/rds/ib_rdma.c
@@ -187,11 +187,8 @@ void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock)
 	INIT_LIST_HEAD(list);
 	spin_unlock_irq(list_lock);
 
-	list_for_each_entry_safe(ic, _ic, &tmp_list, ib_node) {
-		if (ic->conn->c_passive)
-			rds_conn_destroy(ic->conn->c_passive);
+	list_for_each_entry_safe(ic, _ic, &tmp_list, ib_node)
 		rds_conn_destroy(ic->conn);
-	}
 }
 
 struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *rds_ibdev)
diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c
index de4a1b1..b25d785 100644
--- a/net/rds/iw_rdma.c
+++ b/net/rds/iw_rdma.c
@@ -245,11 +245,8 @@ void __rds_iw_destroy_conns(struct list_head *list, spinlock_t *list_lock)
 	INIT_LIST_HEAD(list);
 	spin_unlock_irq(list_lock);
 
-	list_for_each_entry_safe(ic, _ic, &tmp_list, iw_node) {
-		if (ic->conn->c_passive)
-			rds_conn_destroy(ic->conn->c_passive);
+	list_for_each_entry_safe(ic, _ic, &tmp_list, iw_node)
 		rds_conn_destroy(ic->conn);
-	}
 }
 
 static void rds_iw_set_scatterlist(struct rds_iw_scatterlist *sg,
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 4/5] RDS: Do not send congestion updates to loopback connections
From: Andy Grover @ 2009-10-30 18:51 UTC (permalink / raw)
  To: netdev; +Cc: rds-devel
In-Reply-To: <1256928717-17757-1-git-send-email-andy.grover@oracle.com>

This issue was discovered by HP's Pradeep and fixed in OFED
1.3, but not fixed in later versions, since the fix's implementation
was not immediately applyable to the later code. This patch should
do the trick for 1.4+ codebases.

Signed-off-by: Andy Grover <andy.grover@oracle.com>
---
 net/rds/cong.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/rds/cong.c b/net/rds/cong.c
index dd2711d..6d06cac 100644
--- a/net/rds/cong.c
+++ b/net/rds/cong.c
@@ -218,6 +218,8 @@ void rds_cong_queue_updates(struct rds_cong_map *map)
 	spin_lock_irqsave(&rds_cong_lock, flags);
 
 	list_for_each_entry(conn, &map->m_conn_list, c_map_item) {
+		if (conn->c_loopback)
+			continue;
 		if (!test_and_set_bit(0, &conn->c_map_queued)) {
 			rds_stats_inc(s_cong_update_queued);
 			queue_delayed_work(rds_wq, &conn->c_send_w, 0);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 5/5] RDS/IB+IW: Move recv processing to a tasklet
From: Andy Grover @ 2009-10-30 18:51 UTC (permalink / raw)
  To: netdev; +Cc: rds-devel
In-Reply-To: <1256928717-17757-1-git-send-email-andy.grover@oracle.com>

Move receive processing from event handler to a tasklet.
This should help prevent hangcheck timer from going off
when RDS is under heavy load.

Signed-off-by: Andy Grover <andy.grover@oracle.com>
---
 net/rds/ib.h      |    2 ++
 net/rds/ib_cm.c   |    2 ++
 net/rds/ib_recv.c |   28 ++++++++++++++++++++++------
 net/rds/iw.h      |    2 ++
 net/rds/iw_cm.c   |    2 ++
 net/rds/iw_recv.c |   28 ++++++++++++++++++++++------
 6 files changed, 52 insertions(+), 12 deletions(-)

diff --git a/net/rds/ib.h b/net/rds/ib.h
index 1378b85..64df4e7 100644
--- a/net/rds/ib.h
+++ b/net/rds/ib.h
@@ -98,6 +98,7 @@ struct rds_ib_connection {
 	struct rds_ib_send_work *i_sends;
 
 	/* rx */
+	struct tasklet_struct	i_recv_tasklet;
 	struct mutex		i_recv_mutex;
 	struct rds_ib_work_ring	i_recv_ring;
 	struct rds_ib_incoming	*i_ibinc;
@@ -303,6 +304,7 @@ void rds_ib_inc_free(struct rds_incoming *inc);
 int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
 			     size_t size);
 void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context);
+void rds_ib_recv_tasklet_fn(unsigned long data);
 void rds_ib_recv_init_ring(struct rds_ib_connection *ic);
 void rds_ib_recv_clear_ring(struct rds_ib_connection *ic);
 void rds_ib_recv_init_ack(struct rds_ib_connection *ic);
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index c2d372f..9d32069 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -694,6 +694,8 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp)
 		return -ENOMEM;
 
 	INIT_LIST_HEAD(&ic->ib_node);
+	tasklet_init(&ic->i_recv_tasklet, rds_ib_recv_tasklet_fn,
+		     (unsigned long) ic);
 	mutex_init(&ic->i_recv_mutex);
 #ifndef KERNEL_HAS_ATOMIC64
 	spin_lock_init(&ic->i_ack_lock);
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index 2f009d3..fe5ab8c 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -825,17 +825,22 @@ void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context)
 {
 	struct rds_connection *conn = context;
 	struct rds_ib_connection *ic = conn->c_transport_data;
-	struct ib_wc wc;
-	struct rds_ib_ack_state state = { 0, };
-	struct rds_ib_recv_work *recv;
 
 	rdsdebug("conn %p cq %p\n", conn, cq);
 
 	rds_ib_stats_inc(s_ib_rx_cq_call);
 
-	ib_req_notify_cq(cq, IB_CQ_SOLICITED);
+	tasklet_schedule(&ic->i_recv_tasklet);
+}
 
-	while (ib_poll_cq(cq, 1, &wc) > 0) {
+static inline void rds_poll_cq(struct rds_ib_connection *ic,
+			       struct rds_ib_ack_state *state)
+{
+	struct rds_connection *conn = ic->conn;
+	struct ib_wc wc;
+	struct rds_ib_recv_work *recv;
+
+	while (ib_poll_cq(ic->i_recv_cq, 1, &wc) > 0) {
 		rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n",
 			 (unsigned long long)wc.wr_id, wc.status, wc.byte_len,
 			 be32_to_cpu(wc.ex.imm_data));
@@ -853,7 +858,7 @@ void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context)
 		if (rds_conn_up(conn) || rds_conn_connecting(conn)) {
 			/* We expect errors as the qp is drained during shutdown */
 			if (wc.status == IB_WC_SUCCESS) {
-				rds_ib_process_recv(conn, recv, wc.byte_len, &state);
+				rds_ib_process_recv(conn, recv, wc.byte_len, state);
 			} else {
 				rds_ib_conn_error(conn, "recv completion on "
 				       "%pI4 had status %u, disconnecting and "
@@ -864,6 +869,17 @@ void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context)
 
 		rds_ib_ring_free(&ic->i_recv_ring, 1);
 	}
+}
+
+void rds_ib_recv_tasklet_fn(unsigned long data)
+{
+	struct rds_ib_connection *ic = (struct rds_ib_connection *) data;
+	struct rds_connection *conn = ic->conn;
+	struct rds_ib_ack_state state = { 0, };
+
+	rds_poll_cq(ic, &state);
+	ib_req_notify_cq(ic->i_recv_cq, IB_CQ_SOLICITED);
+	rds_poll_cq(ic, &state);
 
 	if (state.ack_next_valid)
 		rds_ib_set_ack(ic, state.ack_next, state.ack_required);
diff --git a/net/rds/iw.h b/net/rds/iw.h
index dd72b62..eef2f0c 100644
--- a/net/rds/iw.h
+++ b/net/rds/iw.h
@@ -119,6 +119,7 @@ struct rds_iw_connection {
 	struct rds_iw_send_work *i_sends;
 
 	/* rx */
+	struct tasklet_struct	i_recv_tasklet;
 	struct mutex		i_recv_mutex;
 	struct rds_iw_work_ring	i_recv_ring;
 	struct rds_iw_incoming	*i_iwinc;
@@ -330,6 +331,7 @@ void rds_iw_inc_free(struct rds_incoming *inc);
 int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
 			     size_t size);
 void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context);
+void rds_iw_recv_tasklet_fn(unsigned long data);
 void rds_iw_recv_init_ring(struct rds_iw_connection *ic);
 void rds_iw_recv_clear_ring(struct rds_iw_connection *ic);
 void rds_iw_recv_init_ack(struct rds_iw_connection *ic);
diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c
index a416b0d..394cf6b 100644
--- a/net/rds/iw_cm.c
+++ b/net/rds/iw_cm.c
@@ -696,6 +696,8 @@ int rds_iw_conn_alloc(struct rds_connection *conn, gfp_t gfp)
 		return -ENOMEM;
 
 	INIT_LIST_HEAD(&ic->iw_node);
+	tasklet_init(&ic->i_recv_tasklet, rds_iw_recv_tasklet_fn,
+		     (unsigned long) ic);
 	mutex_init(&ic->i_recv_mutex);
 #ifndef KERNEL_HAS_ATOMIC64
 	spin_lock_init(&ic->i_ack_lock);
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c
index 9f98150..24fc53f 100644
--- a/net/rds/iw_recv.c
+++ b/net/rds/iw_recv.c
@@ -784,17 +784,22 @@ void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context)
 {
 	struct rds_connection *conn = context;
 	struct rds_iw_connection *ic = conn->c_transport_data;
-	struct ib_wc wc;
-	struct rds_iw_ack_state state = { 0, };
-	struct rds_iw_recv_work *recv;
 
 	rdsdebug("conn %p cq %p\n", conn, cq);
 
 	rds_iw_stats_inc(s_iw_rx_cq_call);
 
-	ib_req_notify_cq(cq, IB_CQ_SOLICITED);
+	tasklet_schedule(&ic->i_recv_tasklet);
+}
 
-	while (ib_poll_cq(cq, 1, &wc) > 0) {
+static inline void rds_poll_cq(struct rds_iw_connection *ic,
+			       struct rds_iw_ack_state *state)
+{
+	struct rds_connection *conn = ic->conn;
+	struct ib_wc wc;
+	struct rds_iw_recv_work *recv;
+
+	while (ib_poll_cq(ic->i_recv_cq, 1, &wc) > 0) {
 		rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n",
 			 (unsigned long long)wc.wr_id, wc.status, wc.byte_len,
 			 be32_to_cpu(wc.ex.imm_data));
@@ -812,7 +817,7 @@ void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context)
 		if (rds_conn_up(conn) || rds_conn_connecting(conn)) {
 			/* We expect errors as the qp is drained during shutdown */
 			if (wc.status == IB_WC_SUCCESS) {
-				rds_iw_process_recv(conn, recv, wc.byte_len, &state);
+				rds_iw_process_recv(conn, recv, wc.byte_len, state);
 			} else {
 				rds_iw_conn_error(conn, "recv completion on "
 				       "%pI4 had status %u, disconnecting and "
@@ -823,6 +828,17 @@ void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context)
 
 		rds_iw_ring_free(&ic->i_recv_ring, 1);
 	}
+}
+
+void rds_iw_recv_tasklet_fn(unsigned long data)
+{
+	struct rds_iw_connection *ic = (struct rds_iw_connection *) data;
+	struct rds_connection *conn = ic->conn;
+	struct rds_iw_ack_state state = { 0, };
+
+	rds_poll_cq(ic, &state);
+	ib_req_notify_cq(ic->i_recv_cq, IB_CQ_SOLICITED);
+	rds_poll_cq(ic, &state);
 
 	if (state.ack_next_valid)
 		rds_iw_set_ack(ic, state.ack_next, state.ack_required);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 2/5] RDS: Fix potential race around rds_i[bw]_allocation
From: Andy Grover @ 2009-10-30 18:51 UTC (permalink / raw)
  To: netdev; +Cc: rds-devel
In-Reply-To: <1256928717-17757-1-git-send-email-andy.grover@oracle.com>

>From Shin Hong:

"At rds_ib_recv_refill_one(), it first executes atomic_read(&rds_ib_allocation)
for if-condition checking,

and then executes atomic_inc(&rds_ib_allocation) if the condition was
not satisfied.

However, if any other code which updates rds_ib_allocation executes
between these two atomic operation executions,
it seems that it may result race condition. (especially when
rds_ib_allocation + 1 == rds_ib_sysctl_max_recv_allocation)"

This patch fixes this by using atomic_inc_unless to eliminate the
possibility of allocating more than rds_ib_sysctl_max_recv_allocation
and then decrementing the count if the allocation fails. It also
makes an identical change to the iwarp transport.

Reported-by: Shin Hong <hongshin@gmail.com>
Signed-off-by: Andy Grover <andy.grover@oracle.com>
---
 net/rds/ib_recv.c |    7 ++++---
 net/rds/iw_recv.c |    7 ++++---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index cd7a6cf..2f009d3 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -143,15 +143,16 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn,
 	int ret = -ENOMEM;
 
 	if (recv->r_ibinc == NULL) {
-		if (atomic_read(&rds_ib_allocation) >= rds_ib_sysctl_max_recv_allocation) {
+		if (!atomic_add_unless(&rds_ib_allocation, 1, rds_ib_sysctl_max_recv_allocation)) {
 			rds_ib_stats_inc(s_ib_rx_alloc_limit);
 			goto out;
 		}
 		recv->r_ibinc = kmem_cache_alloc(rds_ib_incoming_slab,
 						 kptr_gfp);
-		if (recv->r_ibinc == NULL)
+		if (recv->r_ibinc == NULL) {
+			atomic_dec(&rds_ib_allocation);
 			goto out;
-		atomic_inc(&rds_ib_allocation);
+		}
 		INIT_LIST_HEAD(&recv->r_ibinc->ii_frags);
 		rds_inc_init(&recv->r_ibinc->ii_inc, conn, conn->c_faddr);
 	}
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c
index 8683f5f..9f98150 100644
--- a/net/rds/iw_recv.c
+++ b/net/rds/iw_recv.c
@@ -143,15 +143,16 @@ static int rds_iw_recv_refill_one(struct rds_connection *conn,
 	int ret = -ENOMEM;
 
 	if (recv->r_iwinc == NULL) {
-		if (atomic_read(&rds_iw_allocation) >= rds_iw_sysctl_max_recv_allocation) {
+		if (!atomic_add_unless(&rds_iw_allocation, 1, rds_iw_sysctl_max_recv_allocation)) {
 			rds_iw_stats_inc(s_iw_rx_alloc_limit);
 			goto out;
 		}
 		recv->r_iwinc = kmem_cache_alloc(rds_iw_incoming_slab,
 						 kptr_gfp);
-		if (recv->r_iwinc == NULL)
+		if (recv->r_iwinc == NULL) {
+			atomic_dec(&rds_iw_allocation);
 			goto out;
-		atomic_inc(&rds_iw_allocation);
+		}
 		INIT_LIST_HEAD(&recv->r_iwinc->ii_frags);
 		rds_inc_init(&recv->r_iwinc->ii_inc, conn, conn->c_faddr);
 	}
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 1/5] RDS: Add GET_MR_FOR_DEST sockopt
From: Andy Grover @ 2009-10-30 18:54 UTC (permalink / raw)
  To: netdev; +Cc: rds-devel
In-Reply-To: <1256928893-17844-1-git-send-email-andy.grover@oracle.com>

RDS currently supports a GET_MR sockopt to establish a
memory region (MR) for a chunk of memory. However, the fastreg
method ties a MR to a particular destination. The GET_MR_FOR_DEST
sockopt allows the remote machine to be specified, and thus
support for fastreg (aka FRWRs).

Note that this patch does *not* do all of this - it simply
implements the new sockopt in terms of the old one, so applications
can begin to use the new sockopt in preparation for cutover to
FRWRs.

Signed-off-by: Andy Grover <andy.grover@oracle.com>
---
 include/linux/rds.h |    8 ++++++++
 net/rds/af_rds.c    |    3 +++
 net/rds/rdma.c      |   24 ++++++++++++++++++++++++
 net/rds/rdma.h      |    1 +
 4 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/include/linux/rds.h b/include/linux/rds.h
index 89d46e1..cab4994 100644
--- a/include/linux/rds.h
+++ b/include/linux/rds.h
@@ -56,6 +56,7 @@
 /* deprecated: RDS_BARRIER 4 */
 #define RDS_RECVERR			5
 #define RDS_CONG_MONITOR		6
+#define RDS_GET_MR_FOR_DEST		7
 
 /*
  * Control message types for SOL_RDS.
@@ -224,6 +225,13 @@ struct rds_get_mr_args {
 	uint64_t	flags;
 };
 
+struct rds_get_mr_for_dest_args {
+	struct sockaddr_storage	dest_addr;
+	struct rds_iovec 	vec;
+	u_int64_t		cookie_addr;
+	uint64_t		flags;
+};
+
 struct rds_free_mr_args {
 	rds_rdma_cookie_t cookie;
 	u_int64_t	flags;
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index a202e5b..2b978dc 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -265,6 +265,9 @@ static int rds_setsockopt(struct socket *sock, int level, int optname,
 	case RDS_GET_MR:
 		ret = rds_get_mr(rs, optval, optlen);
 		break;
+	case RDS_GET_MR_FOR_DEST:
+		ret = rds_get_mr_for_dest(rs, optval, optlen);
+		break;
 	case RDS_FREE_MR:
 		ret = rds_free_mr(rs, optval, optlen);
 		break;
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index 8dc83d2..971b5a6 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -317,6 +317,30 @@ int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen)
 	return __rds_rdma_map(rs, &args, NULL, NULL);
 }
 
+int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen)
+{
+	struct rds_get_mr_for_dest_args args;
+	struct rds_get_mr_args new_args;
+
+	if (optlen != sizeof(struct rds_get_mr_for_dest_args))
+		return -EINVAL;
+
+	if (copy_from_user(&args, (struct rds_get_mr_for_dest_args __user *)optval,
+			   sizeof(struct rds_get_mr_for_dest_args)))
+		return -EFAULT;
+
+	/*
+	 * Initially, just behave like get_mr().
+	 * TODO: Implement get_mr as wrapper around this
+	 *	 and deprecate it.
+	 */
+	new_args.vec = args.vec;
+	new_args.cookie_addr = args.cookie_addr;
+	new_args.flags = args.flags;
+
+	return __rds_rdma_map(rs, &new_args, NULL, NULL);
+}
+
 /*
  * Free the MR indicated by the given R_Key
  */
diff --git a/net/rds/rdma.h b/net/rds/rdma.h
index 4255120..909c398 100644
--- a/net/rds/rdma.h
+++ b/net/rds/rdma.h
@@ -61,6 +61,7 @@ static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie)
 }
 
 int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen);
+int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen);
 int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen);
 void rds_rdma_drop_keys(struct rds_sock *rs);
 int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next 0/5] RDS: minor updates for net-next
From: Andy Grover @ 2009-10-30 18:54 UTC (permalink / raw)
  To: netdev; +Cc: rds-devel

These patches fix some small issues with RDS, please review and
apply if ok.

Thanks -- Regards -- Andy


^ permalink raw reply

* Re: [PATCH] sky2: set carrier off in probe
From: Herbert Xu @ 2009-10-30 19:13 UTC (permalink / raw)
  To: David Miller; +Cc: bphilips, shemminger, netdev
In-Reply-To: <20091030.112051.20510373.davem@davemloft.net>

On Fri, Oct 30, 2009 at 11:20:51AM -0700, David Miller wrote:
>
> Since many drivers (especially virtual software ones) do not manage
> carrier state and therefore that's why we start in state carrier on.
> 
> We've had this discussion a few times before, most recently with
> Rusty wrt. virtio :-)

You're right, modifying the driver is the best way.  Oh well,
at least it's easy to find them by searching for netif_carrier :)
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: Connection tracking and vlan
From: Adayadil Thomas @ 2009-10-30 19:20 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Herbert Xu, netdev, Patrick McHardy
In-Reply-To: <4AEB06E6.6020206@gmail.com>

On Fri, Oct 30, 2009 at 11:31 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:

> Very strange, this question about vlan looks like discussion we had
> yesterday (or the day before...) about interfaces (versus packet defragmentation)
>
> "IP conntracking" is about IP, and [V]LAN doesnt matter at all at this protocol level.
>
> Same thing if you have two interfaces, eth0 & eth1 : IP conntrack tuples dont
> include interface name/index

I am concerned about the following situation -

The linux device is configured as a bridge and is deployed between the
trunk ports
of 2 switches. In this situation the linux device will be seeing 802.1q packets
with vlan headers specifying the vlanids.

It is valid to have an environment where private IP addresses are duplicated
on different virtual LANs. i.e. it is valid to have machine A (
10.10.10.1) talking to
machine B (10.10.10.2) on vlan 1,
and
at the same time machine C ( 10.10.10.1) talking to machine D
(10.10.10.2) on vlan 2.

Since they are on different LANs (VLANs), there should not be any issues.

Now when VLANs are shared across switches, the trunk port will sent
802.1q tagged
packets between the switches. Imagine these packets when going through
the linux bridge.
The 802.1q header should identify the separate vlans by the vlan id.

If ip_conntrack does not consider vlans, it is possible that all 5
tuple are the same
and thus affect the connection tracking.

I hope I have described the scenario well. If not I can explain in a
more detailed fashion.

Thanks

^ permalink raw reply

* Re: [PATCH net-next 0/5] RDS: minor updates for net-next
From: David Miller @ 2009-10-30 19:23 UTC (permalink / raw)
  To: andy.grover; +Cc: netdev, rds-devel
In-Reply-To: <1256928893-17844-1-git-send-email-andy.grover@oracle.com>

From: Andy Grover <andy.grover@oracle.com>
Date: Fri, 30 Oct 2009 11:54:52 -0700

> These patches fix some small issues with RDS, please review and
> apply if ok.

Adding new socket options is not appropriate for -rc* series
submissions.

The changes that fix races and panics are fine, the rest is not.

Please respin your changes properly for net-2.6, and we can add the
socket option and do the other stuff in net-next-2.6

Thanks.

^ permalink raw reply

* Re: WARNING: at net/ipv4/af_inet.c:154 inet_sock_destruct
From: David Miller @ 2009-10-30 19:26 UTC (permalink / raw)
  To: eric.dumazet; +Cc: francis.moro, linux-kernel, netdev
In-Reply-To: <4AEB0059.1050400@gmail.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 30 Oct 2009 16:03:53 +0100

> [PATCH take2] net: fix sk_forward_alloc corruption
> 
> On UDP sockets, we must call skb_free_datagram() with socket locked,
> or risk sk_forward_alloc corruption. This requirement is not respected
> in SUNRPC.
> 
> Add a convenient helper, skb_free_datagram_locked() and use it in SUNRPC
> 
> Reported-by: Francis Moreau <francis.moro@gmail.com>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

I've tentatively applied this to my net-2.6 tree, I won't
push it out until we have positive testing results.

^ permalink raw reply

* Re: How to use gretap with bridge?
From: David Miller @ 2009-10-30 19:27 UTC (permalink / raw)
  To: shemminger; +Cc: herbert, nneul, netdev
In-Reply-To: <20091030093957.7128c596@nehalam>

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Fri, 30 Oct 2009 09:39:57 -0700

> On Fri, 30 Oct 2009 11:51:48 -0400
> Herbert Xu <herbert@gondor.apana.org.au> wrote:
> 
>> gre: Fix dev_addr clobbering for gretap
>> 
>> Nathan Neulinger noticed that gretap devices get their MAC address
>> from the local IP address, which results in invalid MAC addresses
>> half of the time.
>> 
>> This is because gretap is still using the tunnel netdev ops rather
>> than the correct tap netdev ops struct.
>> 
>> This patch also fixes changelink to not clobber the MAC address
>> for the gretap case.
>> 
>> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>> 
>> Thanks,
> 
> Acked-by: Stephen Hemminger <shemminger@vyatta.com>

Applied to net-2.6, thanks!

^ permalink raw reply

* Re: [PATCH] sky2: set carrier off in probe
From: David Miller @ 2009-10-30 19:28 UTC (permalink / raw)
  To: bphilips; +Cc: shemminger, netdev
In-Reply-To: <20091029235807.GF3228@jenkins.home.ifup.org>

From: Brandon Philips <bphilips@suse.de>
Date: Thu, 29 Oct 2009 16:58:07 -0700

> Before bringing up a sky2 interface up ethtool reports 
> "Link detected: yes". Do as ixgbe does and netif_carrier_off() on
> probe().
> 
> Signed-off-by: Brandon Philips <bphilips@suse.de>

Applied to net-2.6, thanks.

^ permalink raw reply

* Re: [PATCH 0/6] Bonding simplifications and netns support
From: David Miller @ 2009-10-30 19:41 UTC (permalink / raw)
  To: ebiederm; +Cc: netdev, fubar
In-Reply-To: <m1tyxhwxah.fsf@fess.ebiederm.org>

From: ebiederm@xmission.com (Eric W. Biederman)
Date: Thu, 29 Oct 2009 17:16:54 -0700

> I recently had it pointed out to me that the bonding driver does not
> work in a network namespace.  So I have simplified the bonding driver
> a bit, added support for ip link add and ip link del, and finally made
> the bonding driver work in multiple network namespaces.
> 
> The most note worthy change in the patchset is the addition of support
> in the networking core for registering a sysfs group for a device.
> 
> Using this in the bonding driver simplifies the code and removes a
> userspace race between actions triggered by the netlink event and the
> bonding sysfs attributes appearing.

I've tossed patches 1-7 into net-next-2.6, thanks Eric.

^ permalink raw reply

* Re: Connection tracking and vlan
From: Caitlin Bestler @ 2009-10-30 19:51 UTC (permalink / raw)
  To: Adayadil Thomas; +Cc: Eric Dumazet, Herbert Xu, netdev, Patrick McHardy
In-Reply-To: <fb7befa20910301220y53e43608u3b37de17661feb4e@mail.gmail.com>

Yes, it is legitimate for a Bridge to see two different 10.*.*.*
networks on different VLANs.
A Bridge can even see that same MAC address being used by two
different end stations
on different VLANs (especially if the global bit is not set).

What is not legitimate is presenting both of those 10.*.*.* networks
for local delivery.

If you are only bridging the frames then there are no connections to
track, only frames.



On Fri, Oct 30, 2009 at 12:20 PM, Adayadil Thomas
<adayadil.thomas@gmail.com> wrote:
> On Fri, Oct 30, 2009 at 11:31 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
>> Very strange, this question about vlan looks like discussion we had
>> yesterday (or the day before...) about interfaces (versus packet defragmentation)
>>
>> "IP conntracking" is about IP, and [V]LAN doesnt matter at all at this protocol level.
>>
>> Same thing if you have two interfaces, eth0 & eth1 : IP conntrack tuples dont
>> include interface name/index
>
> I am concerned about the following situation -
>
> The linux device is configured as a bridge and is deployed between the
> trunk ports
> of 2 switches. In this situation the linux device will be seeing 802.1q packets
> with vlan headers specifying the vlanids.
>
> It is valid to have an environment where private IP addresses are duplicated
> on different virtual LANs. i.e. it is valid to have machine A (
> 10.10.10.1) talking to
> machine B (10.10.10.2) on vlan 1,
> and
> at the same time machine C ( 10.10.10.1) talking to machine D
> (10.10.10.2) on vlan 2.
>
> Since they are on different LANs (VLANs), there should not be any issues.
>
> Now when VLANs are shared across switches, the trunk port will sent
> 802.1q tagged
> packets between the switches. Imagine these packets when going through
> the linux bridge.
> The 802.1q header should identify the separate vlans by the vlan id.
>
> If ip_conntrack does not consider vlans, it is possible that all 5
> tuple are the same
> and thus affect the connection tracking.
>
> I hope I have described the scenario well. If not I can explain in a
> more detailed fashion.
>
> Thanks
> --
> 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

* Re: Fw: [Bug 14470] New: freez in TCP stack
From: Herbert Xu @ 2009-10-30 20:18 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: eric.dumazet, davem, akpm, shemminger, netdev, kolo,
	bugzilla-daemon
In-Reply-To: <alpine.DEB.2.00.0910291316340.19761@wel-95.cs.helsinki.fi>

Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> wrote:
> 
> One more alternative along those lines could perhaps be:
> 
> We enter with empty write_queue there and with the hint being null, so we 
> take the else branch... and skb_peek then gives us the NULL ptr. However, 
> I cannot see how this could happen as all branches trap with return 
> before the reach tcp_xmit_retransmit_queue.

Why don't we add a WARN_ON in there and see if it triggers?

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: Connection tracking and vlan
From: Adayadil Thomas @ 2009-10-30 20:40 UTC (permalink / raw)
  To: Caitlin Bestler; +Cc: Eric Dumazet, Herbert Xu, netdev, Patrick McHardy
In-Reply-To: <469958e00910301251he051d69p178ce53e84130765@mail.gmail.com>

On Fri, Oct 30, 2009 at 3:51 PM, Caitlin Bestler
<caitlin.bestler@gmail.com> wrote:
> Yes, it is legitimate for a Bridge to see two different 10.*.*.*
> networks on different VLANs.
> A Bridge can even see that same MAC address being used by two
> different end stations
> on different VLANs (especially if the global bit is not set).
>
> What is not legitimate is presenting both of those 10.*.*.* networks
> for local delivery.
>

I did not mean this case.

> If you are only bridging the frames then there are no connections to
> track, only frames.
>

This is more like what I was trying to do with the device, but with
stateful firewall functionality
for which I was using iptables/netfilter.

Thanks

^ permalink raw reply

* Re: pull request: wireless-next-2.6 2009-10-28
From: Jarek Poplawski @ 2009-10-30 20:44 UTC (permalink / raw)
  To: John W. Linville
  Cc: Johannes Berg, Bartlomiej Zolnierkiewicz, Pekka Enberg,
	David Miller, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20091030150223.GA2586-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>

On Fri, Oct 30, 2009 at 11:02:24AM -0400, John W. Linville wrote:
> On Fri, Oct 30, 2009 at 11:06:16AM +0000, Jarek Poplawski wrote:
> 
> > There are various ways to disagree, and ignoring by John questions
> > from a merited developer both in this referenced lkml and current
> > threads looks at least strange (if not offensive) as well.
> 
> Did you read the thread for which Bartlomiej provided a link earlier?
> There were ten responses (only three of them from him) in that thread.
> His comments were not ignored, they were rejected.
> 
> Ever since Bartlomiej decided to tear himself away from
> drivers/staging, he has been nothing but negative -- petty, whining,
> indignat, whatever.  Just what has he done to merit any special
> consideration here?  Why should he have any sort of veto over rt2x00?
> 
> And of all things on which to take a stand -- how dare the rt2x00 guys
> use two header files instead of three?  The nerve of those people!!!
> 
> Ridiculous...

Maybe. Different tastes for sure, so simply no good solution.

Anyway, my point was somewhere else: Davem could be a good example;-)
I simply can't imagine a thread with such concerns left completely
uncommented before merging a patch. It's not about convincing anybody.
Usually you know at least if the concern is dismissed, or valid, but
fixable. (Sometimes you can even read between lines, or explicit, what
he really thinks...)

This discussion is mainly around trying to omit a maintainer with
"higher authority". Of course it's a mortal sin! ...Except, when the
maintainer doesn't seem to respond at all.

BTW, it seems Bartlomiej's main argument in the current thread has
changed to the non-working driver, so ridiculous only if you have a
clue.

Jarek P.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 0/6] Bonding simplifications and netns support
From: Jay Vosburgh @ 2009-10-30 21:12 UTC (permalink / raw)
  To: David Miller; +Cc: ebiederm, netdev
In-Reply-To: <20091030.124153.00934819.davem@davemloft.net>

David Miller <davem@davemloft.net> wrote:

>From: ebiederm@xmission.com (Eric W. Biederman)
>Date: Thu, 29 Oct 2009 17:16:54 -0700
>
>> I recently had it pointed out to me that the bonding driver does not
>> work in a network namespace.  So I have simplified the bonding driver
>> a bit, added support for ip link add and ip link del, and finally made
>> the bonding driver work in multiple network namespaces.
>> 
>> The most note worthy change in the patchset is the addition of support
>> in the networking core for registering a sysfs group for a device.
>> 
>> Using this in the bonding driver simplifies the code and removes a
>> userspace race between actions triggered by the netlink event and the
>> bonding sysfs attributes appearing.
>
>I've tossed patches 1-7 into net-next-2.6, thanks Eric.

	I put patches 1-7 on a recent net-next-2.6, and from a simple
"insmod bonding.ko; rmmod bonding" I'm seeing the following:

------------[ cut here ]------------
WARNING: at fs/proc/generic.c:847 remove_proc_entry+0x1a8/0x1c7()
Hardware name: IBM eserver xSeries 220 -[8645]-
remove_proc_entry: removing non-empty directory 'net/bonding', leaking at least 
'bond0'
Modules linked in: bonding(-) ipv6 microcode loop ppdev sworks_agp parport_pc tg
3 e100 agpgart parport mii libphy e1000 edd pata_serverworks [last unloaded: spe
edstep_lib]
Pid: 6216, comm: rmmod Not tainted 2.6.32-rc3-devel #19
Call Trace:
 [<c012ec9d>] warn_slowpath_common+0x60/0x90
 [<c012ed01>] warn_slowpath_fmt+0x24/0x27
 [<c01e3e55>] remove_proc_entry+0x1a8/0x1c7
 [<e0906435>] ? bond_net_exit+0x0/0xa3 [bonding]
 [<e09064c3>] bond_net_exit+0x8e/0xa3 [bonding]
 [<c02e6ee8>] unregister_pernet_gen_subsys+0x23/0x3d
 [<e0910baa>] bonding_exit+0x3a/0x66 [bonding]
 [<c015ccf3>] sys_delete_module+0x191/0x1f1
 [<c0147a30>] ? up_read+0x16/0x2a
 [<c0102a18>] ? restore_all_notrace+0x0/0x18
 [<c0353357>] ? do_page_fault+0x0/0x393
 [<c0102904>] sysenter_do_call+0x12/0x32
---[ end trace 8f3eaeee682a572c ]---

	Any thoughts?  I have not as yet investigated further.

	-J

---
	-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com

^ permalink raw reply

* Re: [PATCH net-next 0/5] RDS: minor updates for net-next
From: Andrew Grover @ 2009-10-30 21:23 UTC (permalink / raw)
  To: David Miller; +Cc: andy.grover, netdev, rds-devel
In-Reply-To: <20091030.122326.73781593.davem@davemloft.net>

On Fri, Oct 30, 2009 at 12:23 PM, David Miller <davem@davemloft.net> wrote:
>> These patches fix some small issues with RDS, please review and
>> apply if ok.
> Adding new socket options is not appropriate for -rc* series
> submissions.
>
> The changes that fix races and panics are fine, the rest is not.
>
> Please respin your changes properly for net-2.6, and we can add the
> socket option and do the other stuff in net-next-2.6

I'm fine with it all going into net-next, actually. Even the fixes are
not for showstopper bugs, and RDS is not a widely-used protocol.

Thanks -- Regards -- Andy

^ permalink raw reply

* Re: [PATCH net-next 0/5] RDS: minor updates for net-next
From: David Miller @ 2009-10-30 22:06 UTC (permalink / raw)
  To: andy.grover; +Cc: andy.grover, netdev, rds-devel
In-Reply-To: <c0a09e5c0910301423k7726909frde1ae63e6ac9f009@mail.gmail.com>

From: Andrew Grover <andy.grover@gmail.com>
Date: Fri, 30 Oct 2009 14:23:13 -0700

> On Fri, Oct 30, 2009 at 12:23 PM, David Miller <davem@davemloft.net> wrote:
>>> These patches fix some small issues with RDS, please review and
>>> apply if ok.
>> Adding new socket options is not appropriate for -rc* series
>> submissions.
>>
>> The changes that fix races and panics are fine, the rest is not.
>>
>> Please respin your changes properly for net-2.6, and we can add the
>> socket option and do the other stuff in net-next-2.6
> 
> I'm fine with it all going into net-next, actually. Even the fixes are
> not for showstopper bugs, and RDS is not a widely-used protocol.

Okie dokie, I've tossed all 5 patches into net-next-2.6

Thanks!

^ permalink raw reply

* [net-next PATCH 0/4] qlge: Add ethtool self-test.
From: Ron Mercer @ 2009-10-30 22:13 UTC (permalink / raw)
  To: davem; +Cc: netdev, ron.mercer

Changes for QLGE.

1) Add ethtool selftest.
2) Reduce debug print output.
3) Generic cleanup.




^ permalink raw reply

* [net-next PATCH 1/4] qlge: Add ethtool self-test.
From: Ron Mercer @ 2009-10-30 22:13 UTC (permalink / raw)
  To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1256940816-27540-1-git-send-email-ron.mercer@qlogic.com>


Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
 drivers/net/qlge/qlge.h         |    6 ++
 drivers/net/qlge/qlge_ethtool.c |  112 +++++++++++++++++++++++++++++++++++++++
 drivers/net/qlge/qlge_main.c    |   20 +++++++-
 3 files changed, 137 insertions(+), 1 deletions(-)

diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 4b954e1..b9f65e0 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1580,6 +1580,8 @@ enum {
 	QL_ALLMULTI = 6,
 	QL_PORT_CFG = 7,
 	QL_CAM_RT_SET = 8,
+	QL_SELFTEST = 9,
+	QL_LB_LINK_UP = 10,
 };
 
 /* link_status bit definitions */
@@ -1716,6 +1718,7 @@ struct ql_adapter {
 	struct completion ide_completion;
 	struct nic_operations *nic_ops;
 	u16 device_id;
+	atomic_t lb_count;
 };
 
 /*
@@ -1807,6 +1810,9 @@ int ql_mb_set_port_cfg(struct ql_adapter *qdev);
 int ql_wait_fifo_empty(struct ql_adapter *qdev);
 void ql_gen_reg_dump(struct ql_adapter *qdev,
 			struct ql_reg_dump *mpi_coredump);
+netdev_tx_t ql_lb_send(struct sk_buff *skb, struct net_device *ndev);
+void ql_check_lb_frame(struct ql_adapter *, struct sk_buff *);
+int ql_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget);
 
 #if 1
 #define QL_ALL_DUMP
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 62c4af0..058fa0a 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -36,6 +36,11 @@
 
 #include "qlge.h"
 
+static const char ql_gstrings_test[][ETH_GSTRING_LEN] = {
+	"Loopback test  (offline)"
+};
+#define QLGE_TEST_LEN (sizeof(ql_gstrings_test) / ETH_GSTRING_LEN)
+
 static int ql_update_ring_coalescing(struct ql_adapter *qdev)
 {
 	int i, status = 0;
@@ -251,6 +256,8 @@ static void ql_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
 static int ql_get_sset_count(struct net_device *dev, int sset)
 {
 	switch (sset) {
+	case ETH_SS_TEST:
+		return QLGE_TEST_LEN;
 	case ETH_SS_STATS:
 		return ARRAY_SIZE(ql_stats_str_arr);
 	default:
@@ -429,6 +436,110 @@ static int ql_phys_id(struct net_device *ndev, u32 data)
 	return 0;
 }
 
+static int ql_start_loopback(struct ql_adapter *qdev)
+{
+	if (netif_carrier_ok(qdev->ndev)) {
+		set_bit(QL_LB_LINK_UP, &qdev->flags);
+		netif_carrier_off(qdev->ndev);
+	} else
+		clear_bit(QL_LB_LINK_UP, &qdev->flags);
+	qdev->link_config |= CFG_LOOPBACK_PCS;
+	return ql_mb_set_port_cfg(qdev);
+}
+
+static void ql_stop_loopback(struct ql_adapter *qdev)
+{
+	qdev->link_config &= ~CFG_LOOPBACK_PCS;
+	ql_mb_set_port_cfg(qdev);
+	if (test_bit(QL_LB_LINK_UP, &qdev->flags)) {
+		netif_carrier_on(qdev->ndev);
+		clear_bit(QL_LB_LINK_UP, &qdev->flags);
+	}
+}
+
+static void ql_create_lb_frame(struct sk_buff *skb,
+					unsigned int frame_size)
+{
+	memset(skb->data, 0xFF, frame_size);
+	frame_size &= ~1;
+	memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
+	memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
+	memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
+}
+
+void ql_check_lb_frame(struct ql_adapter *qdev,
+					struct sk_buff *skb)
+{
+	unsigned int frame_size = skb->len;
+
+	if ((*(skb->data + 3) == 0xFF) &&
+		(*(skb->data + frame_size / 2 + 10) == 0xBE) &&
+		(*(skb->data + frame_size / 2 + 12) == 0xAF)) {
+			atomic_dec(&qdev->lb_count);
+			return;
+	}
+}
+
+static int ql_run_loopback_test(struct ql_adapter *qdev)
+{
+	int i;
+	netdev_tx_t rc;
+	struct sk_buff *skb;
+	unsigned int size = SMALL_BUF_MAP_SIZE;
+
+	for (i = 0; i < 64; i++) {
+		skb = netdev_alloc_skb(qdev->ndev, size);
+		if (!skb)
+			return -ENOMEM;
+
+		skb->queue_mapping = 0;
+		skb_put(skb, size);
+		ql_create_lb_frame(skb, size);
+		rc = ql_lb_send(skb, qdev->ndev);
+		if (rc != NETDEV_TX_OK)
+			return -EPIPE;
+		atomic_inc(&qdev->lb_count);
+	}
+
+	ql_clean_lb_rx_ring(&qdev->rx_ring[0], 128);
+	return atomic_read(&qdev->lb_count) ? -EIO : 0;
+}
+
+static int ql_loopback_test(struct ql_adapter *qdev, u64 *data)
+{
+	*data = ql_start_loopback(qdev);
+	if (*data)
+		goto out;
+	*data = ql_run_loopback_test(qdev);
+out:
+	ql_stop_loopback(qdev);
+	return *data;
+}
+
+static void ql_self_test(struct net_device *ndev,
+				struct ethtool_test *eth_test, u64 *data)
+{
+	struct ql_adapter *qdev = netdev_priv(ndev);
+
+	if (netif_running(ndev)) {
+		set_bit(QL_SELFTEST, &qdev->flags);
+		if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
+			/* Offline tests */
+			if (ql_loopback_test(qdev, &data[0]))
+				eth_test->flags |= ETH_TEST_FL_FAILED;
+
+		} else {
+			/* Online tests */
+			data[0] = 0;
+		}
+		clear_bit(QL_SELFTEST, &qdev->flags);
+	} else {
+		QPRINTK(qdev, DRV, ERR,
+			"%s: is down, Loopback test will fail.\n", ndev->name);
+		eth_test->flags |= ETH_TEST_FL_FAILED;
+	}
+}
+
 static int ql_get_regs_len(struct net_device *ndev)
 {
 	return sizeof(struct ql_reg_dump);
@@ -575,6 +686,7 @@ const struct ethtool_ops qlge_ethtool_ops = {
 	.set_msglevel = ql_set_msglevel,
 	.get_link = ethtool_op_get_link,
 	.phys_id		 = ql_phys_id,
+	.self_test		 = ql_self_test,
 	.get_pauseparam		 = ql_get_pauseparam,
 	.set_pauseparam		 = ql_set_pauseparam,
 	.get_rx_csum = ql_get_rx_csum,
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index dd0ea02..9e4d3dc 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1680,6 +1680,13 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
 		return;
 	}
 
+	/* loopback self test for ethtool */
+	if (test_bit(QL_SELFTEST, &qdev->flags)) {
+		ql_check_lb_frame(qdev, skb);
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
 	prefetch(skb->data);
 	skb->dev = ndev;
 	if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) {
@@ -2248,6 +2255,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)
 	return NETDEV_TX_OK;
 }
 
+
 static void ql_free_shadow_space(struct ql_adapter *qdev)
 {
 	if (qdev->rx_ring_shadow_reg_area) {
@@ -4173,7 +4181,6 @@ err_out:
 	return err;
 }
 
-
 static const struct net_device_ops qlge_netdev_ops = {
 	.ndo_open		= qlge_open,
 	.ndo_stop		= qlge_close,
@@ -4242,10 +4249,21 @@ static int __devinit qlge_probe(struct pci_dev *pdev,
 	}
 	ql_link_off(qdev);
 	ql_display_dev_info(ndev);
+	atomic_set(&qdev->lb_count, 0);
 	cards_found++;
 	return 0;
 }
 
+netdev_tx_t ql_lb_send(struct sk_buff *skb, struct net_device *ndev)
+{
+	return qlge_send(skb, ndev);
+}
+
+int ql_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget)
+{
+	return ql_clean_inbound_rx_ring(rx_ring, budget);
+}
+
 static void __devexit qlge_remove(struct pci_dev *pdev)
 {
 	struct net_device *ndev = pci_get_drvdata(pdev);
-- 
1.6.0.2


^ permalink raw reply related


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