* [RFC PATCH 3/5] net: Add & modify tracepoints to skb FCLONE_SCRATCH paths
From: Neil Horman @ 2011-10-27 19:53 UTC (permalink / raw)
To: netdev; +Cc: Neil Horman, Neil Horman, David S. Miller
In-Reply-To: <1319745221-30880-1-git-send-email-nhorman@tuxdriver.com>
From: Neil Horman <nhorman@updev.think-freely.org>
Since skbs that are fcloned via the FCLONE_SCRATCH method are opportunistic, it
would be nice to have some feedback on how efficiently the path is acting.
These tracepoints provide the infrastructure needed to create perf scripts that
let us measure things like the number of skbs that are converted for
FCLONE_SCRATCH use, the number of scratch skbs that actually get
allocated, and the average per-packet time spent in the napi softirq context.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: "David S. Miller" <davem@davemloft.net>
---
include/linux/skbuff.h | 21 +--------------------
include/trace/events/napi.h | 41 +++++++++++++++++++++++++++++++++++++++++
include/trace/events/skb.h | 41 +++++++++++++++++++++++++++++++++++++++++
net/core/dev.c | 2 ++
net/core/skbuff.c | 37 +++++++++++++++++++++++++++++++++----
5 files changed, 118 insertions(+), 24 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index e04fa48..77e3605 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2540,26 +2540,7 @@ extern unsigned int skb_make_fclone_scratch(struct sk_buff *skb);
/*
* Allocates an skb out of our scratch space
*/
-static inline struct sk_buff *alloc_fscratch_skb(struct sk_buff *skb)
-{
- struct skb_scr_control *sctl = skb_get_scratch_control(skb);
- struct sk_buff *sskb;
-
- BUG_ON(skb->fclone != SKB_FCLONE_SCRATCH);
- BUG_ON(!sctl);
- BUG_ON(sctl->owner != skb);
- if (skb_queue_empty(&sctl->scr_skbs))
- return NULL;
-
- sskb = __skb_dequeue(&sctl->scr_skbs);
-
- /*
- * Mark us as a scratch skb, so we get properly kfree-ed
- */
- sskb->fclone = SKB_FCLONE_SCRATCH;
-
- return sskb;
-}
+extern struct sk_buff *alloc_fscratch_skb(struct sk_buff *skb);
#endif /* __KERNEL__ */
#endif /* _LINUX_SKBUFF_H */
diff --git a/include/trace/events/napi.h b/include/trace/events/napi.h
index 8fe1e93..5af5675 100644
--- a/include/trace/events/napi.h
+++ b/include/trace/events/napi.h
@@ -7,6 +7,7 @@
#include <linux/netdevice.h>
#include <linux/tracepoint.h>
#include <linux/ftrace.h>
+#include <linux/kernel_stat.h>
#define NO_DEV "(no_device)"
@@ -30,6 +31,46 @@ TRACE_EVENT(napi_poll,
__entry->napi, __get_str(dev_name))
);
+TRACE_EVENT(napi_schedule,
+
+ TP_PROTO(struct napi_struct *napi),
+
+ TP_ARGS(napi),
+
+ TP_STRUCT__entry(
+ __field( struct napi_struct *, napi)
+ __string( dev_name, napi->dev ? napi->dev->name : NO_DEV)
+ ),
+
+ TP_fast_assign(
+ __entry->napi = napi;
+ __assign_str(dev_name, napi->dev ? napi->dev->name : NO_DEV);
+ ),
+
+ TP_printk("napi schedule on napi struct %p for device %s",
+ __entry->napi, __get_str(dev_name))
+);
+
+TRACE_EVENT(napi_complete,
+
+ TP_PROTO(struct napi_struct *napi),
+
+ TP_ARGS(napi),
+
+ TP_STRUCT__entry(
+ __field( struct napi_struct *, napi)
+ __string( dev_name, napi->dev ? napi->dev->name : NO_DEV)
+ ),
+
+ TP_fast_assign(
+ __entry->napi = napi;
+ __assign_str(dev_name, napi->dev ? napi->dev->name : NO_DEV);
+ ),
+
+ TP_printk("napi complete on napi struct %p for device %s",
+ __entry->napi, __get_str(dev_name))
+);
+
#undef NO_DEV
#endif /* _TRACE_NAPI_H_ */
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index 0c68ae22..3b83438 100644
--- a/include/trace/events/skb.h
+++ b/include/trace/events/skb.h
@@ -69,6 +69,47 @@ TRACE_EVENT(skb_copy_datagram_iovec,
TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len)
);
+TRACE_EVENT(skb_make_fclone_scratch,
+
+ TP_PROTO(struct sk_buff *skb, int count),
+
+ TP_ARGS(skb, count),
+
+ TP_STRUCT__entry(
+ __field( const struct sk_buff *, skb)
+ __string( name, skb->dev ? skb->dev->name : "unknown")
+ __field( int, fccount)
+ ),
+
+ TP_fast_assign(
+ __entry->skb = skb;
+ __assign_str(name, skb->dev ? skb->dev->name : "unknown");
+ __entry->fccount = count;
+ ),
+
+ TP_printk("skb= %p, dev=%s, count=%d", __entry->skb,
+ __get_str(name), __entry->fccount)
+);
+
+TRACE_EVENT(alloc_fscratch_skb,
+
+ TP_PROTO(const struct sk_buff *parent, const struct sk_buff *child),
+
+ TP_ARGS(parent, child),
+
+ TP_STRUCT__entry(
+ __field( const struct sk_buff *, parent)
+ __field( const struct sk_buff *, child)
+ ),
+
+ TP_fast_assign(
+ __entry->parent = parent;
+ __entry->child = child;
+ ),
+
+ TP_printk("parent=%p, child=%p", __entry->parent, __entry->child)
+);
+
#endif /* _TRACE_SKB_H */
/* This part must be outside protection */
diff --git a/net/core/dev.c b/net/core/dev.c
index b7ba81a..1af4c02 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2579,6 +2579,7 @@ int weight_p __read_mostly = 64; /* old backlog weight */
static inline void ____napi_schedule(struct softnet_data *sd,
struct napi_struct *napi)
{
+ trace_napi_schedule(napi);
list_add_tail(&napi->poll_list, &sd->poll_list);
__raise_softirq_irqoff(NET_RX_SOFTIRQ);
}
@@ -3829,6 +3830,7 @@ void __napi_complete(struct napi_struct *n)
BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
BUG_ON(n->gro_list);
+ trace_napi_complete(n);
list_del(&n->poll_list);
smp_mb__before_clear_bit();
clear_bit(NAPI_STATE_SCHED, &n->state);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 6fdf1a7..0347446 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3221,6 +3221,30 @@ void __skb_warn_lro_forwarding(const struct sk_buff *skb)
}
EXPORT_SYMBOL(__skb_warn_lro_forwarding);
+/*
+ * Allocates an skb out of our scratch space
+ */
+struct sk_buff *alloc_fscratch_skb(struct sk_buff *skb)
+{
+ struct skb_scr_control *sctl = skb_get_scratch_control(skb);
+ struct sk_buff *sskb = NULL;
+
+ BUG_ON(skb->fclone != SKB_FCLONE_SCRATCH);
+ BUG_ON(!sctl);
+ BUG_ON(sctl->owner != skb);
+
+ sskb = __skb_dequeue(&sctl->scr_skbs);
+
+ /*
+ * Mark us as a scratch skb, so we get properly kfree-ed
+ */
+ sskb->fclone = SKB_FCLONE_SCRATCH;
+
+ trace_alloc_fscratch_skb(skb, sskb);
+ return sskb;
+}
+EXPORT_SYMBOL(alloc_fscratch_skb);
+
unsigned int skb_make_fclone_scratch(struct sk_buff *skb)
{
size_t bufsz, totsz, scrsz, tmpsz;
@@ -3228,15 +3252,16 @@ unsigned int skb_make_fclone_scratch(struct sk_buff *skb)
struct sk_buff *scr_skb;
struct skb_shared_info *old_info;
bool format_tail = false;
+ int fclone_count = 0;
if (skb_shared(skb))
- return 0;
+ goto out;
/*
* Cant do scratch space on fcloned skbs
*/
if (skb->fclone)
- return 0;
+ goto out;
if ((skb->end - skb->tail) > sizeof(struct skb_shared_info)) {
old_info = skb_shinfo(skb);
@@ -3257,7 +3282,7 @@ unsigned int skb_make_fclone_scratch(struct sk_buff *skb)
sizeof(struct skb_shared_info);
if ((bufsz + sizeof(struct skb_scr_control)) >= totsz)
- return 0;
+ goto out;
/*
* And this is the leftover area, minus sizeof(int) to store the number
@@ -3278,6 +3303,10 @@ unsigned int skb_make_fclone_scratch(struct sk_buff *skb)
skb->fclone = SKB_FCLONE_SCRATCH;
- return skb_queue_len(&sctl->scr_skbs);
+ fclone_count = skb_queue_len(&sctl->scr_skbs);
+out:
+ trace_skb_make_fclone_scratch(skb, fclone_count);
+ return fclone_count;
}
+EXPORT_SYMBOL(skb_make_fclone_scratch);
--
1.7.6.4
^ permalink raw reply related
* [RFC PATCH 2/5] net: add FCLONE_SCRATCH use to ipv4 udp path
From: Neil Horman @ 2011-10-27 19:53 UTC (permalink / raw)
To: netdev; +Cc: Neil Horman, Neil Horman, David S. Miller
In-Reply-To: <1319745221-30880-1-git-send-email-nhorman@tuxdriver.com>
From: Neil Horman <nhorman@updev.think-freely.org>
UDP v4 multicast in a multiple group listener workload is a heavy user of
skb_clone, which can lead to performance problems if memory is constrained and
frame reception rates are high. Once in the udp path however, we can reserve
the unused storage of the udp datagram and allocate skbs from it quickly.
Modify the udp multicast receive path to reserve storage using the
FCLONE_SCRATCH api to make opportunistic use of this space.
Tested successfully by myself
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: "David S. Miller" <davem@davemloft.net>
---
net/ipv4/udp.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ebaa96b..e1c0b1e 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1489,7 +1489,6 @@ drop:
return -1;
}
-
static void flush_stack(struct sock **stack, unsigned int count,
struct sk_buff *skb, unsigned int final)
{
@@ -1532,6 +1531,8 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
int dif;
unsigned int i, count = 0;
+ skb_make_fclone_scratch(skb);
+
spin_lock(&hslot->lock);
sk = sk_nulls_head(&hslot->head);
dif = skb->dev->ifindex;
--
1.7.6.4
^ permalink raw reply related
* [RFC PATCH 1/5] net: add SKB_FCLONE_SCRATCH API
From: Neil Horman @ 2011-10-27 19:53 UTC (permalink / raw)
To: netdev; +Cc: Neil Horman, Neil Horman
In-Reply-To: <1319745221-30880-1-git-send-email-nhorman@tuxdriver.com>
From: Neil Horman <nhorman@updev.think-freely.org>
The FCLONE api for skb allocation is nice in that it allows for the
pre-allocation of skbs when you know you will need additional clones. A nice
addition to this api would be the ability to quickly allocate extra skbs when
needed without having to call into the slab allocator. This API provides that
ability. By using the internally fragmented space between the tail and end
pointer, and after the skb_shinfo space, we can opportunistically format this
space for use as extra sk_buff structures. This allows for both fast
allocations in cases where skbs need to be cloned quickly (like in a multiple
multicast listener workload), and it does so without needing to allocate further
memory from the system, reducing overall memory demand.
There are rules when using this api however:
1) skbs that have their data reserved via this api become fixed, i.e. they can
no longer call skb_pull, or pskb_expand_tail
2) only a single skb can reserve the space. The api assumes that the skb that
reserves the space is the owner, and only that skbs owning context will allocate
out of the shared area
Tested successfully by myself
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
include/linux/skbuff.h | 51 +++++++++++++++++++++++++++++-
net/core/skbuff.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 129 insertions(+), 4 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 6a6b352..e04fa48 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -258,7 +258,7 @@ struct skb_shared_info {
skb_frag_t frags[MAX_SKB_FRAGS];
};
-/* We divide dataref into two halves. The higher 16 bits hold references
+/* We divide dataref two halves. The higher 15 bits hold references
* to the payload part of skb->data. The lower 16 bits hold references to
* the entire skb->data. A clone of a headerless skb holds the length of
* the header in skb->hdr_len.
@@ -277,6 +277,7 @@ enum {
SKB_FCLONE_UNAVAILABLE,
SKB_FCLONE_ORIG,
SKB_FCLONE_CLONE,
+ SKB_FCLONE_SCRATCH,
};
enum {
@@ -2512,5 +2513,53 @@ static inline bool skb_is_recycleable(const struct sk_buff *skb, int skb_size)
return true;
}
+
+struct skb_scr_control {
+ struct sk_buff_head scr_skbs;
+ struct sk_buff *owner;
+};
+
+/*
+ * gets our control data for the scratch area
+ */
+static inline struct skb_scr_control*
+ skb_get_scratch_control(struct sk_buff *skb)
+{
+ struct skb_scr_control *sctl;
+ sctl = (struct skb_scr_control *)((void *)skb_shinfo(skb) +
+ sizeof(struct skb_shared_info));
+ return sctl;
+}
+
+/*
+ * Converts the scratch space of an skbs data area to a list of
+ * skbuffs. Returns the number of additional skbs allocated
+ */
+extern unsigned int skb_make_fclone_scratch(struct sk_buff *skb);
+
+/*
+ * Allocates an skb out of our scratch space
+ */
+static inline struct sk_buff *alloc_fscratch_skb(struct sk_buff *skb)
+{
+ struct skb_scr_control *sctl = skb_get_scratch_control(skb);
+ struct sk_buff *sskb;
+
+ BUG_ON(skb->fclone != SKB_FCLONE_SCRATCH);
+ BUG_ON(!sctl);
+ BUG_ON(sctl->owner != skb);
+ if (skb_queue_empty(&sctl->scr_skbs))
+ return NULL;
+
+ sskb = __skb_dequeue(&sctl->scr_skbs);
+
+ /*
+ * Mark us as a scratch skb, so we get properly kfree-ed
+ */
+ sskb->fclone = SKB_FCLONE_SCRATCH;
+
+ return sskb;
+}
+
#endif /* __KERNEL__ */
#endif /* _LINUX_SKBUFF_H */
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index ca4db40..6fdf1a7 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -367,6 +367,7 @@ static void kfree_skbmem(struct sk_buff *skb)
atomic_t *fclone_ref;
switch (skb->fclone) {
+ case SKB_FCLONE_SCRATCH:
case SKB_FCLONE_UNAVAILABLE:
kmem_cache_free(skbuff_head_cache, skb);
break;
@@ -438,8 +439,16 @@ static void skb_release_all(struct sk_buff *skb)
void __kfree_skb(struct sk_buff *skb)
{
+ struct skb_scr_control *sctl;
+ bool need_free = (skb->fclone == SKB_FCLONE_SCRATCH);
+ if (need_free) {
+ sctl = skb_get_scratch_control(skb);
+ need_free = (sctl->owner == skb);
+ }
+
skb_release_all(skb);
- kfree_skbmem(skb);
+ if (need_free)
+ kfree_skbmem(skb);
}
EXPORT_SYMBOL(__kfree_skb);
@@ -701,6 +710,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask)
struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
{
struct sk_buff *n;
+ atomic_t *fclone_ref;
if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) {
if (skb_copy_ubufs(skb, gfp_mask))
@@ -710,10 +720,15 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
n = skb + 1;
if (skb->fclone == SKB_FCLONE_ORIG &&
n->fclone == SKB_FCLONE_UNAVAILABLE) {
- atomic_t *fclone_ref = (atomic_t *) (n + 1);
+ fclone_ref = (atomic_t *) (n + 1);
n->fclone = SKB_FCLONE_CLONE;
atomic_inc(fclone_ref);
- } else {
+ } else if (skb->fclone == SKB_FCLONE_SCRATCH)
+ n = alloc_fscratch_skb(skb);
+ else
+ n = NULL;
+
+ if (!n) {
n = kmem_cache_alloc(skbuff_head_cache, gfp_mask);
if (!n)
return NULL;
@@ -3205,3 +3220,64 @@ void __skb_warn_lro_forwarding(const struct sk_buff *skb)
" while LRO is enabled\n", skb->dev->name);
}
EXPORT_SYMBOL(__skb_warn_lro_forwarding);
+
+unsigned int skb_make_fclone_scratch(struct sk_buff *skb)
+{
+ size_t bufsz, totsz, scrsz, tmpsz;
+ struct skb_scr_control *sctl;
+ struct sk_buff *scr_skb;
+ struct skb_shared_info *old_info;
+ bool format_tail = false;
+
+ if (skb_shared(skb))
+ return 0;
+
+ /*
+ * Cant do scratch space on fcloned skbs
+ */
+ if (skb->fclone)
+ return 0;
+
+ if ((skb->end - skb->tail) > sizeof(struct skb_shared_info)) {
+ old_info = skb_shinfo(skb);
+ skb->end = skb->tail;
+ memcpy(skb_shinfo(skb), old_info,
+ sizeof(struct skb_shared_info));
+ }
+
+ /*
+ * skb is ours, lets see how big the data area is
+ */
+ totsz = ksize(skb->head);
+
+ /*
+ * This is the used size of our data buffer
+ */
+ bufsz = (skb_end_pointer(skb) - skb->head) +
+ sizeof(struct skb_shared_info);
+
+ if ((bufsz + sizeof(struct skb_scr_control)) >= totsz)
+ return 0;
+
+ /*
+ * And this is the leftover area, minus sizeof(int) to store the number
+ * of scratch skbs we have
+ */
+ scrsz = totsz - (bufsz + sizeof(struct skb_scr_control));
+
+ sctl = skb_get_scratch_control(skb);
+
+ sctl->owner = skb;
+ scr_skb = (struct sk_buff *)(sctl + 1);
+ __skb_queue_head_init(&sctl->scr_skbs);
+ for (tmpsz = sizeof(struct sk_buff); tmpsz < scrsz;
+ tmpsz += sizeof(struct sk_buff)) {
+ __skb_queue_tail(&sctl->scr_skbs, scr_skb);
+ scr_skb++;
+ }
+
+ skb->fclone = SKB_FCLONE_SCRATCH;
+
+ return skb_queue_len(&sctl->scr_skbs);
+
+}
--
1.7.6.4
^ permalink raw reply related
* Introduce FCLONE_SCRATCH skbs to reduce stack memory useage and napi jitter
From: Neil Horman @ 2011-10-27 19:53 UTC (permalink / raw)
To: netdev; +Cc: Neil Horman, David S. Miller
I had this idea awhile ago while I was looking at the receive path for multicast
frames. The top of the mcast recieve path (in __udp4_lib_mcast_deliver, has a
loop in which we traverse a hash list linearly, looking for sockets that are
listening to a given multicast group. For each matching socket we clone the skb
to enqueue it to the corresponding socket. This creates two problems:
1) Application driven jitter in the receive path
As you add processes that listen to the same multcast group, you increase the
number of iterations you have to preform in this loop, which can lead to
increases in the amount of time you spend processing each frame in softirq
context, expecially if you are memory constrained, and the skb_clone operation
has to call all the way back into the buddy allocator for more ram. This can
lead to needlessly dropped frames as rx latency increases in the stack.
2) Increased memory usage
As you increase the number of listeners to a multicast group, you directly
increase the number of times you clone and skb, putting increased memory
pressure on the system.
while neither of these problems is a huge concern, I thought it would be nice if
we could mitigate the effects of increased application instances on performance
in this area. As such I came up with this patch set. I created a new skb
fclone type called FCLONE_SCRATCH. When available, it commandeers the
internally fragmented space of an skb data buffer and uses that to allocate
additional skbs during the clone operation. Since the skb->data area is
allocated with a kmalloc operation (and is therefore nominally a power of 2 in
size), and nominally network interfaces tend to have an mtu of around 1500
bytes, we typically can reclaim several hundred bytes of space at the end of an
skb (more if the incomming packet is not a full MTU in size). This space, being
exclusively accessible to the softirq doing the reclaim, can be quickly accesed
without the need for additional locking, potntially providing lower jitter in
napi context per frame during a receive operation, as well as some memory
savings.
I'm still collecting stats on its performance, but I thought I would post now to
get some early reviews and feedback on it.
Thanks & Regards
Neil
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: "David S. Miller" <davem@davemloft.net>
^ permalink raw reply
* [PATCH v3 3/3] SUNRPC: optimize net_ns dereferencing in rpcbind registering calls
From: Stanislav Kinsbursky @ 2011-10-27 19:30 UTC (permalink / raw)
To: Trond.Myklebust
Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
devel
In-Reply-To: <20111027180824.20459.23219.stgit@localhost6.localdomain6>
Static rpcbind registering functions can be parametrized by network namespace
pointer, calculated only once, instead of using init_net pointer (or taking it
from current when virtualization will be comleted) in many places.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
---
net/sunrpc/rpcb_clnt.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 8c873a8..cc0f402 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -451,14 +451,14 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
/*
* Fill in AF_INET family-specific arguments to register
*/
-static int rpcb_register_inet4(const struct sockaddr *sap,
+static int rpcb_register_inet4(struct sunrpc_net *sn,
+ const struct sockaddr *sap,
struct rpc_message *msg)
{
const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
struct rpcbind_args *map = msg->rpc_argp;
unsigned short port = ntohs(sin->sin_port);
int result;
- struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
map->r_addr = rpc_sockaddr2uaddr(sap);
@@ -479,14 +479,14 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
/*
* Fill in AF_INET6 family-specific arguments to register
*/
-static int rpcb_register_inet6(const struct sockaddr *sap,
+static int rpcb_register_inet6(struct sunrpc_net *sn,
+ const struct sockaddr *sap,
struct rpc_message *msg)
{
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
struct rpcbind_args *map = msg->rpc_argp;
unsigned short port = ntohs(sin6->sin6_port);
int result;
- struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
map->r_addr = rpc_sockaddr2uaddr(sap);
@@ -504,10 +504,10 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
return result;
}
-static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
+static int rpcb_unregister_all_protofamilies(struct sunrpc_net *sn,
+ struct rpc_message *msg)
{
struct rpcbind_args *map = msg->rpc_argp;
- struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
dprintk("RPC: unregistering [%u, %u, '%s'] with "
"local rpcbind\n",
@@ -580,13 +580,13 @@ int rpcb_v4_register(const u32 program, const u32 version,
return -EPROTONOSUPPORT;
if (address == NULL)
- return rpcb_unregister_all_protofamilies(&msg);
+ return rpcb_unregister_all_protofamilies(sn, &msg);
switch (address->sa_family) {
case AF_INET:
- return rpcb_register_inet4(address, &msg);
+ return rpcb_register_inet4(sn, address, &msg);
case AF_INET6:
- return rpcb_register_inet6(address, &msg);
+ return rpcb_register_inet6(sn, address, &msg);
}
return -EAFNOSUPPORT;
^ permalink raw reply related
* [PATCH v3 2/3] SUNRPC: optimize net_ns dereferencing in rpcbind creation calls
From: Stanislav Kinsbursky @ 2011-10-27 19:11 UTC (permalink / raw)
To: Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA
Cc: linux-nfs-u79uwXL29TY76Z2rM5mHXA, xemul-bzQdu9zFT3WakBO8gow8eQ,
neilb-l3A5Bk7waGM, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
bfields-uC3wQj2KruNg9hUCZPvPmw, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
devel-GEFAQzZX7r8dnm+yROfE0A
In-Reply-To: <20111027180824.20459.23219.stgit-bi+AKbBUZKagILUCTcTcHdKyNwTtLsGr@public.gmane.org>
Static rpcbind creation functions can be parametrized by network namespace
pointer, calculated only once, instead of using init_net pointer (or taking it
from current when virtualization will be comleted) in many places.
Signed-off-by: Stanislav Kinsbursky <skinsbursky-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
---
net/sunrpc/rpcb_clnt.c | 35 +++++++++++++++++++----------------
1 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 59bd1fb..8c873a8 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -161,10 +161,10 @@ static void rpcb_map_release(void *data)
kfree(map);
}
-static int rpcb_get_local(void)
+static int rpcb_get_local(struct net *net)
{
int cnt;
- struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
+ struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
spin_lock(&sn->rpcb_clnt_lock);
if (sn->rpcb_users)
@@ -201,9 +201,10 @@ void rpcb_put_local(void)
}
}
-static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
+static void rpcb_set_local(struct net *net, struct rpc_clnt *clnt,
+ struct rpc_clnt *clnt4)
{
- struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
+ struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
/* Protected by rpcb_create_local_mutex */
sn->rpcb_local_clnt = clnt;
@@ -211,22 +212,23 @@ static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
smp_wmb();
sn->rpcb_users = 1;
dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: "
- "%p, rpcb_local_clnt4: %p)\n", sn->rpcb_local_clnt,
- sn->rpcb_local_clnt4);
+ "%p, rpcb_local_clnt4: %p) for net %p%s\n",
+ sn->rpcb_local_clnt, sn->rpcb_local_clnt4,
+ net, (net == &init_net) ? " (init_net)" : "");
}
/*
* Returns zero on success, otherwise a negative errno value
* is returned.
*/
-static int rpcb_create_local_unix(void)
+static int rpcb_create_local_unix(struct net *net)
{
static const struct sockaddr_un rpcb_localaddr_rpcbind = {
.sun_family = AF_LOCAL,
.sun_path = RPCBIND_SOCK_PATHNAME,
};
struct rpc_create_args args = {
- .net = &init_net,
+ .net = net,
.protocol = XPRT_TRANSPORT_LOCAL,
.address = (struct sockaddr *)&rpcb_localaddr_rpcbind,
.addrsize = sizeof(rpcb_localaddr_rpcbind),
@@ -259,7 +261,7 @@ static int rpcb_create_local_unix(void)
clnt4 = NULL;
}
- rpcb_set_local(clnt, clnt4);
+ rpcb_set_local(net, clnt, clnt4);
out:
return result;
@@ -269,7 +271,7 @@ out:
* Returns zero on success, otherwise a negative errno value
* is returned.
*/
-static int rpcb_create_local_net(void)
+static int rpcb_create_local_net(struct net *net)
{
static const struct sockaddr_in rpcb_inaddr_loopback = {
.sin_family = AF_INET,
@@ -277,7 +279,7 @@ static int rpcb_create_local_net(void)
.sin_port = htons(RPCBIND_PORT),
};
struct rpc_create_args args = {
- .net = &init_net,
+ .net = net,
.protocol = XPRT_TRANSPORT_TCP,
.address = (struct sockaddr *)&rpcb_inaddr_loopback,
.addrsize = sizeof(rpcb_inaddr_loopback),
@@ -311,7 +313,7 @@ static int rpcb_create_local_net(void)
clnt4 = NULL;
}
- rpcb_set_local(clnt, clnt4);
+ rpcb_set_local(net, clnt, clnt4);
out:
return result;
@@ -325,16 +327,17 @@ int rpcb_create_local(void)
{
static DEFINE_MUTEX(rpcb_create_local_mutex);
int result = 0;
+ struct net *net = &init_net;
- if (rpcb_get_local())
+ if (rpcb_get_local(net))
return result;
mutex_lock(&rpcb_create_local_mutex);
- if (rpcb_get_local())
+ if (rpcb_get_local(net))
goto out;
- if (rpcb_create_local_unix() != 0)
- result = rpcb_create_local_net();
+ if (rpcb_create_local_unix(net) != 0)
+ result = rpcb_create_local_net(net);
out:
mutex_unlock(&rpcb_create_local_mutex);
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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
* [PATCH v3 1/3] SUNRPC: move rpcbind internals to sunrpc part of network namespace context
From: Stanislav Kinsbursky @ 2011-10-27 19:11 UTC (permalink / raw)
To: Trond.Myklebust
Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
devel
In-Reply-To: <20111027180824.20459.23219.stgit@localhost6.localdomain6>
This patch makes rpcbind logic works in network namespace context. IOW each
network namespace will have it's own unique rpcbind internals (clients and
friends) which is required for registering svc services per network namespace.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
---
net/sunrpc/netns.h | 5 ++++
net/sunrpc/rpcb_clnt.c | 64 ++++++++++++++++++++++++++----------------------
2 files changed, 40 insertions(+), 29 deletions(-)
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index d013bf2..83eede3 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -9,6 +9,11 @@ struct cache_detail;
struct sunrpc_net {
struct proc_dir_entry *proc_net_rpc;
struct cache_detail *ip_map_cache;
+
+ struct rpc_clnt *rpcb_local_clnt;
+ struct rpc_clnt *rpcb_local_clnt4;
+ spinlock_t rpcb_clnt_lock;
+ unsigned int rpcb_users;
};
extern int sunrpc_net_id;
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 983b74f..59bd1fb 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -23,12 +23,15 @@
#include <linux/errno.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/nsproxy.h>
#include <net/ipv6.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/xprtsock.h>
+#include "netns.h"
+
#ifdef RPC_DEBUG
# define RPCDBG_FACILITY RPCDBG_BIND
#endif
@@ -111,12 +114,6 @@ static void rpcb_getport_done(struct rpc_task *, void *);
static void rpcb_map_release(void *data);
static struct rpc_program rpcb_program;
-static struct rpc_clnt * rpcb_local_clnt;
-static struct rpc_clnt * rpcb_local_clnt4;
-
-DEFINE_SPINLOCK(rpcb_clnt_lock);
-unsigned int rpcb_users;
-
struct rpcbind_args {
struct rpc_xprt * r_xprt;
@@ -167,29 +164,31 @@ static void rpcb_map_release(void *data)
static int rpcb_get_local(void)
{
int cnt;
+ struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
- spin_lock(&rpcb_clnt_lock);
- if (rpcb_users)
- rpcb_users++;
- cnt = rpcb_users;
- spin_unlock(&rpcb_clnt_lock);
+ spin_lock(&sn->rpcb_clnt_lock);
+ if (sn->rpcb_users)
+ sn->rpcb_users++;
+ cnt = sn->rpcb_users;
+ spin_unlock(&sn->rpcb_clnt_lock);
return cnt;
}
void rpcb_put_local(void)
{
- struct rpc_clnt *clnt = rpcb_local_clnt;
- struct rpc_clnt *clnt4 = rpcb_local_clnt4;
+ struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
+ struct rpc_clnt *clnt = sn->rpcb_local_clnt;
+ struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4;
int shutdown;
- spin_lock(&rpcb_clnt_lock);
- if (--rpcb_users == 0) {
- rpcb_local_clnt = NULL;
- rpcb_local_clnt4 = NULL;
+ spin_lock(&sn->rpcb_clnt_lock);
+ if (--sn->rpcb_users == 0) {
+ sn->rpcb_local_clnt = NULL;
+ sn->rpcb_local_clnt4 = NULL;
}
- shutdown = !rpcb_users;
- spin_unlock(&rpcb_clnt_lock);
+ shutdown = !sn->rpcb_users;
+ spin_unlock(&sn->rpcb_clnt_lock);
if (shutdown) {
/*
@@ -204,14 +203,16 @@ void rpcb_put_local(void)
static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
{
+ struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
+
/* Protected by rpcb_create_local_mutex */
- rpcb_local_clnt = clnt;
- rpcb_local_clnt4 = clnt4;
+ sn->rpcb_local_clnt = clnt;
+ sn->rpcb_local_clnt4 = clnt4;
smp_wmb();
- rpcb_users = 1;
+ sn->rpcb_users = 1;
dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: "
- "%p, rpcb_local_clnt4: %p)\n", rpcb_local_clnt,
- rpcb_local_clnt4);
+ "%p, rpcb_local_clnt4: %p)\n", sn->rpcb_local_clnt,
+ sn->rpcb_local_clnt4);
}
/*
@@ -431,6 +432,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
struct rpc_message msg = {
.rpc_argp = &map,
};
+ struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
"rpcbind\n", (port ? "" : "un"),
@@ -440,7 +442,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
if (port)
msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
- return rpcb_register_call(rpcb_local_clnt, &msg);
+ return rpcb_register_call(sn->rpcb_local_clnt, &msg);
}
/*
@@ -453,6 +455,7 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
struct rpcbind_args *map = msg->rpc_argp;
unsigned short port = ntohs(sin->sin_port);
int result;
+ struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
map->r_addr = rpc_sockaddr2uaddr(sap);
@@ -465,7 +468,7 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
if (port)
msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
- result = rpcb_register_call(rpcb_local_clnt4, msg);
+ result = rpcb_register_call(sn->rpcb_local_clnt4, msg);
kfree(map->r_addr);
return result;
}
@@ -480,6 +483,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
struct rpcbind_args *map = msg->rpc_argp;
unsigned short port = ntohs(sin6->sin6_port);
int result;
+ struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
map->r_addr = rpc_sockaddr2uaddr(sap);
@@ -492,7 +496,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
if (port)
msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
- result = rpcb_register_call(rpcb_local_clnt4, msg);
+ result = rpcb_register_call(sn->rpcb_local_clnt4, msg);
kfree(map->r_addr);
return result;
}
@@ -500,6 +504,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
{
struct rpcbind_args *map = msg->rpc_argp;
+ struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
dprintk("RPC: unregistering [%u, %u, '%s'] with "
"local rpcbind\n",
@@ -508,7 +513,7 @@ static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
map->r_addr = "";
msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
- return rpcb_register_call(rpcb_local_clnt4, msg);
+ return rpcb_register_call(sn->rpcb_local_clnt4, msg);
}
/**
@@ -566,8 +571,9 @@ int rpcb_v4_register(const u32 program, const u32 version,
struct rpc_message msg = {
.rpc_argp = &map,
};
+ struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
- if (rpcb_local_clnt4 == NULL)
+ if (sn->rpcb_local_clnt4 == NULL)
return -EPROTONOSUPPORT;
if (address == NULL)
^ permalink raw reply related
* [PATCH v3 0/3] SUNRPC: rcbind clients virtualization
From: Stanislav Kinsbursky @ 2011-10-27 19:10 UTC (permalink / raw)
To: Trond.Myklebust
Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
devel
v3:
1) First two patches from previous version were squashed.
This patch-set was created in context of clone of git branch:
git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git
and rebased on tag "v3.1".
This patch-set virtualizes rpcbind clients per network namespace context. IOW,
each network namespace will have its own pair of rpcbind clients (if they would
be created by request).
Note:
1) this patch-set depends on "SUNRPC: make rpcbind clients allocated and
destroyed dynamically" patch-set which has been send earlier.
2) init_net pointer is still used instead of current->nsproxy->net_ns,
because I'm not sure yet about how to virtualize services. I.e. NFS callback
services will be per netns. NFSd service will be per netns too from my pow. But
Lockd can be per netns or one for all. And also we have NFSd file system, which
is not virtualized yet.
The following series consists of:
---
Stanislav Kinsbursky (3):
SUNRPC: move rpcbind internals to sunrpc part of network namespace context
SUNRPC: optimize net_ns dereferencing in rpcbind creation calls
SUNRPC: optimize net_ns dereferencing in rpcbind registering calls
net/sunrpc/netns.h | 5 ++
net/sunrpc/rpcb_clnt.c | 103 ++++++++++++++++++++++++++----------------------
2 files changed, 61 insertions(+), 47 deletions(-)
--
Signature
^ permalink raw reply
* Re: asix usb network driver: nfg
From: Mark Lord @ 2011-10-27 18:48 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20111026.221719.2216112919297458522.davem@davemloft.net>
On 11-10-26 10:17 PM, David Miller wrote:
> From: Mark Lord <kernel@teksavvy.com>
> Date: Wed, 26 Oct 2011 21:23:15 -0400
>
>> Any strong advance objections to replacing the in-kernel version
>> with a (fixed) vendor open source version?
>
> It need to meet the coding etc. standards for inclusion, last
> time I looked at it their driver indeed need a bit of cleaning up.
Yeah, okay -- I've got approval to spend some paid time on the effort,
so I'll have a deeper look at things.
> It's a sad situation, they started with the upstream driver and
> just hacked on it however they pleased in their private copy.
> So now we have this huge divergance and no effort on their part
> to rectify things.
Will there be any issues with "Signed-Off-By" on this?
It's all GPL, by License, but we don't necessarily know who
make what changes to their driver since they forked it.
I don't think that matters much, but then what I think doesn't matter much
either. :)
But it is the only one of the two that's close to working
(and does work when DEBUG messages are enabled -- a timing issue
somewhere that I'll fix).
Thanks David.
^ permalink raw reply
* Re: Quick Fair Queue scheduler maturity and examples
From: Eric Dumazet @ 2011-10-27 16:27 UTC (permalink / raw)
To: Karel Rericha; +Cc: netdev
In-Reply-To: <1319731732.2601.40.camel@edumazet-laptop>
Le jeudi 27 octobre 2011 à 18:08 +0200, Eric Dumazet a écrit :
> Le jeudi 27 octobre 2011 à 14:46 +0200, Karel Rericha a écrit :
>
> > Actually I am doing some reseach to replace our main shaping machine
> > with 60 000+ htb classes, which now saturates 12 core Xeon Westmere to
> > 30% (there are five gigabit network ports on each interface affinited
> > to cores). AFAIK QFQ should be O(1) complexity so it would bring
> > saturation a requirements for number of cores down considerably (HTB
> > has O(log(N)) complexity).
> >
> > I have test machine and about two months to decide if we will stay
> > with HTB or we will try something else. So it would be VERY helpful,
> > if you would search you memory instead your dead disk :-) and send me
> > some example of QFQ usage, if I can ask for a little of your time. I
> > promise to have results published here in return.
> >
> > Thanks, Karel
> >
>
> That seems a good challenge to me ;)
>
> First upgrade to a recent kernel with QFQ included.
> Also upgrade iproute2 to a recent enough version as well.
>
> Then you discover "tc ... qfq help" is not that helpful :(
>
> # tc qdisc add dev eth3 root qfq help
> Usage: ... qfq
>
> OK, its parameters are :
>
> qfq weight num1 [maxpkt BYTES]
>
> You should not touch maxpkt, its default value being 2048
>
> Oh well, I just tried the obvious and my (remote) machine doesnt answer
> to me anymore...
>
> Time for a bit of debugging I am afraid :(
Never mind, it was an user error :)
Here is what I used during my tests, I guess you can adapt your
scripts...
DEV=eth3
RATE="rate 40Mbit"
TNETS="10.2.2.0/25"
ALLOT="allot 20000"
tc qdisc del dev dummy0 root 2>/dev/null
tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 rate 1000Mbit \
bandwidth 1000Mbit
tc class add dev $DEV parent 1: classid 1:1 \
est 1sec 8sec cbq allot 10000 mpu 64 \
rate 1000Mbit prio 1 avpkt 1500 bounded
# output to test nets : 40 Mbit limit
tc class add dev $DEV parent 1:1 classid 1:11 \
est 1sec 8sec cbq $ALLOT mpu 64 \
$RATE prio 2 avpkt 1400 bounded
tc qdisc add dev $DEV parent 1:11 handle 11: \
est 1sec 8sec qfq
tc filter add dev $DEV protocol ip parent 11: handle 3 \
flow hash keys rxhash divisor 8
for i in `seq 1 8`
do
classid=11:$(printf %x $i)
tc class add dev $DEV classid $classid qfq
tc qdisc add dev $DEV parent $classid pfifo limit 30
done
for privnet in $TNETS
do
tc filter add dev $DEV parent 1: protocol ip prio 100 u32 \
match ip dst $privnet flowid 1:11
done
tc filter add dev $DEV parent 1: protocol ip prio 100 u32 \
match ip protocol 0 0x00 flowid 1:1
iperf -u -c 10.2.2.1 -P 32 -l 50
^ permalink raw reply
* Re: Quick Fair Queue scheduler maturity and examples
From: Eric Dumazet @ 2011-10-27 16:08 UTC (permalink / raw)
To: Karel Rericha; +Cc: netdev
In-Reply-To: <CAN==1Rq+WEcezLPNPNug2V11nftDkm2=aRKw95u_R8OPGxG72g@mail.gmail.com>
Le jeudi 27 octobre 2011 à 14:46 +0200, Karel Rericha a écrit :
> Actually I am doing some reseach to replace our main shaping machine
> with 60 000+ htb classes, which now saturates 12 core Xeon Westmere to
> 30% (there are five gigabit network ports on each interface affinited
> to cores). AFAIK QFQ should be O(1) complexity so it would bring
> saturation a requirements for number of cores down considerably (HTB
> has O(log(N)) complexity).
>
> I have test machine and about two months to decide if we will stay
> with HTB or we will try something else. So it would be VERY helpful,
> if you would search you memory instead your dead disk :-) and send me
> some example of QFQ usage, if I can ask for a little of your time. I
> promise to have results published here in return.
>
> Thanks, Karel
>
That seems a good challenge to me ;)
First upgrade to a recent kernel with QFQ included.
Also upgrade iproute2 to a recent enough version as well.
Then you discover "tc ... qfq help" is not that helpful :(
# tc qdisc add dev eth3 root qfq help
Usage: ... qfq
OK, its parameters are :
qfq weight num1 [maxpkt BYTES]
You should not touch maxpkt, its default value being 2048
Oh well, I just tried the obvious and my (remote) machine doesnt answer
to me anymore...
Time for a bit of debugging I am afraid :(
^ permalink raw reply
* Re: [PATCH 2/2 v3] net/smsc911x: Add regulator support
From: Mark Brown @ 2011-10-27 15:46 UTC (permalink / raw)
To: Mike Frysinger
Cc: Linus Walleij, netdev, Steve Glendinning, Mathieu Poirer,
Robert Marklund, Paul Mundt, linux-sh, Sascha Hauer,
Tony Lindgren, linux-omap, uclinux-dist-devel, Linus Walleij
In-Reply-To: <CAJaTeTrzFwxsn22U-NHQ8iCiaUM+mj8PyicavR-DN0HgE08ZEQ@mail.gmail.com>
On Thu, Oct 27, 2011 at 03:21:47PM +0200, Mike Frysinger wrote:
> my gut reaction: smsc911x is working just fine without regulator
> support for many people, so why do we suddenly need to make it a
> requirement ? this is a fairly small amount of code, so adding a
> smsc911x Kconfig symbol to control the regulator support seems like
> overkill. only other option would be to change the patch to not make
> missing regulators non-fatal. so i'd probably lean towards the latter
> (and it sounds like you changed this with earlier versions).
The regulator API contains a series of generic facilities for stubbing
itself out when not in use - there's no need for individual drivers to
worry about this stuff, they should just rely on the framework. The
main one at the minute is REGULATOR_DUMMY which does what you suggest
and makes regulator_get() never fail.
^ permalink raw reply
* Re: [PATCH 2/2 v3] net/smsc911x: Add regulator support
From: Mike Frysinger @ 2011-10-27 13:21 UTC (permalink / raw)
To: Linus Walleij
Cc: netdev, Steve Glendinning, Mathieu Poirer, Robert Marklund,
Paul Mundt, linux-sh, Sascha Hauer, Tony Lindgren, linux-omap,
uclinux-dist-devel, Linus Walleij
In-Reply-To: <1319719691-15799-1-git-send-email-linus.walleij@stericsson.com>
On Thu, Oct 27, 2011 at 14:48, Linus Walleij wrote:
> Platforms that use regulators and the smsc911x and have no defined
> regulator for the smsc911x and claim complete regulator
> constraints with no dummy regulators will need to provide it, for
> example using a fixed voltage regulator. It appears that this may
> affect (apart from Ux500 Snowball) possibly these archs/machines
> that from some grep:s appear to define both CONFIG_SMSC911X and
> CONFIG_REGULATOR:
>
> - ARM Freescale mx3 and OMAP 2 plus, Raumfeld machines
> - Blackfin
> - Super-H
no Blackfin board in the tree uses regulators by default. we do list
regulator resources with some boards so people can rebuild the
development system to support addon daughter cards.
my gut reaction: smsc911x is working just fine without regulator
support for many people, so why do we suddenly need to make it a
requirement ? this is a fairly small amount of code, so adding a
smsc911x Kconfig symbol to control the regulator support seems like
overkill. only other option would be to change the patch to not make
missing regulators non-fatal. so i'd probably lean towards the latter
(and it sounds like you changed this with earlier versions).
> --- a/drivers/net/ethernet/smsc/smsc911x.c
> +++ b/drivers/net/ethernet/smsc/smsc911x.c
>
> +#define SMSC911X_NUM_SUPPLIES 2
this gets used once (to define the array), so i wonder if it shouldn't
just be inlined
> +static int smsc911x_enable_disable_resources(struct platform_device *pdev,
> + bool enable)
> +{
> ...
> + if (enable) {
> + ret = regulator_bulk_enable(ARRAY_SIZE(pdata->supplies),
> + pdata->supplies);
> + if (ret)
> + netdev_err(ndev, "failed to enable regulators %d\n",
> + ret);
> ...
> static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
> ...
> + retval = smsc911x_request_free_resources(pdev, true);
> + if (retval) {
> + pr_err("Could request regulators needed aborting\n");
you warn twice here, and the grammar in the later error is broken, and
uses pr_err() instead of netdev_err(). i would simply drop the latter
pr_err().
> +static int smsc911x_request_free_resources(struct platform_device *pdev,
> + bool request)
> +{
> ...
> + if (request) {
> + ret = regulator_bulk_get(&pdev->dev,
> + ARRAY_SIZE(pdata->supplies),
> + pdata->supplies);
> + if (ret)
> + netdev_err(ndev, "couldn't get regulators %d\n",
> + ret);
> static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
> ...
> + retval = smsc911x_enable_disable_resources(pdev, true);
> + if (retval) {
> + pr_err("Could enable regulators needed aborting\n");
same exact issues with the request/free helper
> + retval = smsc911x_request_free_resources(pdev, false);
> + /* ignore not all have regulators */
old comment ?
-mike
^ permalink raw reply
* [net v2 7/7] bnx2x: update driver version to 1.70.30-0
From: Yaniv Rosner @ 2011-10-27 15:13 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Dmitry Kravkov, Eilon Greenstein
In-Reply-To: <1319728434-25038-1-git-send-email-yanivr@broadcom.com>
From: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 627a580..aec7212 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -23,8 +23,8 @@
* (you will need to reboot afterwards) */
/* #define BNX2X_STOP_ON_ERROR */
-#define DRV_MODULE_VERSION "1.70.00-0"
-#define DRV_MODULE_RELDATE "2011/06/13"
+#define DRV_MODULE_VERSION "1.70.30-0"
+#define DRV_MODULE_RELDATE "2011/10/25"
#define BNX2X_BC_VER 0x040200
#if defined(CONFIG_DCB)
--
1.7.2.2
^ permalink raw reply related
* [net v2 5/7] bnx2x: Enable changing speed when port type is PORT_DA
From: Yaniv Rosner @ 2011-10-27 15:13 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
.../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 1a6e37c..f0ca8b2 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -329,6 +329,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
break;
case PORT_FIBRE:
+ case PORT_DA:
if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE)
break; /* no port change */
--
1.7.2.2
^ permalink raw reply related
* [net v2 6/7] bnx2x: use FW 7.0.29.0
From: Yaniv Rosner @ 2011-10-27 15:13 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Dmitry Kravkov, Eilon Greenstein
In-Reply-To: <1319728434-25038-1-git-send-email-yanivr@broadcom.com>
From: Dmitry Kravkov <dmitry@broadcom.com>
The FW includes the following fixes:
1. (iSCSI) Arrival of un-solicited ASYNC message causes
firmware to abort the connection with RST.
2. (FCoE) There is a probability that truncated FCoE packet on
RX path won't get detected which might lead to FW assert.
3. (iSCSI) Arrival of target-initiated NOP-IN during intense
ISCSI traffic might lead to FW assert.
4. (iSCSI) Chip hangs when in case of retransmission not aligned
to 4-bytes from the beginning of iSCSI PDU.
5. (FCoE) Arrival of packets beyond task IO size can lead to crash.
Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index e44b858..fc754cb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -2550,7 +2550,7 @@ struct host_func_stats {
#define BCM_5710_FW_MAJOR_VERSION 7
#define BCM_5710_FW_MINOR_VERSION 0
-#define BCM_5710_FW_REVISION_VERSION 23
+#define BCM_5710_FW_REVISION_VERSION 29
#define BCM_5710_FW_ENGINEERING_VERSION 0
#define BCM_5710_FW_COMPILE_FLAGS 1
--
1.7.2.2
^ permalink raw reply related
* [net v2 4/7] bnx2x: Fix 54618se LED behavior
From: Yaniv Rosner @ 2011-10-27 15:09 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1319728191-24938-1-git-send-email-yanivr@broadcom.com>
Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 44 +++++++++++----------
1 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 23333e0..bce203f 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -5994,7 +5994,13 @@ int bnx2x_set_led(struct link_params *params,
SHARED_HW_CFG_LED_MAC1);
tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
- EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
+ if (params->phy[EXT_PHY1].type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
+ EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp & 0xfff1);
+ else {
+ EMAC_WR(bp, EMAC_REG_EMAC_LED,
+ (tmp | EMAC_LED_OVERRIDE));
+ }
break;
case LED_MODE_OPER:
@@ -6047,8 +6053,15 @@ int bnx2x_set_led(struct link_params *params,
else
REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
hw_led_mode);
+ } else if ((params->phy[EXT_PHY1].type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
+ (mode != LED_MODE_OPER)) {
+ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
+ tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
+ EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp | 0x3);
} else
- REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
+ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
+ hw_led_mode);
REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
/* Set blinking rate to ~15.9Hz */
@@ -6060,8 +6073,13 @@ int bnx2x_set_led(struct link_params *params,
LED_BLINK_RATE_VAL_E1X_E2);
REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
port*4, 1);
- tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
- EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp & (~EMAC_LED_OVERRIDE)));
+ if ((params->phy[EXT_PHY1].type !=
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
+ (mode != LED_MODE_OPER)) {
+ tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
+ EMAC_WR(bp, EMAC_REG_EMAC_LED,
+ (tmp & (~EMAC_LED_OVERRIDE)));
+ }
if (CHIP_IS_E1(bp) &&
((speed == SPEED_2500) ||
@@ -10309,22 +10327,6 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
return 0;
}
-static void bnx2x_54618se_set_link_led(struct bnx2x_phy *phy,
- struct link_params *params, u8 mode)
-{
- struct bnx2x *bp = params->bp;
- DP(NETIF_MSG_LINK, "54618SE set link led (mode=%x)\n", mode);
- switch (mode) {
- case LED_MODE_FRONT_PANEL_OFF:
- case LED_MODE_OFF:
- case LED_MODE_OPER:
- case LED_MODE_ON:
- default:
- break;
- }
- return;
-}
-
static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
struct link_params *params)
{
@@ -11101,7 +11103,7 @@ static struct bnx2x_phy phy_54618se = {
.config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback,
.format_fw_ver = (format_fw_ver_t)NULL,
.hw_reset = (hw_reset_t)NULL,
- .set_link_led = (set_link_led_t)bnx2x_54618se_set_link_led,
+ .set_link_led = (set_link_led_t)NULL,
.phy_specific_func = (phy_specific_func_t)NULL
};
/*****************************************************************/
--
1.7.2.2
^ permalink raw reply related
* [net v2 3/7] bnx2x: Fix RX/TX problem caused by the MAC layer
From: Yaniv Rosner @ 2011-10-27 15:09 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1319728191-24938-1-git-send-email-yanivr@broadcom.com>
This patch fixes a problem in which the host stops receiving data after
restarting the interface. This issue is caused by combination of incorrect
data path tap closure, along with missing MAC reset.
Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 45 ++++++++++++++++------
1 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index a47db9d..23333e0 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -1494,6 +1494,18 @@ static void bnx2x_set_xumac_nig(struct link_params *params,
NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
}
+static void bnx2x_umac_disable(struct link_params *params)
+{
+ u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
+ struct bnx2x *bp = params->bp;
+ if (!(REG_RD(bp, MISC_REG_RESET_REG_2) &
+ (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
+ return;
+
+ /* Disable RX and TX */
+ REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, 0);
+}
+
static void bnx2x_umac_enable(struct link_params *params,
struct link_vars *vars, u8 lb)
{
@@ -1603,8 +1615,9 @@ static u8 bnx2x_is_4_port_mode(struct bnx2x *bp)
}
/* Define the XMAC mode */
-static void bnx2x_xmac_init(struct bnx2x *bp, u32 max_speed)
+static void bnx2x_xmac_init(struct link_params *params, u32 max_speed)
{
+ struct bnx2x *bp = params->bp;
u32 is_port4mode = bnx2x_is_4_port_mode(bp);
/**
@@ -1614,7 +1627,8 @@ static void bnx2x_xmac_init(struct bnx2x *bp, u32 max_speed)
* ports of the path
**/
- if (is_port4mode && (REG_RD(bp, MISC_REG_RESET_REG_2) &
+ if ((CHIP_NUM(bp) == CHIP_NUM_57840) &&
+ (REG_RD(bp, MISC_REG_RESET_REG_2) &
MISC_REGISTERS_RESET_REG_2_XMAC)) {
DP(NETIF_MSG_LINK,
"XMAC already out of reset in 4-port mode\n");
@@ -1681,10 +1695,6 @@ static void bnx2x_xmac_disable(struct link_params *params)
(pfc_ctrl | (1<<1)));
DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0);
- usleep_range(1000, 1000);
- bnx2x_set_xumac_nig(params, 0, 0);
- REG_WR(bp, xmac_base + XMAC_REG_CTRL,
- XMAC_CTRL_REG_SOFT_RESET);
}
}
@@ -1697,7 +1707,7 @@ static int bnx2x_xmac_enable(struct link_params *params,
xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
- bnx2x_xmac_init(bp, vars->line_speed);
+ bnx2x_xmac_init(params, vars->line_speed);
/*
* This register determines on which events the MAC will assert
@@ -6310,8 +6320,10 @@ static int bnx2x_update_link_down(struct link_params *params,
MISC_REGISTERS_RESET_REG_2_CLEAR,
(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
}
- if (CHIP_IS_E3(bp))
+ if (CHIP_IS_E3(bp)) {
bnx2x_xmac_disable(params);
+ bnx2x_umac_disable(params);
+ }
return 0;
}
@@ -11810,8 +11822,10 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
/* Stop BigMac rx */
if (!CHIP_IS_E3(bp))
bnx2x_bmac_rx_disable(bp, port);
- else
+ else {
bnx2x_xmac_disable(params);
+ bnx2x_umac_disable(params);
+ }
/* disable emac */
if (!CHIP_IS_E3(bp))
REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
@@ -11849,14 +11863,21 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
if (params->phy[INT_PHY].link_reset)
params->phy[INT_PHY].link_reset(
¶ms->phy[INT_PHY], params);
- /* reset BigMac */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
/* disable nig ingress interface */
if (!CHIP_IS_E3(bp)) {
+ /* reset BigMac */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
+ } else {
+ u32 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
+ bnx2x_set_xumac_nig(params, 0, 0);
+ if (REG_RD(bp, MISC_REG_RESET_REG_2) &
+ MISC_REGISTERS_RESET_REG_2_XMAC)
+ REG_WR(bp, xmac_base + XMAC_REG_CTRL,
+ XMAC_CTRL_REG_SOFT_RESET);
}
vars->link_up = 0;
vars->phy_flags = 0;
--
1.7.2.2
^ permalink raw reply related
* [net v2 2/7] bnx2x: Add link retry to 578xx-KR
From: Yaniv Rosner @ 2011-10-27 15:09 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1319728191-24938-1-git-send-email-yanivr@broadcom.com>
This fix solves a problem of no link on 578xx-KR by retrying to link up to
four timer using the periodic function.
Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 117 +++++++++++++++++++---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h | 3 +
2 files changed, 104 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index edc9259..a47db9d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -261,6 +261,7 @@
#define MAX_PACKET_SIZE (9700)
#define WC_UC_TIMEOUT 100
+#define MAX_KR_LINK_RETRY 4
/**********************************************************/
/* INTERFACE */
@@ -3578,6 +3579,11 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
u16 val16 = 0, lane, bam37 = 0;
struct bnx2x *bp = params->bp;
DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
+
+ /* Disable Autoneg: re-enable it after adv is done. */
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+ MDIO_WC_REG_IEEE0BLK_MIICNTL, 0);
+
/* Check adding advertisement for 1G KX */
if (((vars->line_speed == SPEED_AUTO_NEG) &&
(phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
@@ -3619,9 +3625,6 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
0x03f0);
- bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
- MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
- 0x383f);
/* Advertised speeds */
bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
@@ -3648,19 +3651,22 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
/* Advertise pause */
bnx2x_ext_phy_set_pause(params, phy, vars);
- /* Enable Autoneg */
- bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
- MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000);
-
- /* Over 1G - AN local device user page 1 */
- bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
- MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
+ vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_DIGITAL5_MISC7, &val16);
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100);
+
+ /* Over 1G - AN local device user page 1 */
+ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+ MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
+
+ /* Enable Autoneg */
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+ MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000);
+
}
static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
@@ -4129,6 +4135,85 @@ static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
else
return 0;
}
+static int bnx2x_warpcore_get_sigdet(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ u16 gp2_status_reg0, lane;
+ struct bnx2x *bp = params->bp;
+
+ lane = bnx2x_get_warpcore_lane(phy, params);
+
+ bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
+ &gp2_status_reg0);
+
+ return (gp2_status_reg0 >> (8+lane)) & 0x1;
+}
+
+static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u32 serdes_net_if;
+ u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
+ u16 lane = bnx2x_get_warpcore_lane(phy, params);
+
+ vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
+
+ if (!vars->turn_to_run_wc_rt)
+ return;
+
+ /* return if there is no link partner */
+ if (!(bnx2x_warpcore_get_sigdet(phy, params))) {
+ DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n");
+ return;
+ }
+
+ if (vars->rx_tx_asic_rst) {
+ serdes_net_if = (REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region, dev_info.
+ port_hw_config[params->port].default_cfg)) &
+ PORT_HW_CFG_NET_SERDES_IF_MASK);
+
+ switch (serdes_net_if) {
+ case PORT_HW_CFG_NET_SERDES_IF_KR:
+ /* Do we get link yet? */
+ bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 0x81d1,
+ &gp_status1);
+ lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */
+ /*10G KR*/
+ lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
+
+ DP(NETIF_MSG_LINK,
+ "gp_status1 0x%x\n", gp_status1);
+
+ if (lnkup_kr || lnkup) {
+ vars->rx_tx_asic_rst = 0;
+ DP(NETIF_MSG_LINK,
+ "link up, rx_tx_asic_rst 0x%x\n",
+ vars->rx_tx_asic_rst);
+ } else {
+ /*reset the lane to see if link comes up.*/
+ bnx2x_warpcore_reset_lane(bp, phy, 1);
+ bnx2x_warpcore_reset_lane(bp, phy, 0);
+
+ /* restart Autoneg */
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+ MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
+
+ vars->rx_tx_asic_rst--;
+ DP(NETIF_MSG_LINK, "0x%x retry left\n",
+ vars->rx_tx_asic_rst);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ } /*params->rx_tx_asic_rst*/
+
+}
static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
struct link_params *params,
@@ -12339,11 +12424,6 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
u16 phy_idx;
- if (!params) {
- DP(NETIF_MSG_LINK, "Uninitialized params !\n");
- return;
- }
-
for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) {
bnx2x_set_aer_mmd(params, ¶ms->phy[phy_idx]);
@@ -12352,8 +12432,13 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
}
}
- if (CHIP_IS_E3(bp))
+ if (CHIP_IS_E3(bp)) {
+ struct bnx2x_phy *phy = ¶ms->phy[INT_PHY];
+ bnx2x_set_aer_mmd(params, phy);
bnx2x_check_over_curr(params, vars);
+ bnx2x_warpcore_config_runtime(phy, params, vars);
+ }
+
}
u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
index c12db6d..2a46e63 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
@@ -303,6 +303,9 @@ struct link_vars {
#define PERIODIC_FLAGS_LINK_EVENT 0x0001
u32 aeu_int_mask;
+ u8 rx_tx_asic_rst;
+ u8 turn_to_run_wc_rt;
+ u16 rsrv2;
};
/***********************************************************/
--
1.7.2.2
^ permalink raw reply related
* [net v2 1/7] bnx2x: Fix LED blink rate for 578xx
From: Yaniv Rosner @ 2011-10-27 15:09 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1319728191-24938-1-git-send-email-yanivr@broadcom.com>
Adjust blink rate on 578xx to fit its clock rate.
Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 818723c..edc9259 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -45,6 +45,9 @@
#define MCPR_IMC_COMMAND_READ_OP 1
#define MCPR_IMC_COMMAND_WRITE_OP 2
+/* LED Blink rate that will achieve ~15.9Hz */
+#define LED_BLINK_RATE_VAL_E3 354
+#define LED_BLINK_RATE_VAL_E1X_E2 480
/***********************************************************/
/* Shortcut definitions */
/***********************************************************/
@@ -5954,8 +5957,12 @@ int bnx2x_set_led(struct link_params *params,
REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
/* Set blinking rate to ~15.9Hz */
- REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
- LED_BLINK_RATE_VAL);
+ if (CHIP_IS_E3(bp))
+ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
+ LED_BLINK_RATE_VAL_E3);
+ else
+ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
+ LED_BLINK_RATE_VAL_E1X_E2);
REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
port*4, 1);
tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
--
1.7.2.2
^ permalink raw reply related
* [net 0/7] bnx2x: driver and firmware fixes
From: Yaniv Rosner @ 2011-10-27 15:09 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Yaniv Rosner
Hi Dave,
The following patch series describe few link fixes and firmware update.
Please consider applying it to net.
Thanks,
Yaniv
^ permalink raw reply
* [PATCH 2/2 v3] net/smsc911x: Add regulator support
From: Linus Walleij @ 2011-10-27 12:48 UTC (permalink / raw)
To: netdev, Steve Glendinning
Cc: Mathieu Poirer, Robert Marklund, Paul Mundt, linux-sh,
Sascha Hauer, Tony Lindgren, linux-omap, Mike Frysinger,
uclinux-dist-devel, Linus Walleij
From: Robert Marklund <robert.marklund@stericsson.com>
Add some basic regulator support for the power pins, as needed
by the ST-Ericsson Snowball platform that powers up the SMSC911
chip using an external regulator.
Platforms that use regulators and the smsc911x and have no defined
regulator for the smsc911x and claim complete regulator
constraints with no dummy regulators will need to provide it, for
example using a fixed voltage regulator. It appears that this may
affect (apart from Ux500 Snowball) possibly these archs/machines
that from some grep:s appear to define both CONFIG_SMSC911X and
CONFIG_REGULATOR:
- ARM Freescale mx3 and OMAP 2 plus, Raumfeld machines
- Blackfin
- Super-H
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: linux-sh@vger.kernel.org
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Tony Lindgren <tony@atomide.com>
Cc: linux-omap@vger.kernel.org
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: uclinux-dist-devel@blackfin.uclinux.org
Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Robert Marklund <robert.marklund@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v2->v3:
- Use bulk regulators on Mark's request.
- Add Cc-fileds to some possibly affected platforms.
ChangeLog v1->v2:
- Don't check for NULL regulators and error out properly if the
regulators can't be found. All platforms using the smsc911x
and the regulator framework simultaneously need to provide some
kind of regulator for it.
---
drivers/net/ethernet/smsc/smsc911x.c | 103 ++++++++++++++++++++++++++++++----
1 files changed, 92 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 8843071..8ad15a6 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -44,6 +44,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/bug.h>
@@ -88,6 +89,8 @@ struct smsc911x_ops {
unsigned int *buf, unsigned int wordcount);
};
+#define SMSC911X_NUM_SUPPLIES 2
+
struct smsc911x_data {
void __iomem *ioaddr;
@@ -138,6 +141,9 @@ struct smsc911x_data {
/* register access functions */
const struct smsc911x_ops *ops;
+
+ /* regulators */
+ struct regulator_bulk_data supplies[SMSC911X_NUM_SUPPLIES];
};
/* Easy access to information */
@@ -362,6 +368,60 @@ out:
spin_unlock_irqrestore(&pdata->dev_lock, flags);
}
+/*
+ * Enable or disable resources, currently just regulators.
+ */
+static int smsc911x_enable_disable_resources(struct platform_device *pdev,
+ bool enable)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct smsc911x_data *pdata = netdev_priv(ndev);
+ int ret = 0;
+
+ /* enable/disable regulators */
+ if (enable) {
+ ret = regulator_bulk_enable(ARRAY_SIZE(pdata->supplies),
+ pdata->supplies);
+ if (ret)
+ netdev_err(ndev, "failed to enable regulators %d\n",
+ ret);
+ } else
+ ret = regulator_bulk_disable(ARRAY_SIZE(pdata->supplies),
+ pdata->supplies);
+ return ret;
+}
+
+/*
+ * Request or free resources, currently just regulators.
+ *
+ * The SMSC911x has two power pins: vddvario and vdd33a, in designs where
+ * these are not always-on we need to request regulators to be turned on
+ * before we can try to access the device registers.
+ */
+static int smsc911x_request_free_resources(struct platform_device *pdev,
+ bool request)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct smsc911x_data *pdata = netdev_priv(ndev);
+ int ret = 0;
+
+ /* Request regulators */
+ if (request) {
+ pdata->supplies[0].supply = "vdd33a";
+ pdata->supplies[1].supply = "vddvario";
+ ret = regulator_bulk_get(&pdev->dev,
+ ARRAY_SIZE(pdata->supplies),
+ pdata->supplies);
+ if (ret)
+ netdev_err(ndev, "couldn't get regulators %d\n",
+ ret);
+ } else
+ regulator_bulk_free(ARRAY_SIZE(pdata->supplies),
+ pdata->supplies);
+
+ return ret;
+}
+
/* waits for MAC not busy, with timeout. Only called by smsc911x_mac_read
* and smsc911x_mac_write, so assumes mac_lock is held */
static int smsc911x_mac_complete(struct smsc911x_data *pdata)
@@ -2065,6 +2125,7 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev)
struct net_device *dev;
struct smsc911x_data *pdata;
struct resource *res;
+ int retval;
dev = platform_get_drvdata(pdev);
BUG_ON(!dev);
@@ -2092,6 +2153,12 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev)
iounmap(pdata->ioaddr);
+ if (smsc911x_enable_disable_resources(pdev, false))
+ pr_warn("Could not disable resource\n");
+
+ retval = smsc911x_request_free_resources(pdev, false);
+ /* ignore not all have regulators */
+
free_netdev(dev);
return 0;
@@ -2218,10 +2285,24 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
pdata->dev = dev;
pdata->msg_enable = ((1 << debug) - 1);
+ platform_set_drvdata(pdev, dev);
+
+ retval = smsc911x_request_free_resources(pdev, true);
+ if (retval) {
+ pr_err("Could request regulators needed aborting\n");
+ goto out_return_resources;
+ }
+
+ retval = smsc911x_enable_disable_resources(pdev, true);
+ if (retval) {
+ pr_err("Could enable regulators needed aborting\n");
+ goto out_disable_resources;
+ }
+
if (pdata->ioaddr == NULL) {
SMSC_WARN(pdata, probe, "Error smsc911x base address invalid");
retval = -ENOMEM;
- goto out_free_netdev_2;
+ goto out_disable_resources;
}
retval = smsc911x_probe_config_dt(&pdata->config, np);
@@ -2233,7 +2314,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
if (retval) {
SMSC_WARN(pdata, probe, "Error smsc911x config not found");
- goto out_unmap_io_3;
+ goto out_disable_resources;
}
/* assume standard, non-shifted, access to HW registers */
@@ -2244,7 +2325,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
retval = smsc911x_init(dev);
if (retval < 0)
- goto out_unmap_io_3;
+ goto out_disable_resources;
/* configure irq polarity and type before connecting isr */
if (pdata->config.irq_polarity == SMSC911X_IRQ_POLARITY_ACTIVE_HIGH)
@@ -2264,15 +2345,13 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
if (retval) {
SMSC_WARN(pdata, probe,
"Unable to claim requested irq: %d", dev->irq);
- goto out_unmap_io_3;
+ goto out_free_irq;
}
- platform_set_drvdata(pdev, dev);
-
retval = register_netdev(dev);
if (retval) {
SMSC_WARN(pdata, probe, "Error %i registering device", retval);
- goto out_unset_drvdata_4;
+ goto out_free_irq;
} else {
SMSC_TRACE(pdata, probe,
"Network interface: \"%s\"", dev->name);
@@ -2321,12 +2400,14 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
out_unregister_netdev_5:
unregister_netdev(dev);
-out_unset_drvdata_4:
- platform_set_drvdata(pdev, NULL);
+out_free_irq:
free_irq(dev->irq, dev);
-out_unmap_io_3:
+out_disable_resources:
+ (void)smsc911x_enable_disable_resources(pdev, false);
+out_return_resources:
+ (void)smsc911x_request_free_resources(pdev, false);
+ platform_set_drvdata(pdev, NULL);
iounmap(pdata->ioaddr);
-out_free_netdev_2:
free_netdev(dev);
out_release_io_1:
release_mem_region(res->start, resource_size(res));
--
1.7.3.2
^ permalink raw reply related
* Re: Quick Fair Queue scheduler maturity and examples
From: Karel Rericha @ 2011-10-27 12:46 UTC (permalink / raw)
To: Eric Dumazet, netdev
In-Reply-To: <1319716772.2601.26.camel@edumazet-laptop>
2011/10/27 Eric Dumazet <eric.dumazet@gmail.com>:
> Le jeudi 27 octobre 2011 à 13:30 +0200, Karel Rericha a écrit :
>> Hi list,
>>
>> has anyone some experience about QFQ and its maturity ? I was not able
>> to find anything more than patches and papers, real world examples and
>> info are nonexistent.
>>
>
> At its inclusion time (in linux 3.0), I did many tests and feedback to
> Stephen.
>
> By the way, QFQ is not only patches and papers, its now officially
> supported by linux netdev team ;)
>
> Unfortunately the machine where I kept traces of my qfq scripts was
> totally lost, no backups.... oh well...
>
> Given that not a single patch was added since initial commit, I guess
> nobody really uses the thing, or its perfect, who knows :)
>
> You definitely should be able to use it, and report here problems if
> any.
>
Actually I am doing some reseach to replace our main shaping machine
with 60 000+ htb classes, which now saturates 12 core Xeon Westmere to
30% (there are five gigabit network ports on each interface affinited
to cores). AFAIK QFQ should be O(1) complexity so it would bring
saturation a requirements for number of cores down considerably (HTB
has O(log(N)) complexity).
I have test machine and about two months to decide if we will stay
with HTB or we will try something else. So it would be VERY helpful,
if you would search you memory instead your dead disk :-) and send me
some example of QFQ usage, if I can ask for a little of your time. I
promise to have results published here in return.
Thanks, Karel
BTW I can provide some virtual Gentoo servers for test setup if you
would want participate in further testing.
^ permalink raw reply
* Re: [PATCH] Add TCP_NO_DELAYED_ACK socket option
From: Daniel Baluta @ 2011-10-27 12:18 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Andy Lutomirski, netdev
In-Reply-To: <1319717597.2601.28.camel@edumazet-laptop>
On Thu, Oct 27, 2011 at 3:13 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le jeudi 27 octobre 2011 à 14:54 +0300, Daniel Baluta a écrit :
>
>> Few days ago, in our custom kernel we made TCP Delack segments and
>> TCP Delack timeout parameters tunable via proc entries.
>> Increasing tcp_delack_segs (number of full sized segments that must
>> be received until an ACK is sent) we observed an improvement of
>> throughput up to 20% in some test cases.
>>
>> Do you think that this kind of patch would have a chance to be
>> included in mainstream?
>>
>
> If your patches are ready, why not sending them as RFC ?
OK, I will port them to the latest kernel and send a patch.
thanks,
Daniel.
^ permalink raw reply
* Re: [PATCH] Add TCP_NO_DELAYED_ACK socket option
From: Eric Dumazet @ 2011-10-27 12:13 UTC (permalink / raw)
To: Daniel Baluta; +Cc: Andy Lutomirski, netdev
In-Reply-To: <CAEnQRZAmDMg943uufpwf4dj0vw9hfsRu3RFRG+LEqfT2Y0ty1Q@mail.gmail.com>
Le jeudi 27 octobre 2011 à 14:54 +0300, Daniel Baluta a écrit :
> Few days ago, in our custom kernel we made TCP Delack segments and
> TCP Delack timeout parameters tunable via proc entries.
> Increasing tcp_delack_segs (number of full sized segments that must
> be received until an ACK is sent) we observed an improvement of
> throughput up to 20% in some test cases.
>
> Do you think that this kind of patch would have a chance to be
> included in mainstream?
>
If your patches are ready, why not sending them as RFC ?
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox