* [net-next-2.6 PATCH 2/4] TCPCT part 1: initial SYN exchange with SYNACK data
From: William Allen Simpson @ 2009-10-15 5:32 UTC (permalink / raw)
To: Linux Kernel Network Developers
In-Reply-To: <4AD6B31B.3060402@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 874 bytes --]
Define sysctl (tcp_cookie_size) to turn on and off the cookie option
default globally, instead of a compiled configuration option.
Define per socket option (TCP_COOKIE_TRANSACTIONS) for setting constant
data values, retrieving variable cookie values, and other facilities.
This is a straightforward re-implementation of an earlier (year-old)
patch that no longer applies cleanly, with permission of the original
author (Adam Langley). The patch was previously reviewed:
http://thread.gmane.org/gmane.linux.network/102586
These functions will also be used in subsequent patches that implement
additional features.
---
include/linux/tcp.h | 31 ++++++++++++++++++++++++++++++-
include/net/tcp.h | 1 +
net/ipv4/sysctl_net_ipv4.c | 8 ++++++++
net/ipv4/tcp_output.c | 8 ++++++++
4 files changed, 47 insertions(+), 1 deletions(-)
[-- Attachment #2: TCPCT+1-2.patch --]
[-- Type: text/plain, Size: 3570 bytes --]
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 61723a7..63ab660 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -96,6 +96,7 @@ enum {
#define TCP_QUICKACK 12 /* Block/reenable quick acks */
#define TCP_CONGESTION 13 /* Congestion control algorithm */
#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */
+#define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */
#define TCPI_OPT_TIMESTAMPS 1
#define TCPI_OPT_SACK 2
@@ -170,6 +171,34 @@ struct tcp_md5sig {
__u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */
};
+/* for TCP_COOKIE_TRANSACTIONS (TCPCT) socket option */
+#define TCP_COOKIE_MAX 16 /* 128-bits */
+#define TCP_COOKIE_MIN 8 /* 64-bits */
+#define TCP_COOKIE_PAIR_SIZE (2*TCP_COOKIE_MAX)
+
+#define TCP_S_DATA_MAX 64U /* after TCP+IP options */
+#define TCP_S_DATA_MSS_DEFAULT 536U /* default MSS (RFC1122) */
+
+/* Flags for both getsockopt and setsockopt */
+#define TCP_COOKIE_IN_ALWAYS (1 << 0) /* Discard SYN without cookie */
+#define TCP_COOKIE_OUT_NEVER (1 << 1) /* Prohibit outgoing cookies,
+ * supercedes everything else. */
+#define TCP_EXTEND_TIMESTAMP (1 << 4) /* Initiate 64-bit timestamps */
+
+/* Flags for getsockopt */
+#define TCP_S_DATA_IN (1 << 2) /* Was data received? */
+#define TCP_S_DATA_OUT (1 << 3) /* Was data sent? */
+
+/* TCP_COOKIE_TRANSACTIONS data */
+struct tcp_cookie_transactions {
+ __u16 tcpct_flags; /* see above */
+ __u8 __tcpct_pad1; /* zero */
+ __u8 tcpct_cookie_desired; /* bytes */
+ __u16 tcpct_s_data_desired; /* bytes of variable data */
+ __u16 tcpct_used; /* bytes in value */
+ __u8 tcpct_value[TCP_S_DATA_MSS_DEFAULT];
+};
+
#ifdef __KERNEL__
#include <linux/skbuff.h>
@@ -431,6 +460,6 @@ static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk)
return (struct tcp_timewait_sock *)sk;
}
-#endif
+#endif /* __KERNEL__ */
#endif /* _LINUX_TCP_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 28bcaf7..63d17fd 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -237,6 +237,7 @@ extern int sysctl_tcp_base_mss;
extern int sysctl_tcp_workaround_signed_windows;
extern int sysctl_tcp_slow_start_after_idle;
extern int sysctl_tcp_max_ssthresh;
+extern int sysctl_tcp_cookie_size;
extern atomic_t tcp_memory_allocated;
extern struct percpu_counter tcp_sockets_allocated;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 2dcf04d..3422c54 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -714,6 +714,14 @@ static struct ctl_table ipv4_table[] = {
},
{
.ctl_name = CTL_UNNUMBERED,
+ .procname = "tcp_cookie_size",
+ .data = &sysctl_tcp_cookie_size,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
.procname = "udp_mem",
.data = &sysctl_udp_mem,
.maxlen = sizeof(sysctl_udp_mem),
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 765d80f..c235196 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -59,6 +59,14 @@ int sysctl_tcp_base_mss __read_mostly = 512;
/* By default, RFC2861 behavior. */
int sysctl_tcp_slow_start_after_idle __read_mostly = 1;
+#ifdef CONFIG_SYSCTL
+/* By default, let the user enable it. */
+int sysctl_tcp_cookie_size __read_mostly = 0;
+#else
+int sysctl_tcp_cookie_size __read_mostly = TCP_COOKIE_MAX;
+#endif
+
+
/* Account for new data that has been sent to the network. */
static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb)
{
--
1.6.0.4
^ permalink raw reply related
* [PATCH] cxgb3: No need to wake queue in xmit handler
From: Krishna Kumar @ 2009-10-15 5:54 UTC (permalink / raw)
To: davem; +Cc: netdev, divy, Krishna Kumar
The xmit handler doesn't need to wake the queue after stopping
it temporarily (some other drivers are doing the same).
Patch on net-next-2.6, multiple netperf sessions tested.
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
drivers/net/cxgb3/sge.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff -ruNp org/drivers/net/cxgb3/sge.c new/drivers/net/cxgb3/sge.c
--- org/drivers/net/cxgb3/sge.c 2009-09-07 10:09:03.000000000 +0530
+++ new/drivers/net/cxgb3/sge.c 2009-09-07 10:11:11.000000000 +0530
@@ -1260,7 +1260,7 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *
if (should_restart_tx(q) &&
test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
q->restarts++;
- netif_tx_wake_queue(txq);
+ netif_tx_start_queue(txq);
}
}
^ permalink raw reply
* [PATCH] genetlink: Optimize genl_register_family()
From: Krishna Kumar @ 2009-10-15 5:54 UTC (permalink / raw)
To: davem; +Cc: netdev, Krishna Kumar
From: Krishna Kumar <krkumar2@in.ibm.com>
genl_register_family() doesn't need to call genl_family_find_byid
when GENL_ID_GENERATE is passed during register.
Patch on net-next-2.6, compile and reboot testing only.
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
diff -ruNp org/net/netlink/genetlink.c new/net/netlink/genetlink.c
--- org/net/netlink/genetlink.c 2009-10-06 08:34:10.000000000 +0530
+++ new/net/netlink/genetlink.c 2009-10-12 13:57:38.000000000 +0530
@@ -374,11 +374,6 @@ int genl_register_family(struct genl_fam
goto errout_locked;
}
- if (genl_family_find_byid(family->id)) {
- err = -EEXIST;
- goto errout_locked;
- }
-
if (family->id == GENL_ID_GENERATE) {
u16 newid = genl_generate_id();
@@ -388,6 +383,9 @@ int genl_register_family(struct genl_fam
}
family->id = newid;
+ } else if (genl_family_find_byid(family->id)) {
+ err = -EEXIST;
+ goto errout_locked;
}
if (family->maxattr) {
^ permalink raw reply
* [PATCH] genetlink: Optimize and one bug fix in genl_generate_id()
From: Krishna Kumar @ 2009-10-15 5:55 UTC (permalink / raw)
To: davem; +Cc: netdev, Krishna Kumar
In-Reply-To: <20091015055453.30128.12160.sendpatchset@localhost.localdomain>
From: Krishna Kumar <krkumar2@in.ibm.com>
1. GENL_MIN_ID is a valid id -> no need to start at
GENL_MIN_ID + 1.
2. Avoid going through the ids two times: If we start at
GENL_MIN_ID+1 (*or bigger*) and all ids are over!, the
code iterates through the list twice (*or lesser*).
3. Simplify code - no need to start at idx=0 which gets
reset to GENL_MIN_ID.
Patch on net-next-2.6. Reboot test shows that first id
passed to genl_register_family was 16, next two were
GENL_ID_GENERATE and genl_generate_id returned 17 & 18
(user level testing of same code shows expected values
across entire range of MIN/MAX).
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
diff -ruNp org/net/netlink/genetlink.c new/net/netlink/genetlink.c
--- org/net/netlink/genetlink.c 2009-10-12 13:57:38.000000000 +0530
+++ new/net/netlink/genetlink.c 2009-10-12 13:57:59.000000000 +0530
@@ -97,25 +97,17 @@ static struct genl_ops *genl_get_cmd(u8
*/
static inline u16 genl_generate_id(void)
{
- static u16 id_gen_idx;
- int overflowed = 0;
+ static u16 id_gen_idx = GENL_MIN_ID;
+ int i;
- do {
- if (id_gen_idx == 0)
+ for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) {
+ if (!genl_family_find_byid(id_gen_idx))
+ return id_gen_idx;
+ if (++id_gen_idx > GENL_MAX_ID)
id_gen_idx = GENL_MIN_ID;
+ }
- if (++id_gen_idx > GENL_MAX_ID) {
- if (!overflowed) {
- overflowed = 1;
- id_gen_idx = 0;
- continue;
- } else
- return 0;
- }
-
- } while (genl_family_find_byid(id_gen_idx));
-
- return id_gen_idx;
+ return 0;
}
static struct genl_multicast_group notify_grp;
^ permalink raw reply
* [RFC] [PATCH 0/5] net: Implement fast TX queue selection
From: Krishna Kumar @ 2009-10-15 5:56 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert, Krishna Kumar, dada1
From: Krishna Kumar <krkumar2@in.ibm.com>
Multiqueue cards on routers/firewalls set skb->queue_mapping on
input which helps in faster xmit. Implement fast queue selection
for locally generated packets also, by saving the txq# for
connected sockets (in dev_pick_tx) and use it in subsequent
iterations. Locally generated packets for a connection will xmit
on the same txq, but routing & firewall loads should not be
affected by this patch. Tests shows the distribution across txq's
for 1-4 netperf sessions is similar to existing code.
Testing & results:
------------------
1. Cycles/Iter (C/I) used by dev_pick_tx:
(B -> Billion, M -> Million)
|--------------|------------------------|------------------------|
| | ORG | NEW |
| Test |--------|---------|-----|--------|---------|-----|
| | Cycles | Iters | C/I | Cycles | Iters | C/I |
|--------------|--------|---------|-----|--------|---------|-----|
| [TCP_STREAM, | 3.98 B | 12.47 M | 320 | 1.95 B | 12.92 M | 152 |
| UDP_STREAM, | | | | | | |
| TCP_RR, | | | | | | |
| UDP_RR] | | | | | | |
|--------------|--------|---------|-----|--------|---------|-----|
| [TCP_STREAM, | 8.92 B | 29.66 M | 300 | 3.82 B | 38.88 M | 98 |
| TCP_RR, | | | | | | |
| UDP_RR] | | | | | | |
|--------------|--------|---------|-----|--------|---------|-----|
2. Stress test (over 48 hours) : 1000 netperfs running combination
of TCP_STREAM/RR, UDP_STREAM/RR (v4/6, NODELAY/~NODELAY for all
tests), with some ssh sessions, reboots, modprobe -r driver, etc.
3. Performance test (10 hours): Single 10 hour netperf run of
TCP_STREAM/RR, TCP_STREAM + NO_DELAY and UDP_RR. Results show an
improvement in both performance and cpu utilization.
Tested on a 4-processor AMD Opteron 2.8 GHz system with 1GB memory,
10G Chelsio card. Each BW number is the sum of 3 iterations of
individual tests using 512, 16K, 64K & 128K I/O sizes, in Mb/s:
------------------------ TCP Tests -----------------------
#procs Org BW New BW (%) Org SD New SD (%)
------------------------------------------------------------
1 77777.7 81011.0 (4.15) 42.3 40.2 (-5.11)
4 91599.2 91878.8 (.30) 955.9 919.3 (-3.83)
6 89533.3 91792.2 (2.52) 2262.0 2143.0 (-5.25)
8 87507.5 89161.9 (1.89) 4363.4 4073.6 (-6.64)
10 85152.4 85607.8 (.53) 6890.4 6851.2 (-.56)
------------------------------------------------------------
------------------------- TCP NO_DELAY Tests ---------------
#procs Org BW New BW (%) Org SD New SD (%)
------------------------------------------------------------
1 57001.9 57888.0 (1.55) 67.7 70.2 (3.75)
4 69555.1 69957.4 (.57) 823.0 834.3 (1.36)
6 71359.3 71918.7 (.78) 1740.8 1724.5 (-.93)
8 72577.6 72496.1 (-.11) 2955.4 2937.7 (-.59)
10 70829.6 71444.2 (.86) 4826.1 4673.4 (-3.16)
------------------------------------------------------------
----------------------- Request Response Tests --------------------
#procs Org TPS New TPS (%) Org SD New SD (%)
(1-10)
-------------------------------------------------------------------
TCP 1019245.9 1042626.4 (2.29) 16352.9 16459.8 (.65)
UDP 934598.64 942956.9 (.89) 11607.3 11593.2 (-.12)
-------------------------------------------------------------------
Thanks,
- KK
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
^ permalink raw reply
* [RFC] [PATCH 1/5] net: Introduce sk_tx_queue_mapping
From: Krishna Kumar @ 2009-10-15 5:56 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert, Krishna Kumar, dada1
In-Reply-To: <20091015055602.30145.65852.sendpatchset@localhost.localdomain>
From: Krishna Kumar <krkumar2@in.ibm.com>
Introduce sk_tx_queue_mapping; and functions that set, test and get
this value. Reset sk_tx_queue_mapping to -1 whenever the dst cache
is set/reset, and in socket alloc & free (free probably doesn't need
it).
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
include/net/sock.h | 21 +++++++++++++++++++++
net/core/sock.c | 7 ++++++-
2 files changed, 27 insertions(+), 1 deletion(-)
diff -ruNp org/include/net/sock.h new/include/net/sock.h
--- org/include/net/sock.h 2009-10-14 10:36:52.000000000 +0530
+++ new/include/net/sock.h 2009-10-14 17:59:44.000000000 +0530
@@ -107,6 +107,7 @@ struct net;
* @skc_node: main hash linkage for various protocol lookup tables
* @skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol
* @skc_refcnt: reference count
+ * @skc_tx_queue_mapping: tx queue number for this connection
* @skc_hash: hash value used with various protocol lookup tables
* @skc_family: network address family
* @skc_state: Connection state
@@ -128,6 +129,7 @@ struct sock_common {
struct hlist_nulls_node skc_nulls_node;
};
atomic_t skc_refcnt;
+ int skc_tx_queue_mapping;
unsigned int skc_hash;
unsigned short skc_family;
@@ -215,6 +217,7 @@ struct sock {
#define sk_node __sk_common.skc_node
#define sk_nulls_node __sk_common.skc_nulls_node
#define sk_refcnt __sk_common.skc_refcnt
+#define sk_tx_queue_mapping __sk_common.skc_tx_queue_mapping
#define sk_copy_start __sk_common.skc_hash
#define sk_hash __sk_common.skc_hash
@@ -1094,8 +1097,24 @@ static inline void sock_put(struct sock
extern int sk_receive_skb(struct sock *sk, struct sk_buff *skb,
const int nested);
+static inline void sk_record_tx_queue(struct sock *sk, int tx_queue)
+{
+ sk->sk_tx_queue_mapping = tx_queue;
+}
+
+static inline int sk_get_tx_queue(const struct sock *sk)
+{
+ return sk->sk_tx_queue_mapping;
+}
+
+static inline bool sk_tx_queue_recorded(const struct sock *sk)
+{
+ return (sk && sk->sk_tx_queue_mapping >= 0);
+}
+
static inline void sk_set_socket(struct sock *sk, struct socket *sock)
{
+ sk_record_tx_queue(sk, -1);
sk->sk_socket = sock;
}
@@ -1152,6 +1171,7 @@ __sk_dst_set(struct sock *sk, struct dst
{
struct dst_entry *old_dst;
+ sk_record_tx_queue(sk, -1);
old_dst = sk->sk_dst_cache;
sk->sk_dst_cache = dst;
dst_release(old_dst);
@@ -1170,6 +1190,7 @@ __sk_dst_reset(struct sock *sk)
{
struct dst_entry *old_dst;
+ sk_record_tx_queue(sk, -1);
old_dst = sk->sk_dst_cache;
sk->sk_dst_cache = NULL;
dst_release(old_dst);
diff -ruNp org/net/core/sock.c new/net/core/sock.c
--- org/net/core/sock.c 2009-10-14 10:36:52.000000000 +0530
+++ new/net/core/sock.c 2009-10-14 17:59:46.000000000 +0530
@@ -358,6 +358,7 @@ struct dst_entry *__sk_dst_check(struct
struct dst_entry *dst = sk->sk_dst_cache;
if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
+ sk_record_tx_queue(sk, -1);
sk->sk_dst_cache = NULL;
dst_release(dst);
return NULL;
@@ -954,7 +955,8 @@ static void sock_copy(struct sock *nsk,
void *sptr = nsk->sk_security;
#endif
BUILD_BUG_ON(offsetof(struct sock, sk_copy_start) !=
- sizeof(osk->sk_node) + sizeof(osk->sk_refcnt));
+ sizeof(osk->sk_node) + sizeof(osk->sk_refcnt) +
+ sizeof(osk->sk_tx_queue_mapping));
memcpy(&nsk->sk_copy_start, &osk->sk_copy_start,
osk->sk_prot->obj_size - offsetof(struct sock, sk_copy_start));
#ifdef CONFIG_SECURITY_NETWORK
@@ -998,6 +1000,7 @@ static struct sock *sk_prot_alloc(struct
if (!try_module_get(prot->owner))
goto out_free_sec;
+ sk_record_tx_queue(sk, -1);
}
return sk;
@@ -1017,6 +1020,8 @@ static void sk_prot_free(struct proto *p
struct kmem_cache *slab;
struct module *owner;
+ sk_record_tx_queue(sk, -1);
+
owner = prot->owner;
slab = prot->slab;
^ permalink raw reply
* [RFC] [PATCH 2/5] net: Use sk_tx_queue_mapping for connected sockets
From: Krishna Kumar @ 2009-10-15 5:57 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert, Krishna Kumar, dada1
In-Reply-To: <20091015055602.30145.65852.sendpatchset@localhost.localdomain>
From: Krishna Kumar <krkumar2@in.ibm.com>
For connected sockets, the first run of dev_pick_tx saves the
calculated txq in sk_tx_queue_mapping. This is not saved if
either skb rx was recorded, or if the device has a queue select
handler. Next iterations of dev_pick_tx uses the cached value of
sk_tx_queue_mapping.
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
net/core/dev.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff -ruNp org/net/core/dev.c new/net/core/dev.c
--- org/net/core/dev.c 2009-10-14 17:59:40.000000000 +0530
+++ new/net/core/dev.c 2009-10-14 18:00:04.000000000 +0530
@@ -1791,13 +1791,25 @@ EXPORT_SYMBOL(skb_tx_hash);
static struct netdev_queue *dev_pick_tx(struct net_device *dev,
struct sk_buff *skb)
{
- const struct net_device_ops *ops = dev->netdev_ops;
- u16 queue_index = 0;
+ u16 queue_index;
+ struct sock *sk = skb->sk;
+
+ if (sk_tx_queue_recorded(sk)) {
+ queue_index = sk_get_tx_queue(sk);
+ } else {
+ const struct net_device_ops *ops = dev->netdev_ops;
- if (ops->ndo_select_queue)
- queue_index = ops->ndo_select_queue(dev, skb);
- else if (dev->real_num_tx_queues > 1)
- queue_index = skb_tx_hash(dev, skb);
+ if (ops->ndo_select_queue) {
+ queue_index = ops->ndo_select_queue(dev, skb);
+ } else {
+ queue_index = 0;
+ if (dev->real_num_tx_queues > 1)
+ queue_index = skb_tx_hash(dev, skb);
+
+ if (sk && sk->sk_dst_cache)
+ sk_record_tx_queue(sk, queue_index);
+ }
+ }
skb_set_queue_mapping(skb, queue_index);
return netdev_get_tx_queue(dev, queue_index);
^ permalink raw reply
* [RFC] [PATCH 3/5] net: IPv6 changes
From: Krishna Kumar @ 2009-10-15 5:57 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert, Krishna Kumar, dada1
In-Reply-To: <20091015055602.30145.65852.sendpatchset@localhost.localdomain>
From: Krishna Kumar <krkumar2@in.ibm.com>
IPv6: Reset sk_tx_queue_mapping when dst_cache is reset.
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
net/ipv6/inet6_connection_sock.c | 1 +
1 file changed, 1 insertion(+)
diff -ruNp org/net/ipv6/inet6_connection_sock.c new/net/ipv6/inet6_connection_sock.c
--- org/net/ipv6/inet6_connection_sock.c 2009-10-14 17:59:58.000000000 +0530
+++ new/net/ipv6/inet6_connection_sock.c 2009-10-14 18:00:11.000000000 +0530
@@ -168,6 +168,7 @@ struct dst_entry *__inet6_csk_dst_check(
if (dst) {
struct rt6_info *rt = (struct rt6_info *)dst;
if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) {
+ sk_record_tx_queue(sk, -1);
sk->sk_dst_cache = NULL;
dst_release(dst);
dst = NULL;
^ permalink raw reply
* [RFC] [PATCH 4/5] net: Fix for dst_negative_advice
From: Krishna Kumar @ 2009-10-15 5:57 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert, Krishna Kumar, dada1
In-Reply-To: <20091015055602.30145.65852.sendpatchset@localhost.localdomain>
From: Krishna Kumar <krkumar2@in.ibm.com>
dst_negative_advice() should check for changed dst and reset
sk_tx_queue_mapping accordingly. Pass sock to the callers of
dst_negative_advice.
(sk_reset_txq is defined just for use by dst_negative_advice. The
only way I could find to get around this is to move dst_negative_()
from dst.h to dst.c, include sock.h in dst.c, etc)
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
include/net/dst.h | 12 ++++++++++--
net/core/sock.c | 6 ++++++
net/dccp/timer.c | 4 ++--
net/decnet/af_decnet.c | 2 +-
net/ipv4/tcp_timer.c | 4 ++--
5 files changed, 21 insertions(+), 7 deletions(-)
diff -ruNp org/include/net/dst.h new/include/net/dst.h
--- org/include/net/dst.h 2009-10-14 18:00:07.000000000 +0530
+++ new/include/net/dst.h 2009-10-14 18:00:22.000000000 +0530
@@ -222,11 +222,19 @@ static inline void dst_confirm(struct ds
neigh_confirm(dst->neighbour);
}
-static inline void dst_negative_advice(struct dst_entry **dst_p)
+static inline void dst_negative_advice(struct dst_entry **dst_p,
+ struct sock *sk)
{
struct dst_entry * dst = *dst_p;
- if (dst && dst->ops->negative_advice)
+ if (dst && dst->ops->negative_advice) {
*dst_p = dst->ops->negative_advice(dst);
+
+ if (dst != *dst_p) {
+ extern void sk_reset_txq(struct sock *sk);
+
+ sk_reset_txq(sk);
+ }
+ }
}
static inline void dst_link_failure(struct sk_buff *skb)
diff -ruNp org/net/core/sock.c new/net/core/sock.c
--- org/net/core/sock.c 2009-10-14 18:00:07.000000000 +0530
+++ new/net/core/sock.c 2009-10-14 18:00:22.000000000 +0530
@@ -353,6 +353,12 @@ discard_and_relse:
}
EXPORT_SYMBOL(sk_receive_skb);
+void sk_reset_txq(struct sock *sk)
+{
+ sk_record_tx_queue(sk, -1);
+}
+EXPORT_SYMBOL(sk_reset_txq);
+
struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
{
struct dst_entry *dst = sk->sk_dst_cache;
diff -ruNp org/net/dccp/timer.c new/net/dccp/timer.c
--- org/net/dccp/timer.c 2009-10-14 18:00:07.000000000 +0530
+++ new/net/dccp/timer.c 2009-10-14 18:00:22.000000000 +0530
@@ -38,7 +38,7 @@ static int dccp_write_timeout(struct soc
if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) {
if (icsk->icsk_retransmits != 0)
- dst_negative_advice(&sk->sk_dst_cache);
+ dst_negative_advice(&sk->sk_dst_cache, sk);
retry_until = icsk->icsk_syn_retries ?
: sysctl_dccp_request_retries;
} else {
@@ -63,7 +63,7 @@ static int dccp_write_timeout(struct soc
Golden words :-).
*/
- dst_negative_advice(&sk->sk_dst_cache);
+ dst_negative_advice(&sk->sk_dst_cache, sk);
}
retry_until = sysctl_dccp_retries2;
diff -ruNp org/net/decnet/af_decnet.c new/net/decnet/af_decnet.c
--- org/net/decnet/af_decnet.c 2009-10-14 18:00:07.000000000 +0530
+++ new/net/decnet/af_decnet.c 2009-10-14 18:00:22.000000000 +0530
@@ -1955,7 +1955,7 @@ static int dn_sendmsg(struct kiocb *iocb
}
if ((flags & MSG_TRYHARD) && sk->sk_dst_cache)
- dst_negative_advice(&sk->sk_dst_cache);
+ dst_negative_advice(&sk->sk_dst_cache, sk);
mss = scp->segsize_rem;
fctype = scp->services_rem & NSP_FC_MASK;
diff -ruNp org/net/ipv4/tcp_timer.c new/net/ipv4/tcp_timer.c
--- org/net/ipv4/tcp_timer.c 2009-10-14 18:00:07.000000000 +0530
+++ new/net/ipv4/tcp_timer.c 2009-10-14 18:00:22.000000000 +0530
@@ -141,14 +141,14 @@ static int tcp_write_timeout(struct sock
if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
if (icsk->icsk_retransmits)
- dst_negative_advice(&sk->sk_dst_cache);
+ dst_negative_advice(&sk->sk_dst_cache, sk);
retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
} else {
if (retransmits_timed_out(sk, sysctl_tcp_retries1)) {
/* Black hole detection */
tcp_mtu_probing(icsk, sk);
- dst_negative_advice(&sk->sk_dst_cache);
+ dst_negative_advice(&sk->sk_dst_cache, sk);
}
retry_until = sysctl_tcp_retries2;
^ permalink raw reply
* [RFC] [PATCH 5/5] net: Encapsulate inner code of __sk_dst_reset
From: Krishna Kumar @ 2009-10-15 5:57 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert, Krishna Kumar, dada1
In-Reply-To: <20091015055602.30145.65852.sendpatchset@localhost.localdomain>
From: Krishna Kumar <krkumar2@in.ibm.com>
Reuse code by adding ___sk_dst_reset() which is called by
__sk_dst_reset() and __sk_dst_check(). This new API is also
called from IPv6 to hide the internals of __sk_dst_reset
and the setting of sk_tx_queue_mapping.
Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
include/net/sock.h | 13 +++++++++----
net/core/sock.c | 4 +---
net/ipv6/inet6_connection_sock.c | 4 +---
3 files changed, 11 insertions(+), 10 deletions(-)
diff -ruNp org/include/net/sock.h new/include/net/sock.h
--- org/include/net/sock.h 2009-10-14 18:00:17.000000000 +0530
+++ new/include/net/sock.h 2009-10-14 18:00:30.000000000 +0530
@@ -1186,17 +1186,22 @@ sk_dst_set(struct sock *sk, struct dst_e
}
static inline void
-__sk_dst_reset(struct sock *sk)
+___sk_dst_reset(struct sock *sk, struct dst_entry *old_dst)
{
- struct dst_entry *old_dst;
-
sk_record_tx_queue(sk, -1);
- old_dst = sk->sk_dst_cache;
sk->sk_dst_cache = NULL;
dst_release(old_dst);
}
static inline void
+__sk_dst_reset(struct sock *sk)
+{
+ struct dst_entry *old_dst = sk->sk_dst_cache;
+
+ ___sk_dst_reset(sk, old_dst);
+}
+
+static inline void
sk_dst_reset(struct sock *sk)
{
write_lock(&sk->sk_dst_lock);
diff -ruNp org/net/core/sock.c new/net/core/sock.c
--- org/net/core/sock.c 2009-10-14 18:00:22.000000000 +0530
+++ new/net/core/sock.c 2009-10-14 18:00:30.000000000 +0530
@@ -364,9 +364,7 @@ struct dst_entry *__sk_dst_check(struct
struct dst_entry *dst = sk->sk_dst_cache;
if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
- sk_record_tx_queue(sk, -1);
- sk->sk_dst_cache = NULL;
- dst_release(dst);
+ ___sk_dst_reset(sk, dst);
return NULL;
}
diff -ruNp org/net/ipv6/inet6_connection_sock.c new/net/ipv6/inet6_connection_sock.c
--- org/net/ipv6/inet6_connection_sock.c 2009-10-14 18:00:17.000000000 +0530
+++ new/net/ipv6/inet6_connection_sock.c 2009-10-14 18:00:30.000000000 +0530
@@ -168,9 +168,7 @@ struct dst_entry *__inet6_csk_dst_check(
if (dst) {
struct rt6_info *rt = (struct rt6_info *)dst;
if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) {
- sk_record_tx_queue(sk, -1);
- sk->sk_dst_cache = NULL;
- dst_release(dst);
+ ___sk_dst_reset(sk, dst);
dst = NULL;
}
}
^ permalink raw reply
* Re: Moving drivers into staging (was Re: [GIT PULL] SCSI fixes for 2.6.32-rc3)
From: Ingo Molnar @ 2009-10-15 6:03 UTC (permalink / raw)
To: Stefan Richter
Cc: Joe Perches, Greg KH, Luis R. Rodriguez, James Bottomley,
Linus Torvalds, Theodore Tso, Andrew Morton, linux-scsi,
linux-kernel, Jing Huang, netdev, linux-wireless
In-Reply-To: <tkrat.88ac5cebebbd9689@s5r6.in-berlin.de>
* Stefan Richter <stefanr@s5r6.in-berlin.de> wrote:
> > Well, the answer is obvious i think. Tell me, at a glance, if you
> > see a patch on lkml, which one is for a staging driver to be
> > obsoleted, and which one is the one going upstream real soon? The
> > patches say:
> >
> > +++ a/drivers/staging/foo/x.c
> >
> > +++ a/drivers/staging/bar/y.c
> >
> > Then tell me the same at a glance if you see patches for:
> >
> > +++ a/drivers/staging/wip/x.c
> >
> > +++ a/drivers/staging/bad/y.c
>
> Does this information matter much?
Yes. You might not appreciate it as you are active in a relatively
narrow field (so all patches in your world have an 'obvious' place) -
but i for example take most of the context of a change from the email
itself and the more self-descriptive it is, the better. I would be more
likely to review work-in-progress patches while not bother about
obsolete drivers on the way out. YMMV.
> What's more interesting is whether development activity will _lead_ to
> a driver being moved from bad or ugly to good.
... a prerequisite of which is for more developers to be accutely aware
of in what state a driver is.
Anyway ... it's all up to Greg and he indicated that he wants the
simplest structure, which is fair enough.
Ingo
^ permalink raw reply
* [PATCH -mmotm -v2] Fix bitmap-introduce-bitmap_set-bitmap_clear-bitmap_find_next_zero_area. patch
From: Akinobu Mita @ 2009-10-15 6:07 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-usb, linux-ia64, linuxppc-dev, Paul Mackerras,
H. Peter Anvin, sparclinux, Lothar Wassmann, x86, linux-altix,
Ingo Molnar, Fenghua Yu, Yevgeny Petrilin, Thomas Gleixner,
Tony Luck, Kyle Hubert, netdev, Greg Kroah-Hartman, linux-kernel,
FUJITA Tomonori, David S. Miller
In-Reply-To: <20091014032258.GA18527@localhost.localdomain>
From: Akinobu Mita <akinobu.mita@gmail.com>
Subject: Fix bitmap-introduce-bitmap_set-bitmap_clear-bitmap_find_next_zero_area.patch
- Rewrite bitmap_set and bitmap_clear
Instead of setting or clearing for each bit.
- Fix off-by-one errors in bitmap_find_next_zero_area
This bug was derived from find_next_zero_area in iommu-helper.
- Add kerneldoc for bitmap_find_next_zero_area
This patch is supposed to be folded into
bitmap-introduce-bitmap_set-bitmap_clear-bitmap_find_next_zero_area.patch
* -v2
- Remove an extra test at the "index" value by find_next_bit
Index was just returned by find_next_zero_bit, so we know it's zero.
Noticed-by: Kyle Hubert <khubert@gmail.com>
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
---
lib/bitmap.c | 62 ++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 48 insertions(+), 14 deletions(-)
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 2415da4..962b863 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -271,28 +271,62 @@ int __bitmap_weight(const unsigned long *bitmap, int bits)
}
EXPORT_SYMBOL(__bitmap_weight);
-void bitmap_set(unsigned long *map, int i, int len)
-{
- int end = i + len;
+#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG))
- while (i < end) {
- __set_bit(i, map);
- i++;
+void bitmap_set(unsigned long *map, int start, int nr)
+{
+ unsigned long *p = map + BIT_WORD(start);
+ const int size = start + nr;
+ int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
+ unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
+
+ while (nr - bits_to_set >= 0) {
+ *p |= mask_to_set;
+ nr -= bits_to_set;
+ bits_to_set = BITS_PER_LONG;
+ mask_to_set = ~0UL;
+ p++;
+ }
+ if (nr) {
+ mask_to_set &= BITMAP_LAST_WORD_MASK(size);
+ *p |= mask_to_set;
}
}
EXPORT_SYMBOL(bitmap_set);
void bitmap_clear(unsigned long *map, int start, int nr)
{
- int end = start + nr;
-
- while (start < end) {
- __clear_bit(start, map);
- start++;
+ unsigned long *p = map + BIT_WORD(start);
+ const int size = start + nr;
+ int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
+ unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
+
+ while (nr - bits_to_clear >= 0) {
+ *p &= ~mask_to_clear;
+ nr -= bits_to_clear;
+ bits_to_clear = BITS_PER_LONG;
+ mask_to_clear = ~0UL;
+ p++;
+ }
+ if (nr) {
+ mask_to_clear &= BITMAP_LAST_WORD_MASK(size);
+ *p &= ~mask_to_clear;
}
}
EXPORT_SYMBOL(bitmap_clear);
+/*
+ * bitmap_find_next_zero_area - find a contiguous aligned zero area
+ * @map: The address to base the search on
+ * @size: The bitmap size in bits
+ * @start: The bitnumber to start searching at
+ * @nr: The number of zeroed bits we're looking for
+ * @align_mask: Alignment mask for zero area
+ *
+ * The @align_mask should be one less than a power of 2; the effect is that
+ * the bit offset of all zero areas this function finds is multiples of that
+ * power of 2. A @align_mask of 0 means no alignment is required.
+ */
unsigned long bitmap_find_next_zero_area(unsigned long *map,
unsigned long size,
unsigned long start,
@@ -304,12 +338,12 @@ again:
index = find_next_zero_bit(map, size, start);
/* Align allocation */
- index = (index + align_mask) & ~align_mask;
+ index = __ALIGN_MASK(index, align_mask);
end = index + nr;
- if (end >= size)
+ if (end > size)
return end;
- i = find_next_bit(map, end, index);
+ i = find_next_bit(map, end, index + 1);
if (i < end) {
start = i + 1;
goto again;
--
1.5.4.3
^ permalink raw reply related
* Re: TCP_DEFER_ACCEPT is missing counter update
From: Willy Tarreau @ 2009-10-15 6:08 UTC (permalink / raw)
To: David Miller; +Cc: ja, netdev, eric.dumazet
In-Reply-To: <20091014.154349.83940908.davem@davemloft.net>
On Wed, Oct 14, 2009 at 03:43:49PM -0700, David Miller wrote:
> For now I'm pushing Willy's change into Linus's tree.
>
> After more discussion we can revert if necessary.
>
> I won't submit this to -stable until the discussion is fully resolved.
Makes sense, thanks David.
BTW, I found a use case I didn't think about where current behaviour
causes trouble :
https://bugs.launchpad.net/ubuntu/+source/apache2/+bug/134274
http://lkml.indiana.edu/hypermail/linux/kernel/0711.0/0461.html
In summary, when front proxies establish pools of connections to
an apache server making use of TCP_DEFER_ACCEPT, the connection
never establishes on the apache server but silently expires in
SYN_RECV state. The front proxy sees lots of SYN/ACKs and sends
many ACKs trying to complete this connection and finally believes
it got it since the server eventually becomes silent. However,
when trying to send data over such a socket, the server immediately
returns an RST.
Such a problem would not happen if we would only drop the first
X packets (X >= 1 is already fine), because the front proxy would
establish the connection, send a second ACK in response to the
second SYN/ACK and the connection would then really be established
and would not have to expire early in SYN_RECV state.
If we really want to behave as it does today, well, let's not fix
it, but obviously, I fail to see what real world use it has, except
causing random and hard to debug issues :-/
Reading the articles below clearly make it think it was designed
to help with HTTP connections by skipping the first expected and
useless ACK packet before waking up the task :
http://httpd.apache.org/docs/1.3/misc/perf-bsd44.html
http://articles.techrepublic.com.com/5100-10878_11-1050771.html
and people still get caught :
http://lkml.indiana.edu/hypermail/linux/kernel/0711.0/0416.html
Maybe it was a bit over-engineered, in the end causing it to fail
to satisfy the primary goal ?
Regards,
Willy
^ permalink raw reply
* Re: [net-next-2.6 PATCH 1/4] TCPCT part 1: initial SYN exchange with SYNACK data
From: David Miller @ 2009-10-15 6:15 UTC (permalink / raw)
To: william.allen.simpson; +Cc: netdev
In-Reply-To: <4AD6B31B.3060402@gmail.com>
From: William Allen Simpson <william.allen.simpson@gmail.com>
Date: Thu, 15 Oct 2009 01:28:59 -0400
> Pass optional function parameters associated with sending SYNACK.
> These parameters are not needed after sending SYNACK, and are not
> used for retransmission. Avoids extending struct tcp_request_sock,
> and avoids allocating kernel memory.
This callback is generic and isn't designed to take opaque
data. All the other arguments to this callback are strongly
typed, and this is on purpose.
You'll need to find another way to implement this.
^ permalink raw reply
* Re: [net-next-2.6 PATCH 4/4] TCPCT part 1: initial SYN exchange with SYNACK data
From: David Miller @ 2009-10-15 6:17 UTC (permalink / raw)
To: william.allen.simpson; +Cc: netdev
In-Reply-To: <4AD6B4F0.8060709@gmail.com>
When posting a patch series like this, use different subject
lines in each patch.
The subject line becomes the commit message header, and if
they are all the same nobody can figure out the general
idea of each part of the patch series when scanning the
commit header lines.
^ permalink raw reply
* [PATCH 1/2] be2net: fix promiscuous and multicast promiscuous modes being enabled always
From: Sathya Perla @ 2009-10-15 6:20 UTC (permalink / raw)
To: netdev
Pls apply to net-2.6 tree.
Signed-off-by: Sathya Perla <sathyap@serverengines.com>
---
drivers/net/benet/be_cmds.c | 8 ++++----
drivers/net/benet/be_cmds.h | 5 +++--
drivers/net/benet/be_main.c | 19 +++++++++++--------
3 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 89876ad..b57abc0 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -729,8 +729,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
/* Create an rx filtering policy configuration on an i/f
* Uses mbox
*/
-int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
- bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
+int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
+ u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_if_create *req;
@@ -746,8 +746,8 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req));
- req->capability_flags = cpu_to_le32(flags);
- req->enable_flags = cpu_to_le32(flags);
+ req->capability_flags = cpu_to_le32(cap_flags);
+ req->enable_flags = cpu_to_le32(en_flags);
req->pmac_invalid = pmac_invalid;
if (!pmac_invalid)
memcpy(req->mac_addr, mac, ETH_ALEN);
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index a86f917..4995378 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -720,8 +720,9 @@ extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
u32 if_id, u32 *pmac_id);
extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id);
-extern int be_cmd_if_create(struct be_adapter *adapter, u32 if_flags, u8 *mac,
- bool pmac_invalid, u32 *if_handle, u32 *pmac_id);
+extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags,
+ u32 en_flags, u8 *mac, bool pmac_invalid,
+ u32 *if_handle, u32 *pmac_id);
extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle);
extern int be_cmd_eq_create(struct be_adapter *adapter,
struct be_queue_info *eq, int eq_delay);
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 6d5e81f..36cb948 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1620,19 +1620,22 @@ static int be_open(struct net_device *netdev)
static int be_setup(struct be_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- u32 if_flags;
+ u32 cap_flags, en_flags;
int status;
- if_flags = BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_PROMISCUOUS |
- BE_IF_FLAGS_MCAST_PROMISCUOUS | BE_IF_FLAGS_UNTAGGED |
- BE_IF_FLAGS_PASS_L3L4_ERRORS;
- status = be_cmd_if_create(adapter, if_flags, netdev->dev_addr,
- false/* pmac_invalid */, &adapter->if_handle,
- &adapter->pmac_id);
+ cap_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+ BE_IF_FLAGS_MCAST_PROMISCUOUS |
+ BE_IF_FLAGS_PROMISCUOUS |
+ BE_IF_FLAGS_PASS_L3L4_ERRORS;
+ en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+ BE_IF_FLAGS_PASS_L3L4_ERRORS;
+
+ status = be_cmd_if_create(adapter, cap_flags, en_flags,
+ netdev->dev_addr, false/* pmac_invalid */,
+ &adapter->if_handle, &adapter->pmac_id);
if (status != 0)
goto do_none;
-
status = be_tx_queues_create(adapter);
if (status != 0)
goto if_destroy;
--
1.6.0.4
^ permalink raw reply related
* [PATCH 2/2] be2net: fix support for PCI hot plug
From: Sathya Perla @ 2009-10-15 6:21 UTC (permalink / raw)
To: netdev
Before issuing any cmds to the FW, the driver must first wait
till the fW becomes ready. This is needed for PCI hot plug when
the driver can be probed while the card fw is being initialized.
Pls apply to net-2.6 tree.
Signed-off-by: Sathya Perla <sathyap@serverengines.com>
---
drivers/net/benet/be_cmds.c | 25 ++++++++++++++++++-------
drivers/net/benet/be_main.c | 8 ++++----
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index b57abc0..28a0eda 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -243,15 +243,26 @@ static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage)
int be_cmd_POST(struct be_adapter *adapter)
{
- u16 stage, error;
+ u16 stage;
+ int status, timeout = 0;
- error = be_POST_stage_get(adapter, &stage);
- if (error || stage != POST_STAGE_ARMFW_RDY) {
- dev_err(&adapter->pdev->dev, "POST failed.\n");
- return -1;
- }
+ do {
+ status = be_POST_stage_get(adapter, &stage);
+ if (status) {
+ dev_err(&adapter->pdev->dev, "POST error; stage=0x%x\n",
+ stage);
+ return -1;
+ } else if (stage != POST_STAGE_ARMFW_RDY) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(2 * HZ);
+ timeout += 2;
+ } else {
+ return 0;
+ }
+ } while (timeout < 20);
- return 0;
+ dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage);
+ return -1;
}
static inline void *embedded_payload(struct be_mcc_wrb *wrb)
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 36cb948..1f941f0 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -2058,6 +2058,10 @@ static int be_hw_up(struct be_adapter *adapter)
if (status)
return status;
+ status = be_cmd_reset_function(adapter);
+ if (status)
+ return status;
+
status = be_cmd_get_fw_ver(adapter, adapter->fw_ver);
if (status)
return status;
@@ -2111,10 +2115,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
if (status)
goto free_netdev;
- status = be_cmd_reset_function(adapter);
- if (status)
- goto ctrl_clean;
-
status = be_stats_init(adapter);
if (status)
goto ctrl_clean;
--
1.6.0.4
^ permalink raw reply related
* Re: [PATCH 1/2] be2net: fix promiscuous and multicast promiscuous modes being enabled always
From: David Miller @ 2009-10-15 6:30 UTC (permalink / raw)
To: sathyap; +Cc: netdev
In-Reply-To: <20091015062042.GA31485@serverengines.com>
From: Sathya Perla <sathyap@serverengines.com>
Date: Thu, 15 Oct 2009 11:50:42 +0530
> Signed-off-by: Sathya Perla <sathyap@serverengines.com>
Applied.
^ permalink raw reply
* Re: [PATCH 2/2] be2net: fix support for PCI hot plug
From: David Miller @ 2009-10-15 6:30 UTC (permalink / raw)
To: sathyap; +Cc: netdev
In-Reply-To: <20091015062117.GA31504@serverengines.com>
From: Sathya Perla <sathyap@serverengines.com>
Date: Thu, 15 Oct 2009 11:51:17 +0530
> Before issuing any cmds to the FW, the driver must first wait
> till the fW becomes ready. This is needed for PCI hot plug when
> the driver can be probed while the card fw is being initialized.
>
> Signed-off-by: Sathya Perla <sathyap@serverengines.com>
Applied.
^ permalink raw reply
* Re: [PATCH] virtio_net: use dev_kfree_skb_any() in free_old_xmit_skbs()
From: David Miller @ 2009-10-15 6:30 UTC (permalink / raw)
To: eric.dumazet; +Cc: mcetra, ctrixk, rjw, linux-kernel, kernel-testers, netdev
In-Reply-To: <4AD66E9B.2020803@gmail.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 15 Oct 2009 02:36:43 +0200
> Massimo Cetra a écrit :
>> Eric,
>> thanks for the patch.
>> The problem didn't arise again and i haven't seen any warning like that
>> on both servers where that problem was happening more frequently.
>>
>> I would say that it's fixed and if it's not, i'll let you know as soon
>> as it happens again.
>>
>
> Thanks Massimo, I think patch is reasonably safe and should be taken as is :
>
>
> [PATCH] virtio_net: use dev_kfree_skb_any() in free_old_xmit_skbs()
Applied, thanks Eric.
^ permalink raw reply
* Re: [net-next 0/8] bnx2x: Device Control Channel bug fixes
From: Eilon Greenstein @ 2009-10-15 6:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <20091014.165704.59488176.davem@davemloft.net>
On Wed, 2009-10-14 at 16:57 -0700, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Wed, 14 Oct 2009 15:09:22 -0700 (PDT)
>
> > Applied to net-next-2.6, which is where this likely belongs.
>
> Eilon I somehow screwed up this patch set, and largely that is
> because the firmware patch was too large for the list and therefore
> it didn't end up in patchwork.
>
> I tried to force in the private copy you sent me into the bundle
> I applied, but I screwed that up somehow.
>
> Could you please privately send me this whole patch set again so I can
> try to apply it properly?
>
> Thanks!
>
Coming right up! Just in case it helps in any way, here is a link to the
patches: http://linux.broadcom.com/eilong/
Thanks,
Eilon
^ permalink raw reply
* [net-next 2/8] bnx2x: Allowing 0 as initial fairness value
From: Eilon Greenstein @ 2009-10-15 6:48 UTC (permalink / raw)
To: David Miller; +Cc: netdev@vger.kernel.org
Value of zero was used to disable the fairness mechanism. Though the code
(driver and FW) allowed changing the value at run time, it did not allow to do
that if the mechanism was disabled to begin with.
Fixed the FW to allow turning on and off the mechanism at run time. Fixed the
code to read the value from the chip at the right sequence.
Without this fix, if the initial value was set to zero, traffic could not run on
the interface.
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x_hsi.h | 4 +-
drivers/net/bnx2x_main.c | 56 +++++++++++++++++++++++-----------------------
firmware/Makefile | 2 +-
firmware/WHENCE | 4 +-
4 files changed, 33 insertions(+), 33 deletions(-)
diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
index 994743d..dc2f8ed 100644
--- a/drivers/net/bnx2x_hsi.h
+++ b/drivers/net/bnx2x_hsi.h
@@ -1259,8 +1259,8 @@ struct host_func_stats {
#define BCM_5710_FW_MAJOR_VERSION 5
-#define BCM_5710_FW_MINOR_VERSION 0
-#define BCM_5710_FW_REVISION_VERSION 21
+#define BCM_5710_FW_MINOR_VERSION 2
+#define BCM_5710_FW_REVISION_VERSION 7
#define BCM_5710_FW_ENGINEERING_VERSION 0
#define BCM_5710_FW_COMPILE_FLAGS 1
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index b4e9c6e..691cf15 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -2333,8 +2333,14 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
}
/* ... only if all min rates are zeros - disable fairness */
- if (all_zero)
- bp->vn_weight_sum = 0;
+ if (all_zero) {
+ bp->cmng.flags.cmng_enables &=
+ ~CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
+ DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
+ " fairness will be disabled\n");
+ } else
+ bp->cmng.flags.cmng_enables |=
+ CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
}
static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
@@ -2353,17 +2359,14 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
} else {
vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
- /* If fairness is enabled (not all min rates are zeroes) and
- if current min rate is zero - set it to 1.
- This is a requirement of the algorithm. */
- if (bp->vn_weight_sum && (vn_min_rate == 0))
+ /* If min rate is zero - set it to 1 */
+ if (!vn_min_rate)
vn_min_rate = DEF_MIN_RATE;
vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
}
-
DP(NETIF_MSG_IFUP,
- "func %d: vn_min_rate=%d vn_max_rate=%d vn_weight_sum=%d\n",
+ "func %d: vn_min_rate %d vn_max_rate %d vn_weight_sum %d\n",
func, vn_min_rate, vn_max_rate, bp->vn_weight_sum);
memset(&m_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn));
@@ -2490,7 +2493,6 @@ static void bnx2x__link_status_update(struct bnx2x *bp)
else
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
- bp->mf_config = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
bnx2x_calc_vn_weight_sum(bp);
/* indicate link status */
@@ -2634,10 +2636,7 @@ static void bnx2x_update_min_max(struct bnx2x *bp)
static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
{
- int func = BP_FUNC(bp);
-
DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event);
- bp->mf_config = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) {
@@ -3067,6 +3066,8 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
int func = BP_FUNC(bp);
REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0);
+ bp->mf_config = SHMEM_RD(bp,
+ mf_cfg.func_mf_config[func].config);
val = SHMEM_RD(bp, func_mb[func].drv_status);
if (val & DRV_STATUS_DCC_EVENT_MASK)
bnx2x_dcc_event(bp,
@@ -5559,20 +5560,18 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
bp->link_vars.line_speed = SPEED_10000;
bnx2x_init_port_minmax(bp);
+ if (!BP_NOMCP(bp))
+ bp->mf_config =
+ SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
bnx2x_calc_vn_weight_sum(bp);
for (vn = VN_0; vn < E1HVN_MAX; vn++)
bnx2x_init_vn_minmax(bp, 2*vn + port);
/* Enable rate shaping and fairness */
- bp->cmng.flags.cmng_enables =
+ bp->cmng.flags.cmng_enables |=
CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN;
- if (bp->vn_weight_sum)
- bp->cmng.flags.cmng_enables |=
- CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
- else
- DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
- " fairness will be disabled\n");
+
} else {
/* rate shaping and fairness are disabled */
DP(NETIF_MSG_IFUP,
@@ -9038,17 +9037,18 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (netif_carrier_ok(dev)) {
cmd->speed = bp->link_vars.line_speed;
cmd->duplex = bp->link_vars.duplex;
- } else {
- cmd->speed = bp->link_params.req_line_speed;
- cmd->duplex = bp->link_params.req_duplex;
- }
- if (IS_E1HMF(bp)) {
- u16 vn_max_rate;
+ if (IS_E1HMF(bp)) {
+ u16 vn_max_rate;
- vn_max_rate = ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
+ vn_max_rate =
+ ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
- if (vn_max_rate < cmd->speed)
- cmd->speed = vn_max_rate;
+ if (vn_max_rate < cmd->speed)
+ cmd->speed = vn_max_rate;
+ }
+ } else {
+ cmd->speed = -1;
+ cmd->duplex = -1;
}
if (bp->link_params.switch_cfg == SWITCH_CFG_10G) {
diff --git a/firmware/Makefile b/firmware/Makefile
index a6c7c3e..45c0466 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -32,7 +32,7 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
adaptec/starfire_tx.bin
fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
-fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-5.0.21.0.fw bnx2x-e1h-5.0.21.0.fw
+fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-5.2.7.0.fw bnx2x-e1h-5.2.7.0.fw
fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-5.0.0.j3.fw \
bnx2/bnx2-rv2p-09-5.0.0.j3.fw \
bnx2/bnx2-rv2p-09ax-5.0.0.j3.fw \
diff --git a/firmware/WHENCE b/firmware/WHENCE
index c437e14..a07aede 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -674,8 +674,8 @@ Found in hex form in kernel source.
Driver: bnx2x: Broadcom Everest
-File: bnx2x-e1-4.8.53.0.fw.ihex
-File: bnx2x-e1h-4.8.53.0.fw.ihex
+File: bnx2x-e1-5.2.7.0.fw.ihex
+File: bnx2x-e1h-5.2.7.0.fw.ihex
License:
Copyright (c) 2007-2009 Broadcom Corporation
--
1.5.4.3
^ permalink raw reply related
* [net-next 8/8] bnx2x: Update to version 1.52.1-1
From: Eilon Greenstein @ 2009-10-15 6:48 UTC (permalink / raw)
To: David Miller; +Cc: netdev@vger.kernel.org
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x_main.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index ba131f4..59b58d8 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -56,8 +56,8 @@
#include "bnx2x_init_ops.h"
#include "bnx2x_dump.h"
-#define DRV_MODULE_VERSION "1.52.1"
-#define DRV_MODULE_RELDATE "2009/08/12"
+#define DRV_MODULE_VERSION "1.52.1-1"
+#define DRV_MODULE_RELDATE "2009/10/13"
#define BNX2X_BC_VER 0x040200
#include <linux/firmware.h>
--
1.5.4.3
^ permalink raw reply related
* [net-next 4/8] bnx2x: Changing the Disabled state to a flag
From: Eilon Greenstein @ 2009-10-15 6:48 UTC (permalink / raw)
To: David Miller; +Cc: netdev@vger.kernel.org
When working with DCC, a function can be disabled or enabled (virtual link down
or up). Using the function state introduced some race conditions with the
load/unload flow.
Using a separate flag to indicate that the function is disabled.
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x.h | 2 +-
drivers/net/bnx2x_main.c | 34 +++++++++++++++++++---------------
2 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 60fa14f..185a6ba 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -900,6 +900,7 @@ struct bnx2x {
#define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
#define HW_VLAN_TX_FLAG 0x400
#define HW_VLAN_RX_FLAG 0x800
+#define MF_FUNC_DIS 0x1000
int func;
#define BP_PORT(bp) (bp->func % PORT_MAX)
@@ -965,7 +966,6 @@ struct bnx2x {
#define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000
#define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000
#define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000
-#define BNX2X_STATE_DISABLED 0xd000
#define BNX2X_STATE_DIAG 0xe000
#define BNX2X_STATE_ERROR 0xf000
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 691cf15..e7b3b27 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -1043,7 +1043,6 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
break;
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
- case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DISABLED):
DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
bp->set_mac_pending--;
smp_wmb();
@@ -2157,7 +2156,7 @@ static void bnx2x_calc_fc_adv(struct bnx2x *bp)
static void bnx2x_link_report(struct bnx2x *bp)
{
- if (bp->state == BNX2X_STATE_DISABLED) {
+ if (bp->flags & MF_FUNC_DIS) {
netif_carrier_off(bp->dev);
printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
return;
@@ -2437,8 +2436,7 @@ static void bnx2x_link_attn(struct bnx2x *bp)
memset(&(pstats->mac_stx[0]), 0,
sizeof(struct mac_stx));
}
- if ((bp->state == BNX2X_STATE_OPEN) ||
- (bp->state == BNX2X_STATE_DISABLED))
+ if (bp->state == BNX2X_STATE_OPEN)
bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
}
@@ -2481,9 +2479,7 @@ static void bnx2x_link_attn(struct bnx2x *bp)
static void bnx2x__link_status_update(struct bnx2x *bp)
{
- int func = BP_FUNC(bp);
-
- if (bp->state != BNX2X_STATE_OPEN)
+ if ((bp->state != BNX2X_STATE_OPEN) || (bp->flags & MF_FUNC_DIS))
return;
bnx2x_link_status_update(&bp->link_params, &bp->link_vars);
@@ -2640,14 +2636,19 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) {
+ /*
+ * This is the only place besides the function initialization
+ * where the bp->flags can change so it is done without any
+ * locks
+ */
if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n");
- bp->state = BNX2X_STATE_DISABLED;
+ bp->flags |= MF_FUNC_DIS;
bnx2x_e1h_disable(bp);
} else {
DP(NETIF_MSG_IFUP, "mf_cfg function enabled\n");
- bp->state = BNX2X_STATE_OPEN;
+ bp->flags &= ~MF_FUNC_DIS;
bnx2x_e1h_enable(bp);
}
@@ -4695,8 +4696,7 @@ static void bnx2x_timer(unsigned long data)
}
}
- if ((bp->state == BNX2X_STATE_OPEN) ||
- (bp->state == BNX2X_STATE_DISABLED))
+ if (bp->state == BNX2X_STATE_OPEN)
bnx2x_stats_handle(bp, STATS_EVENT_UPDATE);
timer_restart:
@@ -7629,7 +7629,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
if (CHIP_IS_E1H(bp))
if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n");
- bp->state = BNX2X_STATE_DISABLED;
+ bp->flags |= MF_FUNC_DIS;
}
if (bp->state == BNX2X_STATE_OPEN) {
@@ -9034,7 +9034,9 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->supported = bp->port.supported;
cmd->advertising = bp->port.advertising;
- if (netif_carrier_ok(dev)) {
+ if ((bp->state == BNX2X_STATE_OPEN) &&
+ !(bp->flags & MF_FUNC_DIS) &&
+ (bp->link_vars.link_up)) {
cmd->speed = bp->link_vars.line_speed;
cmd->duplex = bp->link_vars.duplex;
if (IS_E1HMF(bp)) {
@@ -9433,6 +9435,9 @@ static u32 bnx2x_get_link(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
+ if (bp->flags & MF_FUNC_DIS)
+ return 0;
+
return bp->link_vars.link_up;
}
@@ -9837,8 +9842,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
} else if (eeprom->magic == 0x50485952) {
/* 'PHYR' (0x50485952): re-init link after FW upgrade */
- if ((bp->state == BNX2X_STATE_OPEN) ||
- (bp->state == BNX2X_STATE_DISABLED)) {
+ if (bp->state == BNX2X_STATE_OPEN) {
bnx2x_acquire_phy_lock(bp);
rc |= bnx2x_link_reset(&bp->link_params,
&bp->link_vars, 1);
--
1.5.4.3
^ permalink raw reply related
* [net-next 5/8] bnx2x: Adding FW mailbox mutex
From: Eilon Greenstein @ 2009-10-15 6:48 UTC (permalink / raw)
To: David Miller; +Cc: netdev@vger.kernel.org
DCC commands are not protected with the RTNL lock, so a mutex should be added
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x.h | 3 +++
drivers/net/bnx2x_main.c | 7 +++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 185a6ba..c3b32f7 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -1023,6 +1023,9 @@ struct bnx2x {
/* used to synchronize dmae accesses */
struct mutex dmae_mutex;
+ /* used to protect the FW mail box */
+ struct mutex fw_mb_mutex;
+
/* used to synchronize stats collecting */
int stats_state;
/* used by dmae command loader */
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index e7b3b27..7c5c300 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -2528,6 +2528,7 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
u32 cnt = 1;
u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10;
+ mutex_lock(&bp->fw_mb_mutex);
SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq));
DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
@@ -2537,8 +2538,8 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
rc = SHMEM_RD(bp, func_mb[func].fw_mb_header);
- /* Give the FW up to 2 second (200*10ms) */
- } while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 200));
+ /* Give the FW up to 5 second (500*10ms) */
+ } while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 500));
DP(BNX2X_MSG_MCP, "[after %d ms] read (%x) seq is (%x) from FW MB\n",
cnt*delay, rc, seq);
@@ -2552,6 +2553,7 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
bnx2x_fw_dump(bp);
rc = 0;
}
+ mutex_unlock(&bp->fw_mb_mutex);
return rc;
}
@@ -8956,6 +8958,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */
mutex_init(&bp->port.phy_mutex);
+ mutex_init(&bp->fw_mb_mutex);
#ifdef BCM_CNIC
mutex_init(&bp->cnic_mutex);
#endif
--
1.5.4.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox