Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 18/21] tipc: Enhance handling of discovery object creation failures
From: Paul Gortmaker @ 2011-05-10 20:44 UTC (permalink / raw)
  To: davem; +Cc: netdev, Allan.Stephens, Paul Gortmaker
In-Reply-To: <1305060277-15600-1-git-send-email-paul.gortmaker@windriver.com>

From: Allan Stephens <Allan.Stephens@windriver.com>

Modifies bearer creation and deletion code to improve handling of
scenarios when a neighbor discovery object cannot be created. The
creation routine now aborts the creation of a bearer if its discovery
object cannot be created, and deletes the newly created bearer, rather
than failing quietly and leaving an unusable bearer hanging around.

Since the exit via the goto label really isn't a definitive failure
in all cases, relabel it appropriately.

Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 net/tipc/bearer.c   |   30 ++++++++++++++++++------------
 net/tipc/discover.c |   45 +++++++++++++++++++++------------------------
 net/tipc/discover.h |    8 +++-----
 3 files changed, 42 insertions(+), 41 deletions(-)

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index f7c29af..5fcd1c1 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -46,6 +46,8 @@ static u32 media_count;
 
 struct tipc_bearer tipc_bearers[MAX_BEARERS];
 
+static void bearer_disable(struct tipc_bearer *b_ptr);
+
 /**
  * media_name_valid - validate media name
  *
@@ -518,7 +520,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
 	if (!m_ptr) {
 		warn("Bearer <%s> rejected, media <%s> not registered\n", name,
 		     b_name.media_name);
-		goto failed;
+		goto exit;
 	}
 
 	if (priority == TIPC_MEDIA_LINK_PRI)
@@ -534,14 +536,14 @@ restart:
 		}
 		if (!strcmp(name, tipc_bearers[i].name)) {
 			warn("Bearer <%s> rejected, already enabled\n", name);
-			goto failed;
+			goto exit;
 		}
 		if ((tipc_bearers[i].priority == priority) &&
 		    (++with_this_prio > 2)) {
 			if (priority-- == 0) {
 				warn("Bearer <%s> rejected, duplicate priority\n",
 				     name);
-				goto failed;
+				goto exit;
 			}
 			warn("Bearer <%s> priority adjustment required %u->%u\n",
 			     name, priority + 1, priority);
@@ -551,7 +553,7 @@ restart:
 	if (bearer_id >= MAX_BEARERS) {
 		warn("Bearer <%s> rejected, bearer limit reached (%u)\n",
 		     name, MAX_BEARERS);
-		goto failed;
+		goto exit;
 	}
 
 	b_ptr = &tipc_bearers[bearer_id];
@@ -559,7 +561,7 @@ restart:
 	res = m_ptr->enable_bearer(b_ptr);
 	if (res) {
 		warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res);
-		goto failed;
+		goto exit;
 	}
 
 	b_ptr->identity = bearer_id;
@@ -569,14 +571,18 @@ restart:
 	b_ptr->priority = priority;
 	INIT_LIST_HEAD(&b_ptr->cong_links);
 	INIT_LIST_HEAD(&b_ptr->links);
-	b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr,
-						  disc_domain);
 	spin_lock_init(&b_ptr->lock);
-	write_unlock_bh(&tipc_net_lock);
+
+	res = tipc_disc_create(b_ptr, &m_ptr->bcast_addr, disc_domain);
+	if (res) {
+		bearer_disable(b_ptr);
+		warn("Bearer <%s> rejected, discovery object creation failed\n",
+		     name);
+		goto exit;
+	}
 	info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
 	     name, tipc_addr_string_fill(addr_string, disc_domain), priority);
-	return 0;
-failed:
+exit:
 	write_unlock_bh(&tipc_net_lock);
 	return res;
 }
@@ -627,14 +633,14 @@ static void bearer_disable(struct tipc_bearer *b_ptr)
 	struct link *temp_l_ptr;
 
 	info("Disabling bearer <%s>\n", b_ptr->name);
-	tipc_disc_stop_link_req(b_ptr->link_req);
 	spin_lock_bh(&b_ptr->lock);
-	b_ptr->link_req = NULL;
 	b_ptr->blocked = 1;
 	b_ptr->media->disable_bearer(b_ptr);
 	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
 		tipc_link_delete(l_ptr);
 	}
+	if (b_ptr->link_req)
+		tipc_disc_delete(b_ptr->link_req);
 	spin_unlock_bh(&b_ptr->lock);
 	memset(b_ptr, 0, sizeof(struct tipc_bearer));
 }
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index d2163bd..6acf32a 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -216,22 +216,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
 }
 
 /**
- * tipc_disc_stop_link_req - stop sending periodic link setup requests
- * @req: ptr to link request structure
- */
-
-void tipc_disc_stop_link_req(struct link_req *req)
-{
-	if (!req)
-		return;
-
-	k_cancel_timer(&req->timer);
-	k_term_timer(&req->timer);
-	buf_discard(req->buf);
-	kfree(req);
-}
-
-/**
  * tipc_disc_update_link_req - update frequency of periodic link setup requests
  * @req: ptr to link request structure
  */
@@ -286,28 +270,27 @@ static void disc_timeout(struct link_req *req)
 }
 
 /**
- * tipc_disc_init_link_req - start sending periodic link setup requests
+ * tipc_disc_create - create object to send periodic link setup requests
  * @b_ptr: ptr to bearer issuing requests
  * @dest: destination address for request messages
  * @dest_domain: network domain to which links can be established
  *
- * Returns pointer to link request structure, or NULL if unable to create.
+ * Returns 0 if successful, otherwise -errno.
  */
 
-struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr,
-					 const struct tipc_media_addr *dest,
-					 u32 dest_domain)
+int tipc_disc_create(struct tipc_bearer *b_ptr,
+		     struct tipc_media_addr *dest, u32 dest_domain)
 {
 	struct link_req *req;
 
 	req = kmalloc(sizeof(*req), GFP_ATOMIC);
 	if (!req)
-		return NULL;
+		return -ENOMEM;
 
 	req->buf = tipc_disc_init_msg(DSC_REQ_MSG, dest_domain, b_ptr);
 	if (!req->buf) {
 		kfree(req);
-		return NULL;
+		return -ENOMSG;
 	}
 
 	memcpy(&req->dest, dest, sizeof(*dest));
@@ -316,6 +299,20 @@ struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr,
 	req->timer_intv = TIPC_LINK_REQ_INIT;
 	k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req);
 	k_start_timer(&req->timer, req->timer_intv);
-	return req;
+	b_ptr->link_req = req;
+	return 0;
+}
+
+/**
+ * tipc_disc_delete - destroy object sending periodic link setup requests
+ * @req: ptr to link request structure
+ */
+
+void tipc_disc_delete(struct link_req *req)
+{
+	k_cancel_timer(&req->timer);
+	k_term_timer(&req->timer);
+	buf_discard(req->buf);
+	kfree(req);
 }
 
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index e48a167..d6e44e3 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -39,12 +39,10 @@
 
 struct link_req;
 
-struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr,
-					 const struct tipc_media_addr *dest,
-					 u32 dest_domain);
+int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest,
+		     u32 dest_domain);
+void tipc_disc_delete(struct link_req *req);
 void tipc_disc_update_link_req(struct link_req *req);
-void tipc_disc_stop_link_req(struct link_req *req);
-
 void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr);
 
 #endif
-- 
1.7.4.4


^ permalink raw reply related

* [PATCH net-next 19/21] tipc: Enhance sending of discovery object link request messages
From: Paul Gortmaker @ 2011-05-10 20:44 UTC (permalink / raw)
  To: davem; +Cc: netdev, Allan.Stephens, Paul Gortmaker
In-Reply-To: <1305060277-15600-1-git-send-email-paul.gortmaker@windriver.com>

From: Allan Stephens <Allan.Stephens@windriver.com>

Augments TIPC's discovery object to send its initial neighbor discovery
request message as soon as the associated bearer is created, rather than
waiting for its first periodic timeout to occur, thereby speeding up the
discovery process. Also adds a check to suppress the initial request or
subsequent requests if the bearer is blocked at the time the request is
scheduled for transmission.

Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 net/tipc/discover.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 6acf32a..dba4767 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -241,6 +241,17 @@ void tipc_disc_update_link_req(struct link_req *req)
 }
 
 /**
+ * disc_send_msg - send link setup request message
+ * @req: ptr to link request structure
+ */
+
+static void disc_send_msg(struct link_req *req)
+{
+	if (!req->bearer->blocked)
+		tipc_bearer_send(req->bearer, req->buf, &req->dest);
+}
+
+/**
  * disc_timeout - send a periodic link setup request
  * @req: ptr to link request structure
  *
@@ -251,7 +262,7 @@ static void disc_timeout(struct link_req *req)
 {
 	spin_lock_bh(&req->bearer->lock);
 
-	req->bearer->media->send_msg(req->buf, req->bearer, &req->dest);
+	disc_send_msg(req);
 
 	if ((req->timer_intv == TIPC_LINK_REQ_SLOW) ||
 	    (req->timer_intv == TIPC_LINK_REQ_FAST)) {
@@ -300,6 +311,7 @@ int tipc_disc_create(struct tipc_bearer *b_ptr,
 	k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req);
 	k_start_timer(&req->timer, req->timer_intv);
 	b_ptr->link_req = req;
+	disc_send_msg(req);
 	return 0;
 }
 
-- 
1.7.4.4


^ permalink raw reply related

* [PATCH net-next 16/21] tipc: Avoid recomputation of outgoing message length
From: Paul Gortmaker @ 2011-05-10 20:44 UTC (permalink / raw)
  To: davem; +Cc: netdev, Allan.Stephens, Paul Gortmaker
In-Reply-To: <1305060277-15600-1-git-send-email-paul.gortmaker@windriver.com>

From: Allan Stephens <Allan.Stephens@windriver.com>

Rework TIPC's message sending routines to take advantage of the total
amount of data value passed to it by the kernel socket infrastructure.
This change eliminates the need for TIPC to compute the size of outgoing
messages itself, as well as the check for an oversize message in
tipc_msg_build().  In addition, this change warrants an explanation:

   -     res = send_packet(NULL, sock, &my_msg, 0);
   +     res = send_packet(NULL, sock, &my_msg, bytes_to_send);

Previously, the final argument to send_packet() was ignored (since the
amount of data being sent was recalculated by a lower-level routine)
and we could just pass in a dummy value (0). Now that the
recalculation is being eliminated, the argument value being passed to
send_packet() is significant and we have to supply the actual amount
of data we want to send.

Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 net/tipc/link.c   |   18 +++++++++++-------
 net/tipc/link.h   |    1 +
 net/tipc/msg.c    |   25 +++----------------------
 net/tipc/msg.h    |    5 ++---
 net/tipc/port.c   |   49 +++++++++++++++++++++++++++----------------------
 net/tipc/port.h   |   14 +++++++++-----
 net/tipc/socket.c |   14 +++++++++-----
 net/tipc/subscr.c |    4 ++--
 8 files changed, 64 insertions(+), 66 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 2a9f44a..4bab139 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -92,7 +92,8 @@ static int  link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf);
 static void link_set_supervision_props(struct link *l_ptr, u32 tolerance);
 static int  link_send_sections_long(struct tipc_port *sender,
 				    struct iovec const *msg_sect,
-				    u32 num_sect, u32 destnode);
+				    u32 num_sect, unsigned int total_len,
+				    u32 destnode);
 static void link_check_defragm_bufs(struct link *l_ptr);
 static void link_state_event(struct link *l_ptr, u32 event);
 static void link_reset_statistics(struct link *l_ptr);
@@ -1043,6 +1044,7 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
 int tipc_link_send_sections_fast(struct tipc_port *sender,
 				 struct iovec const *msg_sect,
 				 const u32 num_sect,
+				 unsigned int total_len,
 				 u32 destaddr)
 {
 	struct tipc_msg *hdr = &sender->phdr;
@@ -1058,8 +1060,8 @@ again:
 	 * (Must not hold any locks while building message.)
 	 */
 
-	res = tipc_msg_build(hdr, msg_sect, num_sect, sender->max_pkt,
-			!sender->user_port, &buf);
+	res = tipc_msg_build(hdr, msg_sect, num_sect, total_len,
+			     sender->max_pkt, !sender->user_port, &buf);
 
 	read_lock_bh(&tipc_net_lock);
 	node = tipc_node_find(destaddr);
@@ -1104,7 +1106,8 @@ exit:
 				goto again;
 
 			return link_send_sections_long(sender, msg_sect,
-						       num_sect, destaddr);
+						       num_sect, total_len,
+						       destaddr);
 		}
 		tipc_node_unlock(node);
 	}
@@ -1116,7 +1119,7 @@ exit:
 		return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
 	if (res >= 0)
 		return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
-						 TIPC_ERR_NO_NODE);
+						 total_len, TIPC_ERR_NO_NODE);
 	return res;
 }
 
@@ -1137,12 +1140,13 @@ exit:
 static int link_send_sections_long(struct tipc_port *sender,
 				   struct iovec const *msg_sect,
 				   u32 num_sect,
+				   unsigned int total_len,
 				   u32 destaddr)
 {
 	struct link *l_ptr;
 	struct tipc_node *node;
 	struct tipc_msg *hdr = &sender->phdr;
-	u32 dsz = msg_data_sz(hdr);
+	u32 dsz = total_len;
 	u32 max_pkt, fragm_sz, rest;
 	struct tipc_msg fragm_hdr;
 	struct sk_buff *buf, *buf_chain, *prev;
@@ -1269,7 +1273,7 @@ reject:
 			buf_discard(buf_chain);
 		}
 		return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
-						 TIPC_ERR_NO_NODE);
+						 total_len, TIPC_ERR_NO_NODE);
 	}
 
 	/* Append whole chain to send queue: */
diff --git a/net/tipc/link.h b/net/tipc/link.h
index e6a30db..74fbeca 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -228,6 +228,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
 int tipc_link_send_sections_fast(struct tipc_port *sender,
 				 struct iovec const *msg_sect,
 				 const u32 num_sect,
+				 unsigned int total_len,
 				 u32 destnode);
 void tipc_link_recv_bundle(struct sk_buff *buf);
 int  tipc_link_recv_fragment(struct sk_buff **pending,
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 6d92d17..03e57bf 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -68,20 +68,6 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
 }
 
 /**
- * tipc_msg_calc_data_size - determine total data size for message
- */
-
-int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect)
-{
-	int dsz = 0;
-	int i;
-
-	for (i = 0; i < num_sect; i++)
-		dsz += msg_sect[i].iov_len;
-	return dsz;
-}
-
-/**
  * tipc_msg_build - create message using specified header and data
  *
  * Note: Caller must not hold any locks in case copy_from_user() is interrupted!
@@ -89,18 +75,13 @@ int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect)
  * Returns message data size or errno
  */
 
-int tipc_msg_build(struct tipc_msg *hdr,
-			    struct iovec const *msg_sect, u32 num_sect,
+int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
+		   u32 num_sect, unsigned int total_len,
 			    int max_size, int usrmem, struct sk_buff **buf)
 {
 	int dsz, sz, hsz, pos, res, cnt;
 
-	dsz = tipc_msg_calc_data_size(msg_sect, num_sect);
-	if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) {
-		*buf = NULL;
-		return -EINVAL;
-	}
-
+	dsz = total_len;
 	pos = hsz = msg_hdr_sz(hdr);
 	sz = hsz + dsz;
 	msg_set_size(hdr, sz);
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 005b318..8452454 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -750,9 +750,8 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
 u32 tipc_msg_tot_importance(struct tipc_msg *m);
 void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
 			    u32 hsize, u32 destnode);
-int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect);
-int tipc_msg_build(struct tipc_msg *hdr,
-			    struct iovec const *msg_sect, u32 num_sect,
+int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
+		   u32 num_sect, unsigned int total_len,
 			    int max_size, int usrmem, struct sk_buff **buf);
 
 static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 9f2ff12..c68dc95 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -74,7 +74,8 @@ static u32 port_peerport(struct tipc_port *p_ptr)
  */
 
 int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
-		   u32 num_sect, struct iovec const *msg_sect)
+		   u32 num_sect, struct iovec const *msg_sect,
+		   unsigned int total_len)
 {
 	struct tipc_msg *hdr;
 	struct sk_buff *buf;
@@ -98,7 +99,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
 	msg_set_namelower(hdr, seq->lower);
 	msg_set_nameupper(hdr, seq->upper);
 	msg_set_hdr_sz(hdr, MCAST_H_SIZE);
-	res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE,
+	res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE,
 			!oport->user_port, &buf);
 	if (unlikely(!buf))
 		return res;
@@ -418,12 +419,12 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
 
 int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
 			      struct iovec const *msg_sect, u32 num_sect,
-			      int err)
+			      unsigned int total_len, int err)
 {
 	struct sk_buff *buf;
 	int res;
 
-	res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE,
+	res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE,
 			!p_ptr->user_port, &buf);
 	if (!buf)
 		return res;
@@ -1163,12 +1164,13 @@ int tipc_shutdown(u32 ref)
  */
 
 static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect,
-				   struct iovec const *msg_sect)
+				   struct iovec const *msg_sect,
+				   unsigned int total_len)
 {
 	struct sk_buff *buf;
 	int res;
 
-	res = tipc_msg_build(&sender->phdr, msg_sect, num_sect,
+	res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len,
 			MAX_MSG_SIZE, !sender->user_port, &buf);
 	if (likely(buf))
 		tipc_port_recv_msg(buf);
@@ -1179,7 +1181,8 @@ static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_se
  * tipc_send - send message sections on connection
  */
 
-int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
+int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect,
+	      unsigned int total_len)
 {
 	struct tipc_port *p_ptr;
 	u32 destnode;
@@ -1194,9 +1197,10 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
 		destnode = port_peernode(p_ptr);
 		if (likely(destnode != tipc_own_addr))
 			res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
-							   destnode);
+							   total_len, destnode);
 		else
-			res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
+			res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect,
+						      total_len);
 
 		if (likely(res != -ELINKCONG)) {
 			p_ptr->congested = 0;
@@ -1207,8 +1211,7 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
 	}
 	if (port_unreliable(p_ptr)) {
 		p_ptr->congested = 0;
-		/* Just calculate msg length and return */
-		return tipc_msg_calc_data_size(msg_sect, num_sect);
+		return total_len;
 	}
 	return -ELINKCONG;
 }
@@ -1218,7 +1221,8 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
  */
 
 int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
-	   unsigned int num_sect, struct iovec const *msg_sect)
+		   unsigned int num_sect, struct iovec const *msg_sect,
+		   unsigned int total_len)
 {
 	struct tipc_port *p_ptr;
 	struct tipc_msg *msg;
@@ -1245,23 +1249,23 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
 	if (likely(destport)) {
 		if (likely(destnode == tipc_own_addr))
 			res = tipc_port_recv_sections(p_ptr, num_sect,
-						      msg_sect);
+						      msg_sect, total_len);
 		else
 			res = tipc_link_send_sections_fast(p_ptr, msg_sect,
-							   num_sect, destnode);
+							   num_sect, total_len,
+							   destnode);
 		if (likely(res != -ELINKCONG)) {
 			if (res > 0)
 				p_ptr->sent++;
 			return res;
 		}
 		if (port_unreliable(p_ptr)) {
-			/* Just calculate msg length and return */
-			return tipc_msg_calc_data_size(msg_sect, num_sect);
+			return total_len;
 		}
 		return -ELINKCONG;
 	}
 	return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect,
-					 TIPC_ERR_NO_NAME);
+					 total_len, TIPC_ERR_NO_NAME);
 }
 
 /**
@@ -1269,7 +1273,8 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
  */
 
 int tipc_send2port(u32 ref, struct tipc_portid const *dest,
-	   unsigned int num_sect, struct iovec const *msg_sect)
+		   unsigned int num_sect, struct iovec const *msg_sect,
+		   unsigned int total_len)
 {
 	struct tipc_port *p_ptr;
 	struct tipc_msg *msg;
@@ -1289,18 +1294,18 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
 	msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
 
 	if (dest->node == tipc_own_addr)
-		res =  tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
+		res =  tipc_port_recv_sections(p_ptr, num_sect, msg_sect,
+					       total_len);
 	else
 		res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
-						   dest->node);
+						   total_len, dest->node);
 	if (likely(res != -ELINKCONG)) {
 		if (res > 0)
 			p_ptr->sent++;
 		return res;
 	}
 	if (port_unreliable(p_ptr)) {
-		/* Just calculate msg length and return */
-		return tipc_msg_calc_data_size(msg_sect, num_sect);
+		return total_len;
 	}
 	return -ELINKCONG;
 }
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 87b9424..b9aa341 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -205,23 +205,27 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr);
 /*
  * TIPC messaging routines
  */
-int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect);
+int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect,
+	      unsigned int total_len);
 
 int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain,
-		unsigned int num_sect, struct iovec const *msg_sect);
+		   unsigned int num_sect, struct iovec const *msg_sect,
+		   unsigned int total_len);
 
 int tipc_send2port(u32 portref, struct tipc_portid const *dest,
-		unsigned int num_sect, struct iovec const *msg_sect);
+		   unsigned int num_sect, struct iovec const *msg_sect,
+		   unsigned int total_len);
 
 int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest,
 		struct sk_buff *buf, unsigned int dsz);
 
 int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
-		unsigned int section_count, struct iovec const *msg);
+		   unsigned int section_count, struct iovec const *msg,
+		   unsigned int total_len);
 
 int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
 			      struct iovec const *msg_sect, u32 num_sect,
-			      int err);
+			      unsigned int total_len, int err);
 struct sk_buff *tipc_port_get_ports(void);
 void tipc_port_recv_proto_msg(struct sk_buff *buf);
 void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index e1c7917..3388373 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -576,12 +576,14 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
 					     &dest->addr.name.name,
 					     dest->addr.name.domain,
 					     m->msg_iovlen,
-					     m->msg_iov);
+					     m->msg_iov,
+					     total_len);
 		} else if (dest->addrtype == TIPC_ADDR_ID) {
 			res = tipc_send2port(tport->ref,
 					     &dest->addr.id,
 					     m->msg_iovlen,
-					     m->msg_iov);
+					     m->msg_iov,
+					     total_len);
 		} else if (dest->addrtype == TIPC_ADDR_MCAST) {
 			if (needs_conn) {
 				res = -EOPNOTSUPP;
@@ -593,7 +595,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
 			res = tipc_multicast(tport->ref,
 					     &dest->addr.nameseq,
 					     m->msg_iovlen,
-					     m->msg_iov);
+					     m->msg_iov,
+					     total_len);
 		}
 		if (likely(res != -ELINKCONG)) {
 			if (needs_conn && (res >= 0))
@@ -659,7 +662,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
 			break;
 		}
 
-		res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov);
+		res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov,
+				total_len);
 		if (likely(res != -ELINKCONG))
 			break;
 		if (m->msg_flags & MSG_DONTWAIT) {
@@ -766,7 +770,7 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
 				bytes_to_send = curr_left;
 			my_iov.iov_base = curr_start;
 			my_iov.iov_len = bytes_to_send;
-			res = send_packet(NULL, sock, &my_msg, 0);
+			res = send_packet(NULL, sock, &my_msg, bytes_to_send);
 			if (res < 0) {
 				if (bytes_sent)
 					res = bytes_sent;
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index aae9eae..6cf7268 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -109,7 +109,7 @@ static void subscr_send_event(struct subscription *sub,
 	sub->evt.found_upper = htohl(found_upper, sub->swap);
 	sub->evt.port.ref = htohl(port_ref, sub->swap);
 	sub->evt.port.node = htohl(node, sub->swap);
-	tipc_send(sub->server_ref, 1, &msg_sect);
+	tipc_send(sub->server_ref, 1, &msg_sect, msg_sect.iov_len);
 }
 
 /**
@@ -521,7 +521,7 @@ static void subscr_named_msg_event(void *usr_handle,
 
 	/* Send an ACK- to complete connection handshaking */
 
-	tipc_send(server_port_ref, 0, NULL);
+	tipc_send(server_port_ref, 0, NULL, 0);
 
 	/* Handle optional subscription request */
 
-- 
1.7.4.4


^ permalink raw reply related

* [PATCH net-next 15/21] tipc: Abort excessive send requests as early as possible
From: Paul Gortmaker @ 2011-05-10 20:44 UTC (permalink / raw)
  To: davem; +Cc: netdev, Allan.Stephens, Paul Gortmaker
In-Reply-To: <1305060277-15600-1-git-send-email-paul.gortmaker@windriver.com>

From: Allan Stephens <Allan.Stephens@windriver.com>

Adds checks to TIPC's socket send routines to promptly detect and
abort attempts to send more than 66,000 bytes in a single TIPC
message or more than 2**31-1 bytes in a single TIPC byte stream request.
In addition, this ensures that the number of iovecs in a send request
does not exceed the limits of a standard integer variable.

Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 include/linux/tipc.h |    2 +-
 net/tipc/socket.c    |   13 +++++++++++++
 2 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/include/linux/tipc.h b/include/linux/tipc.h
index a5b994a..f2d9009 100644
--- a/include/linux/tipc.h
+++ b/include/linux/tipc.h
@@ -101,7 +101,7 @@ static inline unsigned int tipc_node(__u32 addr)
  * Limiting values for messages
  */
 
-#define TIPC_MAX_USER_MSG_SIZE	66000
+#define TIPC_MAX_USER_MSG_SIZE	66000U
 
 /*
  * Message importance levels
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 29d94d5..e1c7917 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -535,6 +535,9 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
 	if (unlikely((m->msg_namelen < sizeof(*dest)) ||
 		     (dest->family != AF_TIPC)))
 		return -EINVAL;
+	if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
+	    (m->msg_iovlen > (unsigned)INT_MAX))
+		return -EMSGSIZE;
 
 	if (iocb)
 		lock_sock(sk);
@@ -640,6 +643,10 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
 	if (unlikely(dest))
 		return send_msg(iocb, sock, m, total_len);
 
+	if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
+	    (m->msg_iovlen > (unsigned)INT_MAX))
+		return -EMSGSIZE;
+
 	if (iocb)
 		lock_sock(sk);
 
@@ -723,6 +730,12 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
 		goto exit;
 	}
 
+	if ((total_len > (unsigned)INT_MAX) ||
+	    (m->msg_iovlen > (unsigned)INT_MAX)) {
+		res = -EMSGSIZE;
+		goto exit;
+	}
+
 	/*
 	 * Send each iovec entry using one or more messages
 	 *
-- 
1.7.4.4


^ permalink raw reply related

* [PATCH net-next 21/21] tipc: Revise timings used when sending link request messages
From: Paul Gortmaker @ 2011-05-10 20:44 UTC (permalink / raw)
  To: davem; +Cc: netdev, Allan.Stephens, Paul Gortmaker
In-Reply-To: <1305060277-15600-1-git-send-email-paul.gortmaker@windriver.com>

From: Allan Stephens <Allan.Stephens@windriver.com>

Revises the algorithm governing the sending of link request messages
to take into account the number of nodes each bearer is currently in
contact with, and to ensure more rapid rediscovery of neighboring nodes
if a bearer fails and then recovers.

The discovery object now sends requests at least once a second if it
is not in contact with any other nodes, and at least once a minute if
it has at least one neighbor; if contact with the only neighbor is
lost, the object immediately reverts to its initial rapid-fire search
timing to accelerate the rediscovery process.

In addition, the discovery object now stops issuing link request
messages if it is in contact with the only neighboring node it is
configured to communicate with, since further searching is unnecessary.

Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 net/tipc/discover.c |   66 +++++++++++++++++++++++++++-----------------------
 1 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 3cb232d..0987933 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -39,13 +39,9 @@
 #include "discover.h"
 
 #define TIPC_LINK_REQ_INIT	125	/* min delay during bearer start up */
-#define TIPC_LINK_REQ_FAST	2000	/* normal delay if bearer has no links */
-#define TIPC_LINK_REQ_SLOW	600000	/* normal delay if bearer has links */
-
-/*
- * TODO: Most of the inter-cluster setup stuff should be
- * rewritten, and be made conformant with specification.
- */
+#define TIPC_LINK_REQ_FAST	1000	/* max delay if bearer has no links */
+#define TIPC_LINK_REQ_SLOW	60000	/* max delay if bearer has links */
+#define TIPC_LINK_REQ_INACTIVE	0xffffffff /* indicates no timer in use */
 
 
 /**
@@ -220,22 +216,19 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
 /**
  * disc_update - update frequency of periodic link setup requests
  * @req: ptr to link request structure
+ *
+ * Reinitiates discovery process if discovery object has no associated nodes
+ * and is either not currently searching or is searching at a slow rate
  */
 
 static void disc_update(struct link_req *req)
 {
-	if (req->timer_intv == TIPC_LINK_REQ_SLOW) {
-		if (!req->bearer->nodes.count) {
-			req->timer_intv = TIPC_LINK_REQ_FAST;
+	if (!req->num_nodes) {
+		if ((req->timer_intv == TIPC_LINK_REQ_INACTIVE) ||
+		    (req->timer_intv > TIPC_LINK_REQ_FAST)) {
+			req->timer_intv = TIPC_LINK_REQ_INIT;
 			k_start_timer(&req->timer, req->timer_intv);
 		}
-	} else if (req->timer_intv == TIPC_LINK_REQ_FAST) {
-		if (req->bearer->nodes.count) {
-			req->timer_intv = TIPC_LINK_REQ_SLOW;
-			k_start_timer(&req->timer, req->timer_intv);
-		}
-	} else {
-		/* leave timer "as is" if haven't yet reached a "normal" rate */
 	}
 }
 
@@ -247,7 +240,6 @@ static void disc_update(struct link_req *req)
 void tipc_disc_add_dest(struct link_req *req)
 {
 	req->num_nodes++;
-	disc_update(req);
 }
 
 /**
@@ -281,23 +273,37 @@ static void disc_send_msg(struct link_req *req)
 
 static void disc_timeout(struct link_req *req)
 {
+	int max_delay;
+
 	spin_lock_bh(&req->bearer->lock);
 
-	disc_send_msg(req);
+	/* Stop searching if only desired node has been found */
 
-	if ((req->timer_intv == TIPC_LINK_REQ_SLOW) ||
-	    (req->timer_intv == TIPC_LINK_REQ_FAST)) {
-		/* leave timer interval "as is" if already at a "normal" rate */
-	} else {
-		req->timer_intv *= 2;
-		if (req->timer_intv > TIPC_LINK_REQ_FAST)
-			req->timer_intv = TIPC_LINK_REQ_FAST;
-		if ((req->timer_intv == TIPC_LINK_REQ_FAST) &&
-		    (req->bearer->nodes.count))
-			req->timer_intv = TIPC_LINK_REQ_SLOW;
+	if (tipc_node(req->domain) && req->num_nodes) {
+		req->timer_intv = TIPC_LINK_REQ_INACTIVE;
+		goto exit;
 	}
-	k_start_timer(&req->timer, req->timer_intv);
 
+	/*
+	 * Send discovery message, then update discovery timer
+	 *
+	 * Keep doubling time between requests until limit is reached;
+	 * hold at fast polling rate if don't have any associated nodes,
+	 * otherwise hold at slow polling rate
+	 */
+
+	disc_send_msg(req);
+
+	req->timer_intv *= 2;
+	if (req->num_nodes)
+		max_delay = TIPC_LINK_REQ_SLOW;
+	else
+		max_delay = TIPC_LINK_REQ_FAST;
+	if (req->timer_intv > max_delay)
+		req->timer_intv = max_delay;
+
+	k_start_timer(&req->timer, req->timer_intv);
+exit:
 	spin_unlock_bh(&req->bearer->lock);
 }
 
-- 
1.7.4.4


^ permalink raw reply related

* [PATCH net-next 20/21] tipc: Add monitoring of number of nodes discovered by bearer
From: Paul Gortmaker @ 2011-05-10 20:44 UTC (permalink / raw)
  To: davem; +Cc: netdev, Allan.Stephens, Paul Gortmaker
In-Reply-To: <1305060277-15600-1-git-send-email-paul.gortmaker@windriver.com>

From: Allan Stephens <Allan.Stephens@windriver.com>

Augments TIPC's discovery object to track the number of neighboring nodes
having an active link to the associated bearer.

This means tipc_disc_update_link_req() becomes either one of:

       tipc_disc_add_dest()
or:
       tipc_disc_remove_dest()

depending on the code flow direction of things.

Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 net/tipc/bearer.c   |    4 ++--
 net/tipc/discover.c |   32 +++++++++++++++++++++++++++-----
 net/tipc/discover.h |    3 ++-
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 5fcd1c1..85209ea 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -344,15 +344,15 @@ struct sk_buff *tipc_bearer_get_names(void)
 void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest)
 {
 	tipc_nmap_add(&b_ptr->nodes, dest);
-	tipc_disc_update_link_req(b_ptr->link_req);
 	tipc_bcbearer_sort();
+	tipc_disc_add_dest(b_ptr->link_req);
 }
 
 void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest)
 {
 	tipc_nmap_remove(&b_ptr->nodes, dest);
-	tipc_disc_update_link_req(b_ptr->link_req);
 	tipc_bcbearer_sort();
+	tipc_disc_remove_dest(b_ptr->link_req);
 }
 
 /*
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index dba4767..3cb232d 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -53,6 +53,7 @@
  * @bearer: bearer issuing requests
  * @dest: destination address for request messages
  * @domain: network domain to which links can be established
+ * @num_nodes: number of nodes currently discovered (i.e. with an active link)
  * @buf: request message to be (repeatedly) sent
  * @timer: timer governing period between requests
  * @timer_intv: current interval between requests (in ms)
@@ -61,6 +62,7 @@ struct link_req {
 	struct tipc_bearer *bearer;
 	struct tipc_media_addr dest;
 	u32 domain;
+	int num_nodes;
 	struct sk_buff *buf;
 	struct timer_list timer;
 	unsigned int timer_intv;
@@ -216,15 +218,12 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
 }
 
 /**
- * tipc_disc_update_link_req - update frequency of periodic link setup requests
+ * disc_update - update frequency of periodic link setup requests
  * @req: ptr to link request structure
  */
 
-void tipc_disc_update_link_req(struct link_req *req)
+static void disc_update(struct link_req *req)
 {
-	if (!req)
-		return;
-
 	if (req->timer_intv == TIPC_LINK_REQ_SLOW) {
 		if (!req->bearer->nodes.count) {
 			req->timer_intv = TIPC_LINK_REQ_FAST;
@@ -241,6 +240,28 @@ void tipc_disc_update_link_req(struct link_req *req)
 }
 
 /**
+ * tipc_disc_add_dest - increment set of discovered nodes
+ * @req: ptr to link request structure
+ */
+
+void tipc_disc_add_dest(struct link_req *req)
+{
+	req->num_nodes++;
+	disc_update(req);
+}
+
+/**
+ * tipc_disc_remove_dest - decrement set of discovered nodes
+ * @req: ptr to link request structure
+ */
+
+void tipc_disc_remove_dest(struct link_req *req)
+{
+	req->num_nodes--;
+	disc_update(req);
+}
+
+/**
  * disc_send_msg - send link setup request message
  * @req: ptr to link request structure
  */
@@ -307,6 +328,7 @@ int tipc_disc_create(struct tipc_bearer *b_ptr,
 	memcpy(&req->dest, dest, sizeof(*dest));
 	req->bearer = b_ptr;
 	req->domain = dest_domain;
+	req->num_nodes = 0;
 	req->timer_intv = TIPC_LINK_REQ_INIT;
 	k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req);
 	k_start_timer(&req->timer, req->timer_intv);
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index d6e44e3..a3af595 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -42,7 +42,8 @@ struct link_req;
 int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest,
 		     u32 dest_domain);
 void tipc_disc_delete(struct link_req *req);
-void tipc_disc_update_link_req(struct link_req *req);
+void tipc_disc_add_dest(struct link_req *req);
+void tipc_disc_remove_dest(struct link_req *req);
 void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr);
 
 #endif
-- 
1.7.4.4


^ permalink raw reply related

* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Eric Dumazet @ 2011-05-10 20:45 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Vegard Nossum, Pekka Enberg, casteyde.christian, Andrew Morton,
	netdev, bugzilla-daemon, bugme-daemon
In-Reply-To: <alpine.DEB.2.00.1105101531160.4023@router.home>

Le mardi 10 mai 2011 à 15:33 -0500, Christoph Lameter a écrit :
> On Tue, 10 May 2011, Eric Dumazet wrote:
> 
> > Le mardi 10 mai 2011 à 14:38 -0500, Christoph Lameter a écrit :
> >
> > > Optimizing? You think about this as concurrency issue between multiple
> > > cpus. That is fundamentally wrong. This is dealing with access to per cpu
> > > data and the concurrency issues are only with code running on the *same*
> > > cpu.
> > >
> >
> > If you enable irqs, then this object can be allocated by _this_ cpu and
> > given to another one.
> 
> That will cause an incrementing of the tid.
> 
> > Another cpu can free the page, forcing you to call a very expensive
> > function, that might give obsolete result as soon it returns.
> 
> No the other cpu cannot free the page since the page is pinned by
> the current cpu (see PageFrozen()).
> 

What happens then ? Other cpu calls kfree() on last nonfreed object for
this slab, and yet the page stay frozen ? How this page is going to be
freed at all ?

> > Maybe I am just tired tonight, this seems very obvious, I must miss
> > something.
> 
> Yeah you are way off thinking about cpu to cpu concurrency issues that do
> not apply here.

I fail to understand how current cpu can assert page ownership, if IRQs
are enabled, this seems obvious it cannot.




^ permalink raw reply

* Re: [PATCHv2 net-next-2.6 2/2] qlcnic: Take FW dump via ethtool
From: Anirban Chakraborty @ 2011-05-10 21:00 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev, David Miller
In-Reply-To: <1305052826.2859.53.camel@bwh-desktop>


On May 10, 2011, at 11:40 AM, Ben Hutchings wrote:

> On Mon, 2011-05-09 at 18:02 -0700, Anirban Chakraborty wrote:
>> Driver checks if the previous dump has been cleared before taking the dump.
>> It doesn't take the dump if it is not cleared.
>> 
>> Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
>> ---
>> drivers/net/qlcnic/qlcnic_ethtool.c |   60 +++++++++++++++++++++++++++++++++++
>> 1 files changed, 60 insertions(+), 0 deletions(-)
>> 
>> diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
>> index c541461..1237449 100644
>> --- a/drivers/net/qlcnic/qlcnic_ethtool.c
>> +++ b/drivers/net/qlcnic/qlcnic_ethtool.c
>> @@ -965,6 +965,64 @@ static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
>> 	adapter->msg_enable = msglvl;
>> }
>> 
>> +static int
>> +qlcnic_get_dump(struct net_device *netdev, struct ethtool_dump *dump,
>> +		void *buffer)
>> +{
>> +	int i, copy_sz;
>> +	u32 *hdr_ptr, *data;
>> +	struct qlcnic_adapter *adapter = netdev_priv(netdev);
>> +	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
>> +
>> +	if (dump->type == ETHTOOL_DUMP_FLAG) {
>> +		dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
>> +		dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
>> +		return 0;
>> +	}
>> +	if (!fw_dump->clr) {
>> +		netdev_info(netdev, "Dump not available\n");
>> +		return -EINVAL;
>> +	}
>> +	copy_sz = fw_dump->tmpl_hdr->size;
>> +	/* Copy template header first */
>> +	hdr_ptr = (u32 *) fw_dump->tmpl_hdr;
>> +	data = (u32 *) buffer;
>> +	for (i = 0; i < copy_sz/sizeof(u32); i++)
>> +		*data++ = cpu_to_le32(*hdr_ptr++);
>> +	/* Copy captured dump data */
>> +	memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
>> +	dump->len = copy_sz + fw_dump->size;
>> +	dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
>> +	/* free dump area once the whoel dump data has been captured */
>> +	vfree(fw_dump->data);
>> +	fw_dump->size = 0;
>> +	fw_dump->data = NULL;
>> +	fw_dump->clr = 0;
> 
> This doesn't seem to be serialised with the code that captures firmware
> dumps.  They need to use the same lock!
When we take the dump, we bring down the interface. So, ethtool will not get a chance to
fetch the dump data while the dump operation is in progress.

> 
>> +	return 0;
>> +}
>> +
>> +static int
>> +qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
>> +{
>> +	struct qlcnic_adapter *adapter = netdev_priv(netdev);
>> +	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
>> +	if (val->flag == QLCNIC_FORCE_FW_DUMP_KEY) {
>> +		netdev_info(netdev, "Forcing a FW dump\n");
>> +		qlcnic_dev_request_reset(adapter);
>> +	} else {
>> +		if (val->flag > QLCNIC_DUMP_MASK_MAX ||
>> +			val->flag < QLCNIC_DUMP_MASK_MIN) {
>> +				netdev_info(netdev,
>> +				"Invalid dump level: 0x%x\n", val->flag);
>> +				return -EINVAL;
>> +		}
>> +		fw_dump->tmpl_hdr->drv_cap_mask = val->flag & 0xff;
>> +		netdev_info(netdev, "Driver mask changed to: 0x%x\n",
>> +			fw_dump->tmpl_hdr->drv_cap_mask);
> 
> If the flags change, doesn't this invalidate any dump that has been
> collected by the driver but not saved?
If the flags change, its effect would be relevant from the next dump capture. The flag indicates to the
driver to gather FW dump for a specific level of detail.

> 
> Also, same locking problem here.
Addressed above.

Thanks for reviewing. 

-Anirban



^ permalink raw reply

* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Christoph Lameter @ 2011-05-10 21:22 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Vegard Nossum, Pekka Enberg, casteyde.christian, Andrew Morton,
	netdev, bugzilla-daemon, bugme-daemon
In-Reply-To: <1305060353.2437.26.camel@edumazet-laptop>

On Tue, 10 May 2011, Eric Dumazet wrote:

> > No the other cpu cannot free the page since the page is pinned by
> > the current cpu (see PageFrozen()).
> >
>
> What happens then ? Other cpu calls kfree() on last nonfreed object for
> this slab, and yet the page stay frozen ? How this page is going to be
> freed at all ?

Yes the page stays frozen. The freed objects are used to replenish the
percpu free list when it becomes empty.

The page is going to be freed when a kmalloc() finds that the per cpu
freelist is empty and that the freelist of the page is also empty. Then
interrupts are disabled, the old page is unfrozen and a new
page is acquired for allocation.

> > > Maybe I am just tired tonight, this seems very obvious, I must miss
> > > something.
> >
> > Yeah you are way off thinking about cpu to cpu concurrency issues that do
> > not apply here.
>
> I fail to understand how current cpu can assert page ownership, if IRQs
> are enabled, this seems obvious it cannot.

The cpu sets a page flag called PageFrozen() and points a per cpu pointer
to the page.



^ permalink raw reply

* [PATCH v2 1/5] ssb: Change fallback sprom to callback mechanism.
From: Hauke Mehrtens @ 2011-05-10 21:31 UTC (permalink / raw)
  To: ralf-6z/3iImG2C8G8FEW9MqTrA
  Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA, Hauke Mehrtens,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA, Florian Fainelli
In-Reply-To: <1305063094-26656-1-git-send-email-hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>

Some embedded devices like the Netgear WNDR3300 have two SSB based
cards without an own sprom on the pci bus. We have to provide two
different fallback sproms for these and this was not possible with the
old solution. In the bcm47xx architecture the sprom data is stored in
the nvram in the main flash storage. The architecture code will be able
to fill the sprom with the stored data based on the bus where the
device was found.

The bcm63xx code should do the same thing as before, just using the new
API.

Acked-by: Michael Buesch <mb-fseUSCV1ubazQB+pC5nmwQ@public.gmane.org>
CC: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: Florian Fainelli <florian-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
Signed-off-by: Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
---

v2: * fix some checkpatch errors and warnings
    * spelling issues

 arch/mips/bcm63xx/boards/board_bcm963xx.c |   16 +++++++++-
 drivers/ssb/pci.c                         |   16 +++++++---
 drivers/ssb/sprom.c                       |   43 +++++++++++++++++------------
 drivers/ssb/ssb_private.h                 |    3 +-
 include/linux/ssb/ssb.h                   |    4 ++-
 5 files changed, 55 insertions(+), 27 deletions(-)

diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index 8dba8cf..40b223b 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -643,6 +643,17 @@ static struct ssb_sprom bcm63xx_sprom = {
 	.boardflags_lo		= 0x2848,
 	.boardflags_hi		= 0x0000,
 };
+
+int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
+{
+	if (bus->bustype == SSB_BUSTYPE_PCI) {
+		memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
+		return 0;
+	} else {
+		printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
+		return -EINVAL;
+	}
+}
 #endif
 
 /*
@@ -793,8 +804,9 @@ void __init board_prom_init(void)
 	if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
 		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
 		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-		if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
-			printk(KERN_ERR "failed to register fallback SPROM\n");
+		if (ssb_arch_register_fallback_sprom(
+				&bcm63xx_get_fallback_sprom) < 0)
+			printk(KERN_ERR PFX "failed to register fallback SPROM\n");
 	}
 #endif
 }
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 6f34963..7ad4858 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -662,7 +662,6 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
 static int ssb_pci_sprom_get(struct ssb_bus *bus,
 			     struct ssb_sprom *sprom)
 {
-	const struct ssb_sprom *fallback;
 	int err;
 	u16 *buf;
 
@@ -707,10 +706,17 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
 		if (err) {
 			/* All CRC attempts failed.
 			 * Maybe there is no SPROM on the device?
-			 * If we have a fallback, use that. */
-			fallback = ssb_get_fallback_sprom();
-			if (fallback) {
-				memcpy(sprom, fallback, sizeof(*sprom));
+			 * Now we ask the arch code if there is some sprom
+			 * available for this device in some other storage */
+			err = ssb_fill_sprom_with_fallback(bus, sprom);
+			if (err) {
+				ssb_printk(KERN_WARNING PFX "WARNING: Using"
+					   " fallback SPROM failed (err %d)\n",
+					   err);
+			} else {
+				ssb_dprintk(KERN_DEBUG PFX "Using SPROM"
+					    " revision %d provided by"
+					    " platform.\n", sprom->revision);
 				err = 0;
 				goto out_free;
 			}
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
index 5f34d7a..45ff0e3 100644
--- a/drivers/ssb/sprom.c
+++ b/drivers/ssb/sprom.c
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 
 
-static const struct ssb_sprom *fallback_sprom;
+static int(*get_fallback_sprom)(struct ssb_bus *dev, struct ssb_sprom *out);
 
 
 static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len,
@@ -145,36 +145,43 @@ out:
 }
 
 /**
- * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found.
+ * ssb_arch_register_fallback_sprom - Registers a method providing a
+ * fallback SPROM if no SPROM is found.
  *
- * @sprom: The SPROM data structure to register.
+ * @sprom_callback: The callback function.
  *
- * With this function the architecture implementation may register a fallback
- * SPROM data structure. The fallback is only used for PCI based SSB devices,
- * where no valid SPROM can be found in the shadow registers.
+ * With this function the architecture implementation may register a
+ * callback handler which fills the SPROM data structure. The fallback is
+ * only used for PCI based SSB devices, where no valid SPROM can be found
+ * in the shadow registers.
  *
- * This function is useful for weird architectures that have a half-assed SSB device
- * hardwired to their PCI bus.
+ * This function is useful for weird architectures that have a half-assed
+ * SSB device hardwired to their PCI bus.
  *
- * Note that it does only work with PCI attached SSB devices. PCMCIA devices currently
- * don't use this fallback.
- * Architectures must provide the SPROM for native SSB devices anyway,
- * so the fallback also isn't used for native devices.
+ * Note that it does only work with PCI attached SSB devices. PCMCIA
+ * devices currently don't use this fallback.
+ * Architectures must provide the SPROM for native SSB devices anyway, so
+ * the fallback also isn't used for native devices.
  *
- * This function is available for architecture code, only. So it is not exported.
+ * This function is available for architecture code, only. So it is not
+ * exported.
  */
-int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom)
+int ssb_arch_register_fallback_sprom(int (*sprom_callback)(struct ssb_bus *bus,
+				     struct ssb_sprom *out))
 {
-	if (fallback_sprom)
+	if (get_fallback_sprom)
 		return -EEXIST;
-	fallback_sprom = sprom;
+	get_fallback_sprom = sprom_callback;
 
 	return 0;
 }
 
-const struct ssb_sprom *ssb_get_fallback_sprom(void)
+int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out)
 {
-	return fallback_sprom;
+	if (!get_fallback_sprom)
+		return -ENOENT;
+
+	return get_fallback_sprom(bus, out);
 }
 
 /* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index 0331139..7765301 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -171,7 +171,8 @@ ssize_t ssb_attr_sprom_store(struct ssb_bus *bus,
 			     const char *buf, size_t count,
 			     int (*sprom_check_crc)(const u16 *sprom, size_t size),
 			     int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom));
-extern const struct ssb_sprom *ssb_get_fallback_sprom(void);
+extern int ssb_fill_sprom_with_fallback(struct ssb_bus *bus,
+					struct ssb_sprom *out);
 
 
 /* core.c */
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 9659eff..045f72a 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -404,7 +404,9 @@ extern bool ssb_is_sprom_available(struct ssb_bus *bus);
 
 /* Set a fallback SPROM.
  * See kdoc at the function definition for complete documentation. */
-extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
+extern int ssb_arch_register_fallback_sprom(
+		int (*sprom_callback)(struct ssb_bus *bus,
+		struct ssb_sprom *out));
 
 /* Suspend a SSB bus.
  * Call this from the parent bus suspend routine. */
-- 
1.7.4.1

--
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 related

* Re: 2.6.39-rc6-mmotm0506 - another lockdep splat (networking this time)
From: Eric Dumazet @ 2011-05-10 21:48 UTC (permalink / raw)
  To: David Miller; +Cc: Valdis.Kletnieks, akpm, linux-kernel, netdev
In-Reply-To: <20110509.205851.189693332.davem@davemloft.net>

Le lundi 09 mai 2011 à 20:58 -0700, David Miller a écrit :
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Tue, 10 May 2011 05:47:51 +0200
> 
> > [PATCH net-next-2.6] net: fix two lockdep splats
> > 
> > Commit e67f88dd12f6 (net: dont hold rtnl mutex during netlink dump
> > callbacks) switched rtnl protection to RCU, but we forgot to adjust two
> > rcu_dereference() lockdep annotations :
> > 
> > inet_get_link_af_size() or inet_fill_link_af() might be called with
> > rcu_read_lock or rtnl held, so use rcu_dereference_rtnl()
> > instead of rtnl_dereference()
> > 
> > Reported-by: Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
> > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> 
> Applied, thanks everyone.

David, I found you applied this patch for net-2.6, but it was
net-next-2.6 material only ...

^ permalink raw reply

* RE: [PATCH 0/7] Network namespace manipulation with file descriptors
From: Luck, Tony @ 2011-05-10 21:56 UTC (permalink / raw)
  To: David Miller, ebiederm@xmission.com
  Cc: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	hadi@cyberus.ca, daniel.lezcano@free.fr,
	containers@lists.osdl.org, renatowestphal@gmail.com
In-Reply-To: <20110509.134007.116389415.davem@davemloft.net>

>> The conflicts on syscall syscall numbers are an unfortunate pain.
>
> The way we've solved this before is the tree that cares pulls in
> the net-next-2.6 tree to resolve the conflict.

Actually it seems more common that new syscalls are only added to
x86 (plus one or more other architectures that the author cares
about). Then arch maintainers throw in a "wire up new syscalls"
patch during the merge window when they see these new bits show up.

-Tony

Oh - ia64 wiring looks good.

Acked-by: Tony Luck <tony.luck@intel.com>

^ permalink raw reply

* Re: [PATCHv2 net-next-2.6 2/2] qlcnic: Take FW dump via ethtool
From: Ben Hutchings @ 2011-05-10 21:58 UTC (permalink / raw)
  To: Anirban Chakraborty; +Cc: netdev, David Miller
In-Reply-To: <3D85CC75-765C-4059-BB3F-82CCBF748FBC@qlogic.com>

On Tue, 2011-05-10 at 14:00 -0700, Anirban Chakraborty wrote:
> On May 10, 2011, at 11:40 AM, Ben Hutchings wrote:
> 
> > On Mon, 2011-05-09 at 18:02 -0700, Anirban Chakraborty wrote:
> >> Driver checks if the previous dump has been cleared before taking the dump.
> >> It doesn't take the dump if it is not cleared.
> >> 
> >> Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
> >> ---
> >> drivers/net/qlcnic/qlcnic_ethtool.c |   60 +++++++++++++++++++++++++++++++++++
> >> 1 files changed, 60 insertions(+), 0 deletions(-)
> >> 
> >> diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
> >> index c541461..1237449 100644
> >> --- a/drivers/net/qlcnic/qlcnic_ethtool.c
> >> +++ b/drivers/net/qlcnic/qlcnic_ethtool.c
> >> @@ -965,6 +965,64 @@ static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
> >> 	adapter->msg_enable = msglvl;
> >> }
> >> 
> >> +static int
> >> +qlcnic_get_dump(struct net_device *netdev, struct ethtool_dump *dump,
> >> +		void *buffer)
> >> +{
> >> +	int i, copy_sz;
> >> +	u32 *hdr_ptr, *data;
> >> +	struct qlcnic_adapter *adapter = netdev_priv(netdev);
> >> +	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
> >> +
> >> +	if (dump->type == ETHTOOL_DUMP_FLAG) {
> >> +		dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
> >> +		dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
> >> +		return 0;
> >> +	}
> >> +	if (!fw_dump->clr) {
> >> +		netdev_info(netdev, "Dump not available\n");
> >> +		return -EINVAL;
> >> +	}
> >> +	copy_sz = fw_dump->tmpl_hdr->size;
> >> +	/* Copy template header first */
> >> +	hdr_ptr = (u32 *) fw_dump->tmpl_hdr;
> >> +	data = (u32 *) buffer;
> >> +	for (i = 0; i < copy_sz/sizeof(u32); i++)
> >> +		*data++ = cpu_to_le32(*hdr_ptr++);
> >> +	/* Copy captured dump data */
> >> +	memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
> >> +	dump->len = copy_sz + fw_dump->size;
> >> +	dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
> >> +	/* free dump area once the whoel dump data has been captured */
> >> +	vfree(fw_dump->data);
> >> +	fw_dump->size = 0;
> >> +	fw_dump->data = NULL;
> >> +	fw_dump->clr = 0;
> > 
> > This doesn't seem to be serialised with the code that captures firmware
> > dumps.  They need to use the same lock!
> When we take the dump, we bring down the interface. So, ethtool will not get a chance to
> fetch the dump data while the dump operation is in progress.
[...]

The ethtool core generally doesn't care whether the interface is
running.  Its operations are serialised only by the RTNL lock.  The work
item you added to extract a dump from the NIC does not take that lock.

Ben.

-- 
Ben Hutchings, Senior Software 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

* Re: 2.6.39-rc6-mmotm0506 - another lockdep splat (networking this time)
From: David Miller @ 2011-05-10 21:59 UTC (permalink / raw)
  To: eric.dumazet; +Cc: Valdis.Kletnieks, akpm, linux-kernel, netdev
In-Reply-To: <1305064116.2437.34.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 10 May 2011 23:48:36 +0200

> Le lundi 09 mai 2011 à 20:58 -0700, David Miller a écrit :
>> From: Eric Dumazet <eric.dumazet@gmail.com>
>> Date: Tue, 10 May 2011 05:47:51 +0200
>> 
>> > [PATCH net-next-2.6] net: fix two lockdep splats
>> > 
>> > Commit e67f88dd12f6 (net: dont hold rtnl mutex during netlink dump
>> > callbacks) switched rtnl protection to RCU, but we forgot to adjust two
>> > rcu_dereference() lockdep annotations :
>> > 
>> > inet_get_link_af_size() or inet_fill_link_af() might be called with
>> > rcu_read_lock or rtnl held, so use rcu_dereference_rtnl()
>> > instead of rtnl_dereference()
>> > 
>> > Reported-by: Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
>> > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>> 
>> Applied, thanks everyone.
> 
> David, I found you applied this patch for net-2.6, but it was
> net-next-2.6 material only ...

Thanks for catching that, I'll fix this.

^ permalink raw reply

* GIT net-2.6 rolled back 8 commits...
From: David Miller @ 2011-05-10 22:08 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netfilter-devel-u79uwXL29TY76Z2rM5mHXA


I made a mistake and applied to net-2.6 a patch from Eric Dumazet that
only is applicable for net-next-2.6

I really don't want to have to toss Linus that commit and a revert commit
just to fix it up.

So I rewound the net-2.6 tree by 8 commits.

So if you've pulled in the past 3 hours, please reset your pull and repull.

Thanks!
--
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: [Bridge] Bug#625914: linux-image-2.6.38-2-amd64: bridging is not interacting well with multicast in 2.6.38-4
From: Stephen Hemminger @ 2011-05-10 22:11 UTC (permalink / raw)
  To: Noah Meyerhans; +Cc: Ben Hutchings, 625914, bridge, netdev
In-Reply-To: <20110510180540.GI6397@morgul.net>

On Tue, 10 May 2011 11:05:40 -0700
Noah Meyerhans <noahm@debian.org> wrote:

> On Tue, May 10, 2011 at 01:42:49PM +0100, Ben Hutchings wrote:
> > > > This is pretty weird.  Debian version 2.6.38-3 has a few bridging
> > > > changes from stable 2.6.38.3 and 2.6.38.4, but they don't look like they
> > > > would cause this.
> > > 
> > > I have apparently filed the bug against the wrong version of Debian's
> > > kernel.  2.6.38-3 is not affected, and works as expected.  The change
> > > was introduced in -4.  That may have been clear from the report itself,
> > > but the report was filed against -3.  I've fixed that in the BTS.
> > 
> > I gathered that, and then made the same mistake in writing the above!
> > The version with the regression, 2.6.38-4, includes the changes from
> > stable 2.6.38.3 and 2.6.38.4
> 
> With a little help from git bisect, I've tracked this regression down to
> the following commit to the stable-2.6.38.y tree:
> 
> commit 5f1c356a3fadc0c19922d660da723b79bcc9aad7
> Author: Herbert Xu <herbert@gondor.apana.org.au>
> Date:   Fri Mar 18 05:27:28 2011 +0000
> 
>     bridge: Reset IPCB when entering IP stack on NF_FORWARD
>     
>     [ Upstream commit 6b1e960fdbd75dcd9bcc3ba5ff8898ff1ad30b6e ]
>     
>     Whenever we enter the IP stack proper from bridge netfilter we
>     need to ensure that the skb is in a form the IP stack expects
>     it to be in.
>     
>     The entry point on NF_FORWARD did not meet the requirements of
>     the IP stack, therefore leading to potential crashes/panics.
>     
>     This patch fixes the problem.
>     
>     Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>     Acked-by: Stephen Hemminger <shemminger@vyatta.com>
>     Signed-off-by: David S. Miller <davem@davemloft.net>
>     Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
> 
> The diff is
> diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
> index 4b5b66d..49d50ea 100644
> --- a/net/bridge/br_netfilter.c
> +++ b/net/bridge/br_netfilter.c
> @@ -741,6 +741,9 @@ static unsigned int br_nf_forward_ip(unsigned int
> hook, struct sk_buff *skb,
>                 nf_bridge->mask |= BRNF_PKT_TYPE;
>         }
>  
> +       if (br_parse_ip_options(skb))
> +               return NF_DROP;
> +
>         /* The physdev module checks on this */
>         nf_bridge->mask |= BRNF_BRIDGED;
>         nf_bridge->physoutdev = skb->dev;
> 
> If I revert this change, network connectivity functions as expected for
> the VMs on this host.
> 
> I don't know enough about this change or the problem it was supposed to
> solve to be able to guess about what's going wrong.
> 
> noah
> 

There were two more follow on commits in stable related to this.
I recommend merging 2.6.38.6 which includes these.


-- 

^ permalink raw reply

* Re: [PATCH 2/2] net/dl2k: Don't reconfigure link @100Mbps when disabling autoneg @1Gbps
From: David Decotigny @ 2011-05-10 22:14 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: Giuseppe Cavallaro, David S. Miller, Joe Perches,
	Stanislaw Gruszka, netdev, linux-kernel
In-Reply-To: <1305053707.2859.57.camel@bwh-desktop>

Hi all,

Yes, right, I will send the updated patch together with the stmmac
update (if any).

I just hope that changing the netdev_private fields without committing
to hardware and before calling netif_carrier_off() will not create too
much confusion. I don't think so, but I still wish I could test.

Regards,

--
David Decotigny



On Tue, May 10, 2011 at 11:55 AM, Ben Hutchings
<bhutchings@solarflare.com> wrote:
> On Mon, 2011-05-09 at 17:19 -0700, David Decotigny wrote:
>> The initial version of the driver used to force the link to 100Mbps
>> when auto-negociation was disabled on a 1Gbps link, ignoring the
>> requested link speed. Instead, this change refuses to change anything
>> when it is asked to configure the link speed at 1Gbps without
>> auto-negociation, but acts as requested in all the other cases.
>>
>> IMPORTANT: Previously, the return value from mii_set_media() was
>>            ignored. This patch uses it for its own return value.
>>
>> Tested: module compiling, NOT tested on real hardware.
>> Signed-off-by: David Decotigny <decot@google.com>
> [...]
>
> The changes to validation look fine.  However, I noticed that there's a
> call to netif_carrier_off() at the top of this function.  This means
> that in the error and shortcut cases, the interface will be left
> disabled!  It's an existing bug but might be made slightly worse by this
> change.
>
> Please also move the call to netif_carrier_off() down to the end, just
> before the call to mii_set_media() which actually alters the link.
>
> Ben.
>
> --
> Ben Hutchings, Senior Software 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

* Re: [PATCHv2 net-next-2.6 2/2] qlcnic: Take FW dump via ethtool
From: Anirban Chakraborty @ 2011-05-10 22:19 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev, David Miller
In-Reply-To: <1305064696.2859.90.camel@bwh-desktop>


On May 10, 2011, at 2:58 PM, Ben Hutchings wrote:

>>>> <snip>
>>> 
>>> This doesn't seem to be serialised with the code that captures firmware
>>> dumps.  They need to use the same lock!
>> When we take the dump, we bring down the interface. So, ethtool will not get a chance to
>> fetch the dump data while the dump operation is in progress.
> [...]
> 
> The ethtool core generally doesn't care whether the interface is
> running.  Its operations are serialised only by the RTNL lock.  The work
> item you added to extract a dump from the NIC does not take that lock.

Oh, ok. Thanks for pointing that out.

-Anirban



^ permalink raw reply

* Re: [PATCH 4/10] ipvs: Use IP_VS_RT_MODE_* instead of magic constants.
From: Julian Anastasov @ 2011-05-10 22:26 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20110509.223118.260083861.davem@davemloft.net>


	Fix more IP_VS_RT_MODE_* constants

Signed-off-by: Julian Anastasov <ja@ssi.bg>
---

	Following patch can be used after patch 4, eg. as
number 6 because patches 4 and 5 are ok and we are going to replace
patches 6 and 7.

diff -urp net-next-2.6-7ef73bc/linux/net/netfilter/ipvs/ip_vs_xmit.c linux/net/netfilter/ipvs/ip_vs_xmit.c
--- net-next-2.6-7ef73bc/linux/net/netfilter/ipvs/ip_vs_xmit.c	2011-05-10 23:51:34.831272176 +0300
+++ linux/net/netfilter/ipvs/ip_vs_xmit.c	2011-05-10 23:51:28.900271527 +0300
@@ -230,8 +230,6 @@ out_err:
 
 /*
  * Get route to destination or remote server
- * rt_mode: flags, &1=Allow local dest, &2=Allow non-local dest,
- *	    &4=Allow redirect from remote daddr to local
  */
 static struct rt6_info *
 __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
@@ -275,13 +273,14 @@ __ip_vs_get_out_rt_v6(struct sk_buff *sk
 	}
 
 	local = __ip_vs_is_local_route6(rt);
-	if (!((local ? 1 : 2) & rt_mode)) {
+	if (!((local ? IP_VS_RT_MODE_LOCAL : IP_VS_RT_MODE_NON_LOCAL) &
+	      rt_mode)) {
 		IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI6\n",
 			     local ? "local":"non-local", daddr);
 		dst_release(&rt->dst);
 		return NULL;
 	}
-	if (local && !(rt_mode & 4) &&
+	if (local && !(rt_mode & IP_VS_RT_MODE_RDR) &&
 	    !((ort = (struct rt6_info *) skb_dst(skb)) &&
 	      __ip_vs_is_local_route6(ort))) {
 		IP_VS_DBG_RL("Redirect from non-local address %pI6 to local "

^ permalink raw reply

* Re: [PATCH 4/10] ipvs: Use IP_VS_RT_MODE_* instead of magic constants.
From: David Miller @ 2011-05-10 22:30 UTC (permalink / raw)
  To: ja; +Cc: netdev
In-Reply-To: <alpine.LFD.2.00.1105110123001.4532@ja.ssi.bg>

From: Julian Anastasov <ja@ssi.bg>
Date: Wed, 11 May 2011 01:26:09 +0300 (EEST)

> 
> 	Fix more IP_VS_RT_MODE_* constants
> 
> Signed-off-by: Julian Anastasov <ja@ssi.bg>
> ---
> 
> 	Following patch can be used after patch 4, eg. as
> number 6 because patches 4 and 5 are ok and we are going to replace
> patches 6 and 7.

Thanks Julian.

What I'm going to do is hold back the IPVS parts of the patches I
posted last night.  In particular, I'll integrate this into the
original patch #4.

And then we can work through the reimplementation ideas you posted to
me in private email.

If you could post those ideas here on the list I'd appreciate it,
so others can follow along and provide feedback.

Thanks!

^ permalink raw reply

* Re: [PATCH 7/10] ipvs: Remove all remaining references to rt->rt_{src,dst}
From: Julian Anastasov @ 2011-05-10 22:46 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20110509.223127.102546540.davem@davemloft.net>


	Remove all remaining references to rt->rt_{src,dst}
by using dest->dst_saddr to cache saddr (used for TUN mode).
For ICMP in FORWARD hook just restrict the rt_mode for NAT
to disable LOCALNODE. All other modes do not allow
IP_VS_RT_MODE_RDR, so we should be safe with the ICMP
forwarding. Using cp->daddr as replacement for rt_dst
is safe for all modes except BYPASS, even when cp->dest is
NULL because it is cp->daddr that is used to assign cp->dest
for sync-ed connections.

Signed-off-by: Julian Anastasov <ja@ssi.bg>
---

	I'm proposing this patch as replacement for
original patches 6 and 7, it can be number 7 again.
The idea is to avoid storing flowi in cp.

diff -urp net-next-2.6-7ef73bc/linux/include/net/ip_vs.h linux/include/net/ip_vs.h
--- net-next-2.6-7ef73bc/linux/include/net/ip_vs.h	2011-05-09 07:24:07.000000000 +0300
+++ linux/include/net/ip_vs.h	2011-05-11 00:46:02.510271856 +0300
@@ -665,9 +665,7 @@ struct ip_vs_dest {
 	struct dst_entry	*dst_cache;	/* destination cache entry */
 	u32			dst_rtos;	/* RT_TOS(tos) for dst */
 	u32			dst_cookie;
-#ifdef CONFIG_IP_VS_IPV6
-	struct in6_addr		dst_saddr;
-#endif
+	union nf_inet_addr	dst_saddr;
 
 	/* for virtual service */
 	struct ip_vs_service	*svc;		/* service it belongs to */
@@ -1236,7 +1234,8 @@ extern int ip_vs_tunnel_xmit
 extern int ip_vs_dr_xmit
 (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
 extern int ip_vs_icmp_xmit
-(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp, int offset);
+(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp,
+ int offset, unsigned int hooknum);
 extern void ip_vs_dst_reset(struct ip_vs_dest *dest);
 
 #ifdef CONFIG_IP_VS_IPV6
@@ -1250,7 +1249,7 @@ extern int ip_vs_dr_xmit_v6
 (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
 extern int ip_vs_icmp_xmit_v6
 (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp,
- int offset);
+ int offset, unsigned int hooknum);
 #endif
 
 #ifdef CONFIG_SYSCTL
diff -urp net-next-2.6-7ef73bc/linux/net/netfilter/ipvs/ip_vs_core.c linux/net/netfilter/ipvs/ip_vs_core.c
--- net-next-2.6-7ef73bc/linux/net/netfilter/ipvs/ip_vs_core.c	2011-05-09 07:24:07.000000000 +0300
+++ linux/net/netfilter/ipvs/ip_vs_core.c	2011-05-11 01:07:29.429270382 +0300
@@ -1378,15 +1378,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *
 	ip_vs_in_stats(cp, skb);
 	if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol)
 		offset += 2 * sizeof(__u16);
-	verdict = ip_vs_icmp_xmit(skb, cp, pp, offset);
-	/* LOCALNODE from FORWARD hook is not supported */
-	if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD &&
-	    skb_rtable(skb)->rt_flags & RTCF_LOCAL) {
-		IP_VS_DBG(1, "%s(): "
-			  "local delivery to %pI4 but in FORWARD\n",
-			  __func__, &skb_rtable(skb)->rt_dst);
-		verdict = NF_DROP;
-	}
+	verdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum);
 
   out:
 	__ip_vs_conn_put(cp);
@@ -1408,7 +1400,6 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, in
 	struct ip_vs_protocol *pp;
 	struct ip_vs_proto_data *pd;
 	unsigned int offset, verdict;
-	struct rt6_info *rt;
 
 	*related = 1;
 
@@ -1470,23 +1461,12 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, in
 	if (!cp)
 		return NF_ACCEPT;
 
-	verdict = NF_DROP;
-
 	/* do the statistics and put it back */
 	ip_vs_in_stats(cp, skb);
 	if (IPPROTO_TCP == cih->nexthdr || IPPROTO_UDP == cih->nexthdr ||
 	    IPPROTO_SCTP == cih->nexthdr)
 		offset += 2 * sizeof(__u16);
-	verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset);
-	/* LOCALNODE from FORWARD hook is not supported */
-	if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD &&
-	    (rt = (struct rt6_info *) skb_dst(skb)) &&
-	    rt->rt6i_dev && rt->rt6i_dev->flags & IFF_LOOPBACK) {
-		IP_VS_DBG(1, "%s(): "
-			  "local delivery to %pI6 but in FORWARD\n",
-			  __func__, &rt->rt6i_dst);
-		verdict = NF_DROP;
-	}
+	verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset, hooknum);
 
 	__ip_vs_conn_put(cp);
 
diff -urp net-next-2.6-7ef73bc/linux/net/netfilter/ipvs/ip_vs_xmit.c linux/net/netfilter/ipvs/ip_vs_xmit.c
--- net-next-2.6-7ef73bc/linux/net/netfilter/ipvs/ip_vs_xmit.c	2011-05-10 23:52:06.000000000 +0300
+++ linux/net/netfilter/ipvs/ip_vs_xmit.c	2011-05-11 01:08:21.837272458 +0300
@@ -87,7 +87,7 @@ __ip_vs_dst_check(struct ip_vs_dest *des
 /* Get route to destination or remote server */
 static struct rtable *
 __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
-		   __be32 daddr, u32 rtos, int rt_mode)
+		   __be32 daddr, u32 rtos, int rt_mode, __be32 *ret_saddr)
 {
 	struct net *net = dev_net(skb_dst(skb)->dev);
 	struct rtable *rt;			/* Route to the other host */
@@ -98,7 +98,12 @@ __ip_vs_get_out_rt(struct sk_buff *skb, 
 		spin_lock(&dest->dst_lock);
 		if (!(rt = (struct rtable *)
 		      __ip_vs_dst_check(dest, rtos))) {
-			rt = ip_route_output(net, dest->addr.ip, 0, rtos, 0);
+			struct flowi4 fl4;
+
+			memset(&fl4, 0, sizeof(fl4));
+			fl4.daddr = dest->addr.ip;
+			fl4.flowi4_tos = rtos;
+			rt = ip_route_output_key(net, &fl4);
 			if (IS_ERR(rt)) {
 				spin_unlock(&dest->dst_lock);
 				IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n",
@@ -106,19 +111,30 @@ __ip_vs_get_out_rt(struct sk_buff *skb, 
 				return NULL;
 			}
 			__ip_vs_dst_set(dest, rtos, dst_clone(&rt->dst), 0);
-			IP_VS_DBG(10, "new dst %pI4, refcnt=%d, rtos=%X\n",
-				  &dest->addr.ip,
+			dest->dst_saddr.ip = fl4.saddr;
+			IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d, "
+				  "rtos=%X\n",
+				  &dest->addr.ip, &dest->dst_saddr.ip,
 				  atomic_read(&rt->dst.__refcnt), rtos);
 		}
 		daddr = dest->addr.ip;
+		if (ret_saddr)
+			*ret_saddr = dest->dst_saddr.ip;
 		spin_unlock(&dest->dst_lock);
 	} else {
-		rt = ip_route_output(net, daddr, 0, rtos, 0);
+		struct flowi4 fl4;
+
+		memset(&fl4, 0, sizeof(fl4));
+		fl4.daddr = daddr;
+		fl4.flowi4_tos = rtos;
+		rt = ip_route_output_key(net, &fl4);
 		if (IS_ERR(rt)) {
 			IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n",
 				     &daddr);
 			return NULL;
 		}
+		if (ret_saddr)
+			*ret_saddr = fl4.saddr;
 	}
 
 	local = rt->rt_flags & RTCF_LOCAL;
@@ -249,7 +265,7 @@ __ip_vs_get_out_rt_v6(struct sk_buff *sk
 			u32 cookie;
 
 			dst = __ip_vs_route_output_v6(net, &dest->addr.in6,
-						      &dest->dst_saddr,
+						      &dest->dst_saddr.in6,
 						      do_xfrm);
 			if (!dst) {
 				spin_unlock(&dest->dst_lock);
@@ -259,11 +275,11 @@ __ip_vs_get_out_rt_v6(struct sk_buff *sk
 			cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
 			__ip_vs_dst_set(dest, 0, dst_clone(&rt->dst), cookie);
 			IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n",
-				  &dest->addr.in6, &dest->dst_saddr,
+				  &dest->addr.in6, &dest->dst_saddr.in6,
 				  atomic_read(&rt->dst.__refcnt));
 		}
 		if (ret_saddr)
-			ipv6_addr_copy(ret_saddr, &dest->dst_saddr);
+			ipv6_addr_copy(ret_saddr, &dest->dst_saddr.in6);
 		spin_unlock(&dest->dst_lock);
 	} else {
 		dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm);
@@ -386,7 +402,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, s
 	EnterFunction(10);
 
 	if (!(rt = __ip_vs_get_out_rt(skb, NULL, iph->daddr, RT_TOS(iph->tos),
-				      IP_VS_RT_MODE_NON_LOCAL)))
+				      IP_VS_RT_MODE_NON_LOCAL, NULL)))
 		goto tx_error_icmp;
 
 	/* MTU checking */
@@ -518,7 +534,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, stru
 				      RT_TOS(iph->tos),
 				      IP_VS_RT_MODE_LOCAL |
 					IP_VS_RT_MODE_NON_LOCAL |
-					IP_VS_RT_MODE_RDR)))
+					IP_VS_RT_MODE_RDR, NULL)))
 		goto tx_error_icmp;
 	local = rt->rt_flags & RTCF_LOCAL;
 	/*
@@ -540,7 +556,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, stru
 #endif
 
 	/* From world but DNAT to loopback address? */
-	if (local && ipv4_is_loopback(rt->rt_dst) &&
+	if (local && ipv4_is_loopback(cp->daddr.ip) &&
 	    rt_is_input_route(skb_rtable(skb))) {
 		IP_VS_DBG_RL_PKT(1, AF_INET, pp, skb, 0, "ip_vs_nat_xmit(): "
 				 "stopping DNAT to loopback address");
@@ -751,6 +767,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, s
 		  struct ip_vs_protocol *pp)
 {
 	struct rtable *rt;			/* Route to the other host */
+	__be32 saddr;				/* Source for tunnel */
 	struct net_device *tdev;		/* Device to other host */
 	struct iphdr  *old_iph = ip_hdr(skb);
 	u8     tos = old_iph->tos;
@@ -764,7 +781,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, s
 
 	if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
 				      RT_TOS(tos), IP_VS_RT_MODE_LOCAL |
-						   IP_VS_RT_MODE_NON_LOCAL)))
+						   IP_VS_RT_MODE_NON_LOCAL,
+						   &saddr)))
 		goto tx_error_icmp;
 	if (rt->rt_flags & RTCF_LOCAL) {
 		ip_rt_put(rt);
@@ -832,8 +850,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, s
 	iph->frag_off		=	df;
 	iph->protocol		=	IPPROTO_IPIP;
 	iph->tos		=	tos;
-	iph->daddr		=	rt->rt_dst;
-	iph->saddr		=	rt->rt_src;
+	iph->daddr		=	cp->daddr.ip;
+	iph->saddr		=	saddr;
 	iph->ttl		=	old_iph->ttl;
 	ip_select_ident(iph, &rt->dst, NULL);
 
@@ -996,7 +1014,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struc
 	if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
 				      RT_TOS(iph->tos),
 				      IP_VS_RT_MODE_LOCAL |
-					IP_VS_RT_MODE_NON_LOCAL)))
+					IP_VS_RT_MODE_NON_LOCAL, NULL)))
 		goto tx_error_icmp;
 	if (rt->rt_flags & RTCF_LOCAL) {
 		ip_rt_put(rt);
@@ -1114,12 +1132,13 @@ tx_error:
  */
 int
 ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
-		struct ip_vs_protocol *pp, int offset)
+		struct ip_vs_protocol *pp, int offset, unsigned int hooknum)
 {
 	struct rtable	*rt;	/* Route to the other host */
 	int mtu;
 	int rc;
 	int local;
+	int rt_mode;
 
 	EnterFunction(10);
 
@@ -1140,11 +1159,13 @@ ip_vs_icmp_xmit(struct sk_buff *skb, str
 	 * mangle and send the packet here (only for VS/NAT)
 	 */
 
+	/* LOCALNODE from FORWARD hook is not supported */
+	rt_mode = (hooknum != NF_INET_FORWARD) ?
+		  IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL |
+		  IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL;
 	if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
 				      RT_TOS(ip_hdr(skb)->tos),
-				      IP_VS_RT_MODE_LOCAL |
-					IP_VS_RT_MODE_NON_LOCAL |
-					IP_VS_RT_MODE_RDR)))
+				      rt_mode, NULL)))
 		goto tx_error_icmp;
 	local = rt->rt_flags & RTCF_LOCAL;
 
@@ -1167,7 +1188,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, str
 #endif
 
 	/* From world but DNAT to loopback address? */
-	if (local && ipv4_is_loopback(rt->rt_dst) &&
+	if (local && ipv4_is_loopback(cp->daddr.ip) &&
 	    rt_is_input_route(skb_rtable(skb))) {
 		IP_VS_DBG(1, "%s(): "
 			  "stopping DNAT to loopback %pI4\n",
@@ -1232,12 +1253,13 @@ ip_vs_icmp_xmit(struct sk_buff *skb, str
 #ifdef CONFIG_IP_VS_IPV6
 int
 ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
-		struct ip_vs_protocol *pp, int offset)
+		struct ip_vs_protocol *pp, int offset, unsigned int hooknum)
 {
 	struct rt6_info	*rt;	/* Route to the other host */
 	int mtu;
 	int rc;
 	int local;
+	int rt_mode;
 
 	EnterFunction(10);
 
@@ -1258,10 +1280,12 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, 
 	 * mangle and send the packet here (only for VS/NAT)
 	 */
 
+	/* LOCALNODE from FORWARD hook is not supported */
+	rt_mode = (hooknum != NF_INET_FORWARD) ?
+		  IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL |
+		  IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL;
 	if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL,
-					 0, (IP_VS_RT_MODE_LOCAL |
-					     IP_VS_RT_MODE_NON_LOCAL |
-					     IP_VS_RT_MODE_RDR))))
+					 0, rt_mode)))
 		goto tx_error_icmp;
 
 	local = __ip_vs_is_local_route6(rt);

^ permalink raw reply

* [GIT] Networking
From: David Miller @ 2011-05-10 22:46 UTC (permalink / raw)
  To: torvalds; +Cc: akpm, netdev, linux-kernel


There's several OOPS'ers and reverts in here.

I think we now have all of the worst ones fixed from the regression
list, and I would recommend doing just one more -rc to get this all
sorted out and tested properly.  But of course that is completely up
to you.

1) ipheth regressed because it had a hard dependency upon NET_IP_ALIGN
   being defined always as 2, get rid of that assumption.  From Ben
   Hutchings.

2) IPV6 REJECT module puts random values in TOS field, fix from
   Fernando Luis Vazquez Cao.

3) When an ipv4 fragmentation entry expires via a timer, we have to
   revalidate the route otherwise we can crash.  Fix from Eric
   Dumazet.

4) In usbnet, usbnet_bh can be scheduled too early during resume
   resulting in flood of RX frames but no reclaim, and this leads to
   running out of atomic memory.  Don't allow usbnet_bh to schedule
   until the device is brought completely up.  Fix from Ming Lei.

5) TCP cubic can divide by zero in some extreme cases, fix from
   Stephen Hemminger.

6) SLIP and SLCAN devices return incorrect values from their ldisc
   open method, from Matvejchikov Ilya and Oliver Hartkopp.

7) VLAN GVRP state is undone at the wrong moment, causing crashes during
   batched device delete.  From Eric Dumazet.

8) dev_close() mistakenly had it's IFF_UP check removed, this has to be
   put back otherwise we can crash during batched device teardown, in
   particular with bonding.  Fix from Eric DUmazet.

9) PCH_GBE "checksum correct" logic on RX is reversed (hardware sets
   the status bit on checksum failure, clears it on success), from
   Toshiharu Okada.

10) vmxnet3 does not take ->cmd_lock consistently with interrupts disabled,
    as is warned by lockdep.  Fix from Roland Dreier.

11) DCCP feature options length needs to be validated properly,
    otherwise we can end up working with negative lengths, fix from
    Dan Rosenberg.

13) Fix regressions in ebtables compat support, from Eric Dumazet and
    Florian Westphal.

14) IPVS namespace support can leave objects referenced indefinitely until
    reboot.  Fixes from Hans Schillstrom.

15) DSCP netfilter code forgets to invert mask, from Fernando Luis
    Vazquez Cao.

16) Revert a buggy xt_conntrack change that broke handling of locally
    generated packets.  From Florian Westphal and Jan Engelhardt.

17) Inter-family packet output was busted in IPSEC, we need to split
    the operation into two parts, ->output() and ->output_finish(), to
    make sure we work in the context of the correct protocol (ipv4 vs
    ipv6) at each step.  Fix from Steffen Klassert.

18) We cannot allow ESN handling when anti-reply detection is disabled,
    also from Steffen Klassert.

Please pull, thanks a lot!

The following changes since commit 54b333529df25b21da462c7dcc16c7dc779d9f26:

  Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus (2011-05-10 12:00:53 -0700)

are available in the git repository at:

  master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git master

Ben Hutchings (1):
      ipheth: Properly distinguish length and alignment in URBs and skbs

Dan Rosenberg (1):
      dccp: handle invalid feature options length

Dan Williams (1):
      net/usb: mark LG VL600 LTE modem ethernet interface as WWAN

David S. Miller (1):
      Merge branch 'pablo/nf-2.6-updates' of git://1984.lsi.us.es/net-2.6

Eric Dumazet (4):
      net: ip_expire() must revalidate route
      netfilter: fix ebtables compat support
      vlan: fix GVRP at dismantle time
      net: dev_close() should check IFF_UP

Fernando Luis Vazquez Cao (2):
      netfilter: IPv6: initialize TOS field in REJECT target module
      netfilter: IPv6: fix DSCP mangle code

Florian Westphal (1):
      netfilter: ebtables: only call xt_compat_add_offset once per rule

Hans Schillstrom (2):
      IPVS: Change of socket usage to enable name space exit.
      IPVS: init and cleanup restructuring

Kleber Sacilotto de Souza (1):
      ehea: fix wrongly reported speed and port

Kurt Van Dijck (1):
      can: fix SJA1000 dlc for RTR packets

Matvejchikov Ilya (1):
      NET: slip, fix ldisc->open retval

Ming Lei (1):
      usbnet: runtime pm: fix out of memory

Oliver Hartkopp (1):
      slcan: fix ldisc->open retval

Pablo Neira Ayuso (2):
      netfilter: ctnetlink: fix timestamp support for new conntracks
      netfilter: revert a2361c8735e07322023aedc36e4938b35af31eb0

Roland Dreier (1):
      vmxnet3: Consistently disable irqs when taking adapter->cmd_lock

Somnath Kotur (1):
      be2net: Fixed bugs related to PVID.

Steffen Klassert (2):
      xfrm: Assign the inner mode output function to the dst entry
      xfrm: Don't allow esn with disabled anti replay detection

Tomoya (1):
      pch_gbe: support ML7223 IOH

Toshiharu Okada (2):
      PCH_GbE : Fixed the issue of collision detection
      PCH_GbE : Fixed the issue of checksum judgment

stephen hemminger (1):
      tcp_cubic: limit delayed_ack ratio to prevent divide error

 drivers/net/Kconfig                  |    8 ++-
 drivers/net/benet/be.h               |    2 +-
 drivers/net/benet/be_cmds.c          |    2 +-
 drivers/net/benet/be_main.c          |   18 ++++--
 drivers/net/can/sja1000/sja1000.c    |    2 +-
 drivers/net/can/slcan.c              |    4 +-
 drivers/net/ehea/ehea_ethtool.c      |   21 ++++--
 drivers/net/pch_gbe/pch_gbe_main.c   |   23 +++++--
 drivers/net/slip.c                   |    4 +-
 drivers/net/usb/cdc_ether.c          |    2 +-
 drivers/net/usb/ipheth.c             |   14 +++--
 drivers/net/usb/usbnet.c             |   10 ++-
 drivers/net/vmxnet3/vmxnet3_drv.c    |   10 ++-
 include/net/ip_vs.h                  |   17 +++++
 include/net/xfrm.h                   |    3 +
 net/8021q/vlan.c                     |    3 +
 net/8021q/vlan_dev.c                 |    3 -
 net/bridge/netfilter/ebtables.c      |   64 +++---------------
 net/core/dev.c                       |   10 ++-
 net/dccp/options.c                   |    2 +
 net/ipv4/ip_fragment.c               |   33 +++++-----
 net/ipv4/tcp_cubic.c                 |    9 ++-
 net/ipv4/xfrm4_output.c              |    8 ++-
 net/ipv4/xfrm4_state.c               |    1 +
 net/ipv6/netfilter/ip6t_REJECT.c     |    4 +-
 net/ipv6/xfrm6_output.c              |    6 +-
 net/ipv6/xfrm6_state.c               |    1 +
 net/netfilter/ipvs/ip_vs_app.c       |   15 +----
 net/netfilter/ipvs/ip_vs_conn.c      |   12 +---
 net/netfilter/ipvs/ip_vs_core.c      |  103 ++++++++++++++++++++++++++---
 net/netfilter/ipvs/ip_vs_ctl.c       |  120 ++++++++++++++++++++++++++++-----
 net/netfilter/ipvs/ip_vs_est.c       |   14 +---
 net/netfilter/ipvs/ip_vs_proto.c     |   11 +---
 net/netfilter/ipvs/ip_vs_sync.c      |   65 ++++++++++--------
 net/netfilter/nf_conntrack_netlink.c |    4 +
 net/netfilter/x_tables.c             |    4 +-
 net/netfilter/xt_DSCP.c              |    2 +-
 net/netfilter/xt_conntrack.c         |    5 --
 net/xfrm/xfrm_policy.c               |   14 ++++-
 net/xfrm/xfrm_replay.c               |    3 +
 40 files changed, 423 insertions(+), 233 deletions(-)

^ permalink raw reply

* Re: [PATCH 0/7] Network namespace manipulation with file descriptors
From: Eric W. Biederman @ 2011-05-10 23:02 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, netdev, linux-fsdevel, jamal, Daniel Lezcano,
	Linux Containers, Renato Westphal
In-Reply-To: <m1tyd7p7tq.fsf@fess.ebiederm.org>

ebiederm@xmission.com (Eric W. Biederman) writes:


> These changes are also available at:
> git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/linux-2.6-nsfd.git

I have noted the acknowledgments, fixed the bugs and resolved the syscall
conflicts.

Eric

^ permalink raw reply

* [PATCH] linux-firmware: bnx2: Update firmware and version
From: Michael Chan @ 2011-05-10 22:16 UTC (permalink / raw)
  To: dwmw2; +Cc: netdev

upstream kernel commit dc187cb381f1bceb30498861ece510245c43ed9f

Update 5709 mips firmware to 6.2.1a to fix iSCSI performance
regression.  There was an unnecessary context read in the fast path
affecting performance.

Update bnx2 to 2.1.6.

Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 WHENCE                      |    1 +
 bnx2/bnx2-mips-09-6.2.1a.fw |  Bin 0 -> 103868 bytes
 2 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 bnx2/bnx2-mips-09-6.2.1a.fw

diff --git a/WHENCE b/WHENCE
index d65a04b..a1cd744 100644
--- a/WHENCE
+++ b/WHENCE
@@ -1005,6 +1005,7 @@ File: bnx2/bnx2-mips-09-5.0.0.j3.fw
 File: bnx2/bnx2-mips-09-5.0.0.j9.fw
 File: bnx2/bnx2-mips-09-6.0.17.fw
 File: bnx2/bnx2-mips-09-6.2.1.fw
+File: bnx2/bnx2-mips-09-6.2.1a.fw
 File: bnx2/bnx2-rv2p-06-4.6.16.fw
 File: bnx2/bnx2-rv2p-06-5.0.0.j3.fw
 File: bnx2/bnx2-rv2p-06-6.0.15.fw
diff --git a/bnx2/bnx2-mips-09-6.2.1a.fw b/bnx2/bnx2-mips-09-6.2.1a.fw
new file mode 100644
index 0000000000000000000000000000000000000000..99ac571d1eef7774a0e46f60bf69d3fa2bd3963b
GIT binary patch
literal 103868
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

literal 0
HcmV?d00001

-- 
1.6.4.GIT



^ permalink raw reply related

* Re: [PATCH] linux-firmware: bnx2: Update firmware and version
From: David Woodhouse @ 2011-05-10 23:10 UTC (permalink / raw)
  To: Michael Chan; +Cc: netdev
In-Reply-To: <1305065779-26976-1-git-send-email-mchan@broadcom.com>

On Tue, 2011-05-10 at 15:16 -0700, Michael Chan wrote:
> upstream kernel commit dc187cb381f1bceb30498861ece510245c43ed9f

This stuff should no longer get changed in the upstream kernel; what's
there is *historical* and due for deletion.

> Update 5709 mips firmware to 6.2.1a to fix iSCSI performance
> regression.  There was an unnecessary context read in the fast path
> affecting performance. 

Is this update not ABI compatible? You have changed the soname of the
firmware... was that intentional?

-- 
dwmw2


^ 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