* dgrs: sparse warnings
From: Stephen Hemminger @ 2007-09-06 12:55 UTC (permalink / raw)
To: Al Viro, Jeff Garzik; +Cc: netdev
The dgrs driver is crap and assumes direct access to PCI iomem.
CHECK drivers/net/dgrs.c
drivers/net/dgrs.c:314:20: warning: cast removes address space of expression
drivers/net/dgrs.c:330:12: warning: incorrect type in argument 1 (different address spaces)
drivers/net/dgrs.c:330:12: expected void volatile [noderef] <asn:2>*addr
drivers/net/dgrs.c:330:12: got void *<noident>
drivers/net/dgrs.c:1003:14: warning: incorrect type in assignment (different address spaces)
drivers/net/dgrs.c:1003:14: expected char *[usertype] vmem
drivers/net/dgrs.c:1003:14: got void [noderef] <asn:2>*
drivers/net/dgrs.c:1023:17: warning: incorrect type in argument 1 (different address spaces)
drivers/net/dgrs.c:1023:17: expected void volatile [noderef] <asn:2>*addr
drivers/net/dgrs.c:1023:17: got char *[usertype] vmem
drivers/net/dgrs.c:1052:16: warning: incorrect type in argument 1 (different address spaces)
drivers/net/dgrs.c:1052:16: expected void volatile [noderef] <asn:2>*addr
drivers/net/dgrs.c:1052:16: got char *[usertype] vmem
drivers/net/dgrs.c:1106:16: warning: incorrect type in argument 1 (different address spaces)
drivers/net/dgrs.c:1106:16: expected void volatile [noderef] <asn:2>*addr
drivers/net/dgrs.c:1106:16: got char *[usertype] vmem
drivers/net/dgrs.c:1369:15: warning: incorrect type in argument 1 (different address spaces)
drivers/net/dgrs.c:1369:15: expected void volatile [noderef] <asn:2>*addr
drivers/net/dgrs.c:1369:15: got char *[usertype] vmem
drivers/net/dgrs.c:1371:12: warning: incorrect type in argument 1 (different address spaces)
drivers/net/dgrs.c:1371:12: expected void volatile [noderef] <asn:2>*addr
drivers/net/dgrs.c:1371:12: got unsigned char [usertype] *<noident>
Perhaps we should just mark it as BROKEN in Kconfig
^ permalink raw reply
* Re: BUG: scheduling while atomic: ifconfig/0x00000002/4170
From: Satyam Sharma @ 2007-09-06 12:52 UTC (permalink / raw)
To: Johannes Berg
Cc: Herbert Xu, Florian Lohoff, Linux Kernel Mailing List, Netdev,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, Michal Piotrowski,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
yi.zhu-ral2JQCrhuEAvxtiuMwx3w, Michael Wu
In-Reply-To: <1189080575.28781.65.camel-YfaajirXv214zXjbi5bjpg@public.gmane.org>
On Thu, 6 Sep 2007, Johannes Berg wrote:
> On Thu, 2007-09-06 at 16:23 +0800, Herbert Xu wrote:
> > On Thu, Sep 06, 2007 at 10:32:33AM +0530, Satyam Sharma wrote:
> > >
> > > > > [ 382.529041] [<c02c8abc>] dev_close+0x24/0x67
> > > > > [ 382.529052] [<e01f402b>] ieee80211_master_stop+0x4a/0x6d [mac80211]
> >
> > This is where the bug is. You cannot call dev_close from an
> > atomic context as i33380211_master_stop does it within spin
> > locks.
>
> Hah, I suspected as much but didn't have a chance to look yet. I had
> plans to replace that sub_if_list with an RCU list and not require the
> lock there, but that's far off.
Unless I missed something obvious (let me know if that's the case! :-)
an RCU-protected list would suffer the same fate. list_for_each_xxx_rcu()
must be under rcu_read_lock() which == preempt_disable() ...
^ permalink raw reply
* Re: BUG: scheduling while atomic: ifconfig/0x00000002/4170
From: Johannes Berg @ 2007-09-06 12:46 UTC (permalink / raw)
To: Satyam Sharma
Cc: Herbert Xu, Florian Lohoff, Linux Kernel Mailing List, Netdev,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, Michal Piotrowski,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
yi.zhu-ral2JQCrhuEAvxtiuMwx3w, Michael Wu
In-Reply-To: <alpine.LFD.0.999.0709061818270.3781-cF9xTIDbLT5E1qDFBaZ7QYsk13R+tSIrn9A1Ff6Mc9Q@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 741 bytes --]
On Thu, 2007-09-06 at 18:22 +0530, Satyam Sharma wrote:
> Unless I missed something obvious (let me know if that's the case! :-)
> an RCU-protected list would suffer the same fate. list_for_each_xxx_rcu()
> must be under rcu_read_lock() which == preempt_disable() ...
Right. But I'm thinking that since all list manipulations are done under
RTNL we only need to protect against removing things from the list while
the RX or TX path is using it, so only it would have to use it under
rcu_read_lock() [which it already takes due to key management] so we
could get rid of that sub_if_lock completely. There is one issue with
this I know about and that is the management skb queue but I'll have to
take a closer look.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply
* Re: BUG: scheduling while atomic: ifconfig/0x00000002/4170
From: Johannes Berg @ 2007-09-06 12:44 UTC (permalink / raw)
To: Herbert Xu
Cc: satyam-wEGCiKHe2LqWVfeAwA7xHQ, flo-BCn6idZOOBwdnm+yROfE0A,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
michal.k.k.piotrowski-Re5JQEeQqe8AvxtiuMwx3w,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
yi.zhu-ral2JQCrhuEAvxtiuMwx3w, flamingice-R9e9/4HEdknk1uMJSBkQmQ
In-Reply-To: <E1ITGb2-0006Be-00-XQvu0L+U/CjiRBuR/1fSEKKkPtS2pBon@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 729 bytes --]
On Thu, 2007-09-06 at 20:36 +0800, Herbert Xu wrote:
> Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org> wrote:
> >
> > Hah, I suspected as much but didn't have a chance to look yet. I had
> > plans to replace that sub_if_list with an RCU list and not require the
> > lock there, but that's far off. Any ideas how to fix this? We can't
> > reject the master stop so we have to walk the list, I guess we'll have
> > to audit the other list manipulation places, I think they're all under
> > RTNL.
>
> Yeah I think they're all under RTNL too. So you don't need to
> take the lock here at all since you should already have the RTNL.
I'll take a look at them and post appropriate patches.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply
* Re: BUG: scheduling while atomic: ifconfig/0x00000002/4170
From: Herbert Xu @ 2007-09-06 12:36 UTC (permalink / raw)
To: Johannes Berg
Cc: herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q,
satyam-wEGCiKHe2LqWVfeAwA7xHQ, flo-BCn6idZOOBwdnm+yROfE0A,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
michal.k.k.piotrowski-Re5JQEeQqe8AvxtiuMwx3w,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
yi.zhu-ral2JQCrhuEAvxtiuMwx3w, flamingice-R9e9/4HEdknk1uMJSBkQmQ
In-Reply-To: <1189080575.28781.65.camel-YfaajirXv214zXjbi5bjpg@public.gmane.org>
Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org> wrote:
>
> Hah, I suspected as much but didn't have a chance to look yet. I had
> plans to replace that sub_if_list with an RCU list and not require the
> lock there, but that's far off. Any ideas how to fix this? We can't
> reject the master stop so we have to walk the list, I guess we'll have
> to audit the other list manipulation places, I think they're all under
> RTNL.
Yeah I think they're all under RTNL too. So you don't need to
take the lock here at all since you should already have the RTNL.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: BUG: scheduling while atomic: ifconfig/0x00000002/4170
From: Johannes Berg @ 2007-09-06 12:09 UTC (permalink / raw)
To: Herbert Xu
Cc: Satyam Sharma, Florian Lohoff, Linux Kernel Mailing List, Netdev,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, Michal Piotrowski,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
yi.zhu-ral2JQCrhuEAvxtiuMwx3w, Michael Wu
In-Reply-To: <20070906082301.GB21929-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 782 bytes --]
On Thu, 2007-09-06 at 16:23 +0800, Herbert Xu wrote:
> On Thu, Sep 06, 2007 at 10:32:33AM +0530, Satyam Sharma wrote:
> >
> > > > [ 382.529041] [<c02c8abc>] dev_close+0x24/0x67
> > > > [ 382.529052] [<e01f402b>] ieee80211_master_stop+0x4a/0x6d [mac80211]
>
> This is where the bug is. You cannot call dev_close from an
> atomic context as i33380211_master_stop does it within spin
> locks.
Hah, I suspected as much but didn't have a chance to look yet. I had
plans to replace that sub_if_list with an RCU list and not require the
lock there, but that's far off. Any ideas how to fix this? We can't
reject the master stop so we have to walk the list, I guess we'll have
to audit the other list manipulation places, I think they're all under
RTNL.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply
* Re: [PATCH 1/1] NFS: change the ip_map cache code to handle IPv6 addresses
From: Aurélien Charbon @ 2007-09-06 11:30 UTC (permalink / raw)
To: Brian Haley; +Cc: Mailing list NFSv4, netdev ML
In-Reply-To: <46CDA874.5020609@hp.com>
[-- Attachment #1: Type: text/plain, Size: 13644 bytes --]
Thanks Chuck and Brian for your comments.
Here is some correction for the ip_map caching code part.
I have updated the code to use Brian's ipv6_addr_v4mapped function, and corrected some mistake you pointed out.
I have checked this patch with the checkpatch.pl script and i do not understand why the indentation is modified when sending it by mail (may be my mailer :-/). So i have added the patch in attachment.
Tests: tested with only IPv4 network and basic nfs ops (mount, file creation and modification)
Signed-off-by: Aurelien Charbon <aurelien.charbon@ext.bull.net>
---
fs/nfsd/export.c | 10 ++-
fs/nfsd/nfsctl.c | 16 ++++-
include/linux/sunrpc/svcauth.h | 4 -
include/net/ipv6.h | 15 +++++
net/sunrpc/svcauth_unix.c | 112 +++++++++++++++++++++++++++--------------
5 files changed, 113 insertions(+), 44 deletions(-)
diff -p -u -r -N linux-2.6.23-rc5/fs/nfsd/export.c linux-2.6.23-rc5-IPv6-ipmap-cache/fs/nfsd/export.c
--- linux-2.6.23-rc5/fs/nfsd/export.c 2007-09-04 13:55:02.000000000 +0200
+++ linux-2.6.23-rc5-IPv6-ipmap-cache/fs/nfsd/export.c 2007-09-04 17:05:47.000000000 +0200
@@ -35,6 +35,7 @@
#include <linux/lockd/bind.h>
#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/gss_api.h>
+#include <net/ipv6.h>
#define NFSDDBG_FACILITY NFSDDBG_EXPORT
@@ -1559,6 +1560,7 @@ exp_addclient(struct nfsctl_client *ncp)
{
struct auth_domain *dom;
int i, err;
+ struct in6_addr addr6;
/* First, consistency check. */
err = -EINVAL;
@@ -1577,9 +1579,11 @@ exp_addclient(struct nfsctl_client *ncp)
goto out_unlock;
/* Insert client into hashtable. */
- for (i = 0; i < ncp->cl_naddr; i++)
- auth_unix_add_addr(ncp->cl_addrlist[i], dom);
-
+ for (i = 0; i < ncp->cl_naddr; i++) {
+ /* Mapping address */
+ ipv6_addr_v4map(ncp->cl_addrlist[i], addr6);
+ auth_unix_add_addr(addr6, dom);
+ }
auth_unix_forget_old(dom);
auth_domain_put(dom);
diff -p -u -r -N linux-2.6.23-rc5/fs/nfsd/nfsctl.c linux-2.6.23-rc5-IPv6-ipmap-cache/fs/nfsd/nfsctl.c
--- linux-2.6.23-rc5/fs/nfsd/nfsctl.c 2007-09-04 13:55:02.000000000 +0200
+++ linux-2.6.23-rc5-IPv6-ipmap-cache/fs/nfsd/nfsctl.c 2007-09-06 11:17:00.000000000 +0200
@@ -38,6 +38,7 @@
#include <asm/uaccess.h>
+#include <net/ipv6.h>
/*
* We have a single directory with 9 nodes in it.
*/
@@ -222,7 +223,7 @@ static ssize_t write_getfs(struct file *
struct auth_domain *clp;
int err = 0;
struct knfsd_fh *res;
-
+ struct in6_addr in6;
if (size < sizeof(*data))
return -EINVAL;
data = (struct nfsctl_fsparm*)buf;
@@ -236,7 +237,11 @@ static ssize_t write_getfs(struct file *
res = (struct knfsd_fh*)buf;
exp_readlock();
- if (!(clp = auth_unix_lookup(sin->sin_addr)))
+
+ /* IPv6 address mapping */
+ ipv6_addr_v4map(sin->sin_addr, in6);
+
+ if (!(clp = auth_unix_lookup(in6)))
err = -EPERM;
else {
err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen);
@@ -253,6 +258,7 @@ static ssize_t write_getfd(struct file *
{
struct nfsctl_fdparm *data;
struct sockaddr_in *sin;
+ struct in6_addr in6;
struct auth_domain *clp;
int err = 0;
struct knfsd_fh fh;
@@ -271,7 +277,11 @@ static ssize_t write_getfd(struct file *
res = buf;
sin = (struct sockaddr_in *)&data->gd_addr;
exp_readlock();
- if (!(clp = auth_unix_lookup(sin->sin_addr)))
+
+ /* IPv6 address mapping */
+ ipv6_addr_v4map(sin->sin_addr, in6);
+
+ if (!(clp = auth_unix_lookup(in6)))
err = -EPERM;
else {
err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE);
diff -p -u -r -N linux-2.6.23-rc5/include/linux/sunrpc/svcauth.h linux-2.6.23-rc5-IPv6-ipmap-cache/include/linux/sunrpc/svcauth.h
--- linux-2.6.23-rc5/include/linux/sunrpc/svcauth.h 2007-09-04 13:55:03.000000000 +0200
+++ linux-2.6.23-rc5-IPv6-ipmap-cache/include/linux/sunrpc/svcauth.h 2007-09-04 14:37:21.000000000 +0200
@@ -120,10 +120,10 @@ extern void svc_auth_unregister(rpc_auth
extern struct auth_domain *unix_domain_find(char *name);
extern void auth_domain_put(struct auth_domain *item);
-extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom);
+extern int auth_unix_add_addr(struct in6_addr addr, struct auth_domain *dom);
extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *new);
extern struct auth_domain *auth_domain_find(char *name);
-extern struct auth_domain *auth_unix_lookup(struct in_addr addr);
+extern struct auth_domain *auth_unix_lookup(struct in6_addr addr);
extern int auth_unix_forget_old(struct auth_domain *dom);
extern void svcauth_unix_purge(void);
extern void svcauth_unix_info_release(void *);
diff -p -u -r -N linux-2.6.23-rc5/include/net/ipv6.h linux-2.6.23-rc5-IPv6-ipmap-cache/include/net/ipv6.h
--- linux-2.6.23-rc5/include/net/ipv6.h 2007-09-04 16:32:38.000000000 +0200
+++ linux-2.6.23-rc5-IPv6-ipmap-cache/include/net/ipv6.h 2007-09-05 10:01:51.000000000 +0200
@@ -21,6 +21,7 @@
#include <net/ndisc.h>
#include <net/flow.h>
#include <net/snmp.h>
+#include <linux/in.h>
#define SIN6_LEN_RFC2133 24
@@ -167,6 +168,12 @@ DECLARE_SNMP_STAT(struct udp_mib, udplit
if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field); \
else SNMP_INC_STATS_USER(udp_stats_in6, field); } while(0)
+#define IS_ADDR_MAPPED(a) \
+ (((uint32_t *) (a))[0] == 0 \
+ && ((uint32_t *) (a))[1] == 0 \
+ && (((uint32_t *) (a))[2] == 0 \
+ || ((uint32_t *) (a))[2] == htonl(0xffff)))
+
struct ip6_ra_chain
{
struct ip6_ra_chain *next;
@@ -377,6 +384,14 @@ static inline int ipv6_addr_any(const st
a->s6_addr32[2] | a->s6_addr32[3] ) == 0);
}
+static inline void ipv6_addr_v4map(const struct in_addr a1, struct in6_addr a2)
+{
+ a2.s6_addr32[0] = 0;
+ a2.s6_addr32[1] = 0;
+ a2.s6_addr32[2] = htonl(0xffff);
+ a2.s6_addr32[3] = (uint32_t)a1.s_addr;
+}
+
static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
{
return ((a->s6_addr32[0] | a->s6_addr32[1]) == 0 &&
diff -p -u -r -N linux-2.6.23-rc5/net/sunrpc/svcauth_unix.c linux-2.6.23-rc5-IPv6-ipmap-cache/net/sunrpc/svcauth_unix.c
--- linux-2.6.23-rc5/net/sunrpc/svcauth_unix.c 2007-09-04 13:55:04.000000000 +0200
+++ linux-2.6.23-rc5-IPv6-ipmap-cache/net/sunrpc/svcauth_unix.c 2007-09-06 10:30:19.000000000 +0200
@@ -11,7 +11,8 @@
#include <linux/hash.h>
#include <linux/string.h>
#include <net/sock.h>
-
+#include <net/ipv6.h>
+#include <linux/kernel.h>
#define RPCDBG_FACILITY RPCDBG_AUTH
@@ -84,7 +85,7 @@ static void svcauth_unix_domain_release(
struct ip_map {
struct cache_head h;
char m_class[8]; /* e.g. "nfsd" */
- struct in_addr m_addr;
+ struct in6_addr m_addr;
struct unix_domain *m_client;
int m_add_change;
};
@@ -112,12 +113,19 @@ static inline int hash_ip(__be32 ip)
return (hash ^ (hash>>8)) & 0xff;
}
#endif
+static inline int hash_ip6(struct in6_addr ip)
+{
+ return (hash_ip(ip.s6_addr32[0]) ^
+ hash_ip(ip.s6_addr32[1]) ^
+ hash_ip(ip.s6_addr32[2]) ^
+ hash_ip(ip.s6_addr32[3]));
+}
static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
{
struct ip_map *orig = container_of(corig, struct ip_map, h);
struct ip_map *new = container_of(cnew, struct ip_map, h);
return strcmp(orig->m_class, new->m_class) == 0
- && orig->m_addr.s_addr == new->m_addr.s_addr;
+ && ipv6_addr_equal(&orig->m_addr, &new->m_addr);
}
static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
{
@@ -125,7 +133,7 @@ static void ip_map_init(struct cache_hea
struct ip_map *item = container_of(citem, struct ip_map, h);
strcpy(new->m_class, item->m_class);
- new->m_addr.s_addr = item->m_addr.s_addr;
+ ipv6_addr_copy(&(new->m_addr), &(item->m_addr));
}
static void update(struct cache_head *cnew, struct cache_head *citem)
{
@@ -151,20 +159,22 @@ static void ip_map_request(struct cache_
{
char text_addr[20];
struct ip_map *im = container_of(h, struct ip_map, h);
- __be32 addr = im->m_addr.s_addr;
-
- snprintf(text_addr, 20, "%u.%u.%u.%u",
- ntohl(addr) >> 24 & 0xff,
- ntohl(addr) >> 16 & 0xff,
- ntohl(addr) >> 8 & 0xff,
- ntohl(addr) >> 0 & 0xff);
+ if (ipv6_addr_v4mapped(&(im->m_addr))) {
+ snprintf(text_addr, 20, NIPQUAD_FMT,
+ ntohl(im->m_addr.s6_addr32[3]) >> 24 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 16 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 8 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 0 & 0xff);
+ } else {
+ snprintf(text_addr, 40, NIP6_FMT, NIP6(im->m_addr));
+ }
qword_add(bpp, blen, im->m_class);
qword_add(bpp, blen, text_addr);
(*bpp)[-1] = '\n';
}
-static struct ip_map *ip_map_lookup(char *class, struct in_addr addr);
+static struct ip_map *ip_map_lookup(char *class, struct in6_addr addr);
static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
static int ip_map_parse(struct cache_detail *cd,
@@ -175,10 +185,10 @@ static int ip_map_parse(struct cache_det
* for scratch: */
char *buf = mesg;
int len;
- int b1,b2,b3,b4;
+ int b1, b2, b3, b4, b5, b6, b7, b8;
char c;
char class[8];
- struct in_addr addr;
+ struct in6_addr addr;
int err;
struct ip_map *ipmp;
@@ -197,9 +207,26 @@ static int ip_map_parse(struct cache_det
len = qword_get(&mesg, buf, mlen);
if (len <= 0) return -EINVAL;
- if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4)
+ if (sscanf(buf, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) == 4) {
+ addr.s6_addr32[0] = 0;
+ addr.s6_addr32[1] = 0;
+ addr.s6_addr32[2] = htonl(0xffff);
+ addr.s6_addr32[3] =
+ htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
+ } else if (sscanf(buf, NIP6_FMT "%c",
+ &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) {
+ addr.s6_addr16[0] = htons(b1);
+ addr.s6_addr16[1] = htons(b2);
+ addr.s6_addr16[2] = htons(b3);
+ addr.s6_addr16[3] = htons(b4);
+ addr.s6_addr16[4] = htons(b5);
+ addr.s6_addr16[5] = htons(b6);
+ addr.s6_addr16[6] = htons(b7);
+ addr.s6_addr16[7] = htons(b8);
+ } else
return -EINVAL;
+
expiry = get_expiry(&mesg);
if (expiry ==0)
return -EINVAL;
@@ -215,9 +242,6 @@ static int ip_map_parse(struct cache_det
} else
dom = NULL;
- addr.s_addr =
- htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
-
ipmp = ip_map_lookup(class,addr);
if (ipmp) {
err = ip_map_update(ipmp,
@@ -238,7 +262,7 @@ static int ip_map_show(struct seq_file *
struct cache_head *h)
{
struct ip_map *im;
- struct in_addr addr;
+ struct in6_addr addr;
char *dom = "-no-domain-";
if (h == NULL) {
@@ -247,20 +271,24 @@ static int ip_map_show(struct seq_file *
}
im = container_of(h, struct ip_map, h);
/* class addr domain */
- addr = im->m_addr;
+ ipv6_addr_copy(&addr, &im->m_addr);
if (test_bit(CACHE_VALID, &h->flags) &&
!test_bit(CACHE_NEGATIVE, &h->flags))
dom = im->m_client->h.name;
- seq_printf(m, "%s %d.%d.%d.%d %s\n",
- im->m_class,
- ntohl(addr.s_addr) >> 24 & 0xff,
- ntohl(addr.s_addr) >> 16 & 0xff,
- ntohl(addr.s_addr) >> 8 & 0xff,
- ntohl(addr.s_addr) >> 0 & 0xff,
- dom
- );
+ if (ipv6_addr_v4mapped(&addr)) {
+ seq_printf(m, "%s" NIPQUAD_FMT "%s\n",
+ im->m_class,
+ ntohl(addr.s6_addr32[3]) >> 24 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 16 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 8 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 0 & 0xff,
+ dom);
+ } else {
+ seq_printf(m, "%s" NIP6_FMT "%s\n",
+ im->m_class, NIP6(addr), dom);
+ }
return 0;
}
@@ -280,16 +308,16 @@ struct cache_detail ip_map_cache = {
.alloc = ip_map_alloc,
};
-static struct ip_map *ip_map_lookup(char *class, struct in_addr addr)
+static struct ip_map *ip_map_lookup(char *class, struct in6_addr addr)
{
struct ip_map ip;
struct cache_head *ch;
strcpy(ip.m_class, class);
- ip.m_addr = addr;
+ ipv6_addr_copy(&ip.m_addr, &addr);
ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h,
hash_str(class, IP_HASHBITS) ^
- hash_ip(addr.s_addr));
+ hash_ip6(addr));
if (ch)
return container_of(ch, struct ip_map, h);
@@ -318,14 +346,14 @@ static int ip_map_update(struct ip_map *
ch = sunrpc_cache_update(&ip_map_cache,
&ip.h, &ipm->h,
hash_str(ipm->m_class, IP_HASHBITS) ^
- hash_ip(ipm->m_addr.s_addr));
+ hash_ip6(ipm->m_addr));
if (!ch)
return -ENOMEM;
cache_put(ch, &ip_map_cache);
return 0;
}
-int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
+int auth_unix_add_addr(struct in6_addr addr, struct auth_domain *dom)
{
struct unix_domain *udom;
struct ip_map *ipmp;
@@ -352,7 +380,7 @@ int auth_unix_forget_old(struct auth_dom
return 0;
}
-struct auth_domain *auth_unix_lookup(struct in_addr addr)
+struct auth_domain *auth_unix_lookup(struct in6_addr addr)
{
struct ip_map *ipm;
struct auth_domain *rv;
@@ -641,7 +669,19 @@ static int unix_gid_find(uid_t uid, stru
int
svcauth_unix_set_client(struct svc_rqst *rqstp)
{
- struct sockaddr_in *sin = svc_addr_in(rqstp);
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ switch (rqstp->rq_addr.ss_family) {
+ default:
+ BUG();
+ case AF_INET:
+ sin = svc_addr_in(rqstp);
+ ipv6_addr_v4map(sin->sin_addr, sin6->sin6_addr);
+ case AF_INET6:
+ sin6 = svc_addr_in6(rqstp);
+ }
+
struct ip_map *ipm;
rqstp->rq_client = NULL;
@@ -651,7 +691,7 @@ svcauth_unix_set_client(struct svc_rqst
ipm = ip_map_cached_get(rqstp);
if (ipm == NULL)
ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
- sin->sin_addr);
+ sin6->sin6_addr);
if (ipm == NULL)
return SVC_DENIED;
--
********************************
Aurelien Charbon
Linux NFSv4 team
Bull SAS
Echirolles - France
http://nfsv4.bullopensource.org/
********************************
[-- Attachment #2: linux-2.6.23-rc5-IPv6-ipmap-cache.diff --]
[-- Type: text/x-patch, Size: 12899 bytes --]
This is a small part of missing pieces of IPv6 support for the server.
It deals with the ip_map caching code part.
It changes the ip_map structure to be able to store INET6 addresses.
It adds also the changes in address hashing, and mapping to test it with INET addresses.
Signed-off-by: Aurelien Charbon <aurelien.charbon@ext.bull.net>
---
diff -p -u -r -N linux-2.6.23-rc5/fs/nfsd/export.c linux-2.6.23-rc5-IPv6-ipmap-cache/fs/nfsd/export.c
--- linux-2.6.23-rc5/fs/nfsd/export.c 2007-09-04 13:55:02.000000000 +0200
+++ linux-2.6.23-rc5-IPv6-ipmap-cache/fs/nfsd/export.c 2007-09-04 17:05:47.000000000 +0200
@@ -35,6 +35,7 @@
#include <linux/lockd/bind.h>
#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/gss_api.h>
+#include <net/ipv6.h>
#define NFSDDBG_FACILITY NFSDDBG_EXPORT
@@ -1559,6 +1560,7 @@ exp_addclient(struct nfsctl_client *ncp)
{
struct auth_domain *dom;
int i, err;
+ struct in6_addr addr6;
/* First, consistency check. */
err = -EINVAL;
@@ -1577,9 +1579,11 @@ exp_addclient(struct nfsctl_client *ncp)
goto out_unlock;
/* Insert client into hashtable. */
- for (i = 0; i < ncp->cl_naddr; i++)
- auth_unix_add_addr(ncp->cl_addrlist[i], dom);
-
+ for (i = 0; i < ncp->cl_naddr; i++) {
+ /* Mapping address */
+ ipv6_addr_v4map(ncp->cl_addrlist[i], addr6);
+ auth_unix_add_addr(addr6, dom);
+ }
auth_unix_forget_old(dom);
auth_domain_put(dom);
diff -p -u -r -N linux-2.6.23-rc5/fs/nfsd/nfsctl.c linux-2.6.23-rc5-IPv6-ipmap-cache/fs/nfsd/nfsctl.c
--- linux-2.6.23-rc5/fs/nfsd/nfsctl.c 2007-09-04 13:55:02.000000000 +0200
+++ linux-2.6.23-rc5-IPv6-ipmap-cache/fs/nfsd/nfsctl.c 2007-09-06 11:17:00.000000000 +0200
@@ -38,6 +38,7 @@
#include <asm/uaccess.h>
+#include <net/ipv6.h>
/*
* We have a single directory with 9 nodes in it.
*/
@@ -222,7 +223,7 @@ static ssize_t write_getfs(struct file *
struct auth_domain *clp;
int err = 0;
struct knfsd_fh *res;
-
+ struct in6_addr in6;
if (size < sizeof(*data))
return -EINVAL;
data = (struct nfsctl_fsparm*)buf;
@@ -236,7 +237,11 @@ static ssize_t write_getfs(struct file *
res = (struct knfsd_fh*)buf;
exp_readlock();
- if (!(clp = auth_unix_lookup(sin->sin_addr)))
+
+ /* IPv6 address mapping */
+ ipv6_addr_v4map(sin->sin_addr, in6);
+
+ if (!(clp = auth_unix_lookup(in6)))
err = -EPERM;
else {
err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen);
@@ -253,6 +258,7 @@ static ssize_t write_getfd(struct file *
{
struct nfsctl_fdparm *data;
struct sockaddr_in *sin;
+ struct in6_addr in6;
struct auth_domain *clp;
int err = 0;
struct knfsd_fh fh;
@@ -271,7 +277,11 @@ static ssize_t write_getfd(struct file *
res = buf;
sin = (struct sockaddr_in *)&data->gd_addr;
exp_readlock();
- if (!(clp = auth_unix_lookup(sin->sin_addr)))
+
+ /* IPv6 address mapping */
+ ipv6_addr_v4map(sin->sin_addr, in6);
+
+ if (!(clp = auth_unix_lookup(in6)))
err = -EPERM;
else {
err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE);
diff -p -u -r -N linux-2.6.23-rc5/include/linux/sunrpc/svcauth.h linux-2.6.23-rc5-IPv6-ipmap-cache/include/linux/sunrpc/svcauth.h
--- linux-2.6.23-rc5/include/linux/sunrpc/svcauth.h 2007-09-04 13:55:03.000000000 +0200
+++ linux-2.6.23-rc5-IPv6-ipmap-cache/include/linux/sunrpc/svcauth.h 2007-09-04 14:37:21.000000000 +0200
@@ -120,10 +120,10 @@ extern void svc_auth_unregister(rpc_auth
extern struct auth_domain *unix_domain_find(char *name);
extern void auth_domain_put(struct auth_domain *item);
-extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom);
+extern int auth_unix_add_addr(struct in6_addr addr, struct auth_domain *dom);
extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *new);
extern struct auth_domain *auth_domain_find(char *name);
-extern struct auth_domain *auth_unix_lookup(struct in_addr addr);
+extern struct auth_domain *auth_unix_lookup(struct in6_addr addr);
extern int auth_unix_forget_old(struct auth_domain *dom);
extern void svcauth_unix_purge(void);
extern void svcauth_unix_info_release(void *);
diff -p -u -r -N linux-2.6.23-rc5/include/net/ipv6.h linux-2.6.23-rc5-IPv6-ipmap-cache/include/net/ipv6.h
--- linux-2.6.23-rc5/include/net/ipv6.h 2007-09-04 16:32:38.000000000 +0200
+++ linux-2.6.23-rc5-IPv6-ipmap-cache/include/net/ipv6.h 2007-09-05 10:01:51.000000000 +0200
@@ -21,6 +21,7 @@
#include <net/ndisc.h>
#include <net/flow.h>
#include <net/snmp.h>
+#include <linux/in.h>
#define SIN6_LEN_RFC2133 24
@@ -167,6 +168,12 @@ DECLARE_SNMP_STAT(struct udp_mib, udplit
if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field); \
else SNMP_INC_STATS_USER(udp_stats_in6, field); } while(0)
+#define IS_ADDR_MAPPED(a) \
+ (((uint32_t *) (a))[0] == 0 \
+ && ((uint32_t *) (a))[1] == 0 \
+ && (((uint32_t *) (a))[2] == 0 \
+ || ((uint32_t *) (a))[2] == htonl(0xffff)))
+
struct ip6_ra_chain
{
struct ip6_ra_chain *next;
@@ -377,6 +384,14 @@ static inline int ipv6_addr_any(const st
a->s6_addr32[2] | a->s6_addr32[3] ) == 0);
}
+static inline void ipv6_addr_v4map(const struct in_addr a1, struct in6_addr a2)
+{
+ a2.s6_addr32[0] = 0;
+ a2.s6_addr32[1] = 0;
+ a2.s6_addr32[2] = htonl(0xffff);
+ a2.s6_addr32[3] = (uint32_t)a1.s_addr;
+}
+
static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
{
return ((a->s6_addr32[0] | a->s6_addr32[1]) == 0 &&
diff -p -u -r -N linux-2.6.23-rc5/net/sunrpc/svcauth_unix.c linux-2.6.23-rc5-IPv6-ipmap-cache/net/sunrpc/svcauth_unix.c
--- linux-2.6.23-rc5/net/sunrpc/svcauth_unix.c 2007-09-04 13:55:04.000000000 +0200
+++ linux-2.6.23-rc5-IPv6-ipmap-cache/net/sunrpc/svcauth_unix.c 2007-09-06 10:30:19.000000000 +0200
@@ -11,7 +11,8 @@
#include <linux/hash.h>
#include <linux/string.h>
#include <net/sock.h>
-
+#include <net/ipv6.h>
+#include <linux/kernel.h>
#define RPCDBG_FACILITY RPCDBG_AUTH
@@ -84,7 +85,7 @@ static void svcauth_unix_domain_release(
struct ip_map {
struct cache_head h;
char m_class[8]; /* e.g. "nfsd" */
- struct in_addr m_addr;
+ struct in6_addr m_addr;
struct unix_domain *m_client;
int m_add_change;
};
@@ -112,12 +113,19 @@ static inline int hash_ip(__be32 ip)
return (hash ^ (hash>>8)) & 0xff;
}
#endif
+static inline int hash_ip6(struct in6_addr ip)
+{
+ return (hash_ip(ip.s6_addr32[0]) ^
+ hash_ip(ip.s6_addr32[1]) ^
+ hash_ip(ip.s6_addr32[2]) ^
+ hash_ip(ip.s6_addr32[3]));
+}
static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
{
struct ip_map *orig = container_of(corig, struct ip_map, h);
struct ip_map *new = container_of(cnew, struct ip_map, h);
return strcmp(orig->m_class, new->m_class) == 0
- && orig->m_addr.s_addr == new->m_addr.s_addr;
+ && ipv6_addr_equal(&orig->m_addr, &new->m_addr);
}
static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
{
@@ -125,7 +133,7 @@ static void ip_map_init(struct cache_hea
struct ip_map *item = container_of(citem, struct ip_map, h);
strcpy(new->m_class, item->m_class);
- new->m_addr.s_addr = item->m_addr.s_addr;
+ ipv6_addr_copy(&(new->m_addr), &(item->m_addr));
}
static void update(struct cache_head *cnew, struct cache_head *citem)
{
@@ -151,20 +159,22 @@ static void ip_map_request(struct cache_
{
char text_addr[20];
struct ip_map *im = container_of(h, struct ip_map, h);
- __be32 addr = im->m_addr.s_addr;
-
- snprintf(text_addr, 20, "%u.%u.%u.%u",
- ntohl(addr) >> 24 & 0xff,
- ntohl(addr) >> 16 & 0xff,
- ntohl(addr) >> 8 & 0xff,
- ntohl(addr) >> 0 & 0xff);
+ if (ipv6_addr_v4mapped(&(im->m_addr))) {
+ snprintf(text_addr, 20, NIPQUAD_FMT,
+ ntohl(im->m_addr.s6_addr32[3]) >> 24 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 16 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 8 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 0 & 0xff);
+ } else {
+ snprintf(text_addr, 40, NIP6_FMT, NIP6(im->m_addr));
+ }
qword_add(bpp, blen, im->m_class);
qword_add(bpp, blen, text_addr);
(*bpp)[-1] = '\n';
}
-static struct ip_map *ip_map_lookup(char *class, struct in_addr addr);
+static struct ip_map *ip_map_lookup(char *class, struct in6_addr addr);
static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
static int ip_map_parse(struct cache_detail *cd,
@@ -175,10 +185,10 @@ static int ip_map_parse(struct cache_det
* for scratch: */
char *buf = mesg;
int len;
- int b1,b2,b3,b4;
+ int b1, b2, b3, b4, b5, b6, b7, b8;
char c;
char class[8];
- struct in_addr addr;
+ struct in6_addr addr;
int err;
struct ip_map *ipmp;
@@ -197,9 +207,26 @@ static int ip_map_parse(struct cache_det
len = qword_get(&mesg, buf, mlen);
if (len <= 0) return -EINVAL;
- if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4)
+ if (sscanf(buf, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) == 4) {
+ addr.s6_addr32[0] = 0;
+ addr.s6_addr32[1] = 0;
+ addr.s6_addr32[2] = htonl(0xffff);
+ addr.s6_addr32[3] =
+ htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
+ } else if (sscanf(buf, NIP6_FMT "%c",
+ &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) {
+ addr.s6_addr16[0] = htons(b1);
+ addr.s6_addr16[1] = htons(b2);
+ addr.s6_addr16[2] = htons(b3);
+ addr.s6_addr16[3] = htons(b4);
+ addr.s6_addr16[4] = htons(b5);
+ addr.s6_addr16[5] = htons(b6);
+ addr.s6_addr16[6] = htons(b7);
+ addr.s6_addr16[7] = htons(b8);
+ } else
return -EINVAL;
+
expiry = get_expiry(&mesg);
if (expiry ==0)
return -EINVAL;
@@ -215,9 +242,6 @@ static int ip_map_parse(struct cache_det
} else
dom = NULL;
- addr.s_addr =
- htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
-
ipmp = ip_map_lookup(class,addr);
if (ipmp) {
err = ip_map_update(ipmp,
@@ -238,7 +262,7 @@ static int ip_map_show(struct seq_file *
struct cache_head *h)
{
struct ip_map *im;
- struct in_addr addr;
+ struct in6_addr addr;
char *dom = "-no-domain-";
if (h == NULL) {
@@ -247,20 +271,24 @@ static int ip_map_show(struct seq_file *
}
im = container_of(h, struct ip_map, h);
/* class addr domain */
- addr = im->m_addr;
+ ipv6_addr_copy(&addr, &im->m_addr);
if (test_bit(CACHE_VALID, &h->flags) &&
!test_bit(CACHE_NEGATIVE, &h->flags))
dom = im->m_client->h.name;
- seq_printf(m, "%s %d.%d.%d.%d %s\n",
- im->m_class,
- ntohl(addr.s_addr) >> 24 & 0xff,
- ntohl(addr.s_addr) >> 16 & 0xff,
- ntohl(addr.s_addr) >> 8 & 0xff,
- ntohl(addr.s_addr) >> 0 & 0xff,
- dom
- );
+ if (ipv6_addr_v4mapped(&addr)) {
+ seq_printf(m, "%s" NIPQUAD_FMT "%s\n",
+ im->m_class,
+ ntohl(addr.s6_addr32[3]) >> 24 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 16 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 8 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 0 & 0xff,
+ dom);
+ } else {
+ seq_printf(m, "%s" NIP6_FMT "%s\n",
+ im->m_class, NIP6(addr), dom);
+ }
return 0;
}
@@ -280,16 +308,16 @@ struct cache_detail ip_map_cache = {
.alloc = ip_map_alloc,
};
-static struct ip_map *ip_map_lookup(char *class, struct in_addr addr)
+static struct ip_map *ip_map_lookup(char *class, struct in6_addr addr)
{
struct ip_map ip;
struct cache_head *ch;
strcpy(ip.m_class, class);
- ip.m_addr = addr;
+ ipv6_addr_copy(&ip.m_addr, &addr);
ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h,
hash_str(class, IP_HASHBITS) ^
- hash_ip(addr.s_addr));
+ hash_ip6(addr));
if (ch)
return container_of(ch, struct ip_map, h);
@@ -318,14 +346,14 @@ static int ip_map_update(struct ip_map *
ch = sunrpc_cache_update(&ip_map_cache,
&ip.h, &ipm->h,
hash_str(ipm->m_class, IP_HASHBITS) ^
- hash_ip(ipm->m_addr.s_addr));
+ hash_ip6(ipm->m_addr));
if (!ch)
return -ENOMEM;
cache_put(ch, &ip_map_cache);
return 0;
}
-int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
+int auth_unix_add_addr(struct in6_addr addr, struct auth_domain *dom)
{
struct unix_domain *udom;
struct ip_map *ipmp;
@@ -352,7 +380,7 @@ int auth_unix_forget_old(struct auth_dom
return 0;
}
-struct auth_domain *auth_unix_lookup(struct in_addr addr)
+struct auth_domain *auth_unix_lookup(struct in6_addr addr)
{
struct ip_map *ipm;
struct auth_domain *rv;
@@ -641,7 +669,19 @@ static int unix_gid_find(uid_t uid, stru
int
svcauth_unix_set_client(struct svc_rqst *rqstp)
{
- struct sockaddr_in *sin = svc_addr_in(rqstp);
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ switch (rqstp->rq_addr.ss_family) {
+ default:
+ BUG();
+ case AF_INET:
+ sin = svc_addr_in(rqstp);
+ ipv6_addr_v4map(sin->sin_addr, sin6->sin6_addr);
+ case AF_INET6:
+ sin6 = svc_addr_in6(rqstp);
+ }
+
struct ip_map *ipm;
rqstp->rq_client = NULL;
@@ -651,7 +691,7 @@ svcauth_unix_set_client(struct svc_rqst
ipm = ip_map_cached_get(rqstp);
if (ipm == NULL)
ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
- sin->sin_addr);
+ sin6->sin6_addr);
if (ipm == NULL)
return SVC_DENIED;
^ permalink raw reply
* Re: [TG3]: Workaround MSI bug on 5714/5780.
From: David Miller @ 2007-09-06 11:02 UTC (permalink / raw)
To: mchan; +Cc: netdev, andy
In-Reply-To: <1189022828.4960.2.camel@dell>
From: "Michael Chan" <mchan@broadcom.com>
Date: Wed, 05 Sep 2007 13:07:08 -0700
> [TG3]: Workaround MSI bug on 5714/5780.
>
> A hardware bug was revealed after a recent PCI MSI patch was made to
> always disable legacy INTX when enabling MSI. The 5714/5780 chips
> will not generate MSI when INTX is disabled, causing MSI failure
> messages to be reported, and another patch was made to workaround the
> problem by disabling MSI on ServerWorks HT1000 bridge chips commonly
> found with the 5714.
>
> We workaround this chip bug by enabling INTX after we enable MSI and
> after we resume from suspend.
>
> Update version to 3.81.
>
> This problem was discovered by David Miller.
>
> Signed-off-by: Michael Chan <mchan@broadcom.com>
Thanks a lot Michael, I'll apply this and work on reverting that
incorrect MSI chipset quirk too.
^ permalink raw reply
* net-2.6.24 rebased
From: David Miller @ 2007-09-06 10:57 UTC (permalink / raw)
To: netdev
Upstream got a backport of my netdev->priv fixes for the
cxgb3 driver, creating a bunch of conflicts with the napi_struct
changes, so I took the opportunity to refresh the tree and
combine some bug fixes into the changes that introduced those
bugs :-) (bug fix attributions were added to the changelogs
as needed)
kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.24.git
I've tried to sanity check this rebase as best as possible
but mistakes are always possible especially since I'm doing
this from the kernel summit in Cambridge :-)
I've kept the previous tree around as "bak-net-2.6.24.git"
so it can be referenced for researching potential mistakes.
Enjoy!
^ permalink raw reply
* [PATCH 2.6.24 5/5]S2io: code Optimization of isr function
From: Sivakumar Subramani @ 2007-09-06 10:53 UTC (permalink / raw)
To: netdev, jeff; +Cc: support
- Code Optimization of s2io_isr function.
- Isr check using per device napi variable instead of driver global.
- Reduced from 3 to 1 if condition before check for processing packet receive
packets.
- Implemented Jeff's comment to use synchronize_irq. Removed the isr_cnt
variable as it became redundant.
- One time de assert the interrupts by writing all F's to the general_int_mask
register instead of de asserting by clearing the source of interrupts with
multiple writes which causes loss of interrupts (race conditions). It is
entirely possible that before the driver has a chance to mask the asserted
alarm bit, another alarm/traffic interrupt bit gets asserted as well. In
this case Herc will keep the INTA line asserted and the bridge will not
send a new Assert_INTA message upstream.
Signed-off-by: Sivakumar Subramani <sivakumar.subramani@neterion.com>
Signed-off-by: Santosh Rastapur <santosh.rastapur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
---
diff -Nurp 2.0.26.2-4/drivers/net/s2io.c 2.0.26.2-5/drivers/net/s2io.c
--- 2.0.26.2-4/drivers/net/s2io.c 2007-09-05 09:24:07.000000000 -0700
+++ 2.0.26.2-5/drivers/net/s2io.c 2007-09-05 10:14:38.000000000 -0700
@@ -84,7 +84,7 @@
#include "s2io.h"
#include "s2io-regs.h"
-#define DRV_VERSION "2.0.26.1"
+#define DRV_VERSION "2.0.26.2"
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
@@ -2714,12 +2714,8 @@ static int s2io_poll(struct net_device *
struct XENA_dev_config __iomem *bar0 = nic->bar0;
int i;
- atomic_inc(&nic->isr_cnt);
-
- if (!is_s2io_card_up(nic)) {
- atomic_dec(&nic->isr_cnt);
+ if (!is_s2io_card_up(nic))
return 0;
- }
mac_control = &nic->mac_control;
config = &nic->config;
@@ -2757,7 +2753,6 @@ static int s2io_poll(struct net_device *
/* Re enable the Rx interrupts. */
writeq(0x0, &bar0->rx_traffic_mask);
readl(&bar0->rx_traffic_mask);
- atomic_dec(&nic->isr_cnt);
return 0;
no_rx:
@@ -2771,7 +2766,6 @@ no_rx:
break;
}
}
- atomic_dec(&nic->isr_cnt);
return 1;
}
@@ -2799,7 +2793,6 @@ static void s2io_netpoll(struct net_devi
disable_irq(dev->irq);
- atomic_inc(&nic->isr_cnt);
mac_control = &nic->mac_control;
config = &nic->config;
@@ -2824,7 +2817,6 @@ static void s2io_netpoll(struct net_devi
break;
}
}
- atomic_dec(&nic->isr_cnt);
enable_irq(dev->irq);
return;
}
@@ -4191,17 +4183,12 @@ static irqreturn_t s2io_msix_ring_handle
struct ring_info *ring = (struct ring_info *)dev_id;
struct s2io_nic *sp = ring->nic;
- atomic_inc(&sp->isr_cnt);
-
- if (!is_s2io_card_up(sp)) {
- atomic_dec(&sp->isr_cnt);
+ if (!is_s2io_card_up(sp))
return IRQ_HANDLED;
- }
rx_intr_handler(ring);
s2io_chk_rx_buffers(sp, ring->ring_no);
- atomic_dec(&sp->isr_cnt);
return IRQ_HANDLED;
}
@@ -4210,15 +4197,10 @@ static irqreturn_t s2io_msix_fifo_handle
struct fifo_info *fifo = (struct fifo_info *)dev_id;
struct s2io_nic *sp = fifo->nic;
- atomic_inc(&sp->isr_cnt);
-
- if (!is_s2io_card_up(sp)) {
- atomic_dec(&sp->isr_cnt);
+ if (!is_s2io_card_up(sp))
return IRQ_HANDLED;
- }
tx_intr_handler(fifo);
- atomic_dec(&sp->isr_cnt);
return IRQ_HANDLED;
}
static void s2io_txpic_intr_handle(struct s2io_nic *sp)
@@ -4594,12 +4576,8 @@ static irqreturn_t s2io_isr(int irq, voi
if (pci_channel_offline(sp->pdev))
return IRQ_NONE;
- atomic_inc(&sp->isr_cnt);
-
- if (!is_s2io_card_up(sp)) {
- atomic_dec(&sp->isr_cnt);
+ if (!is_s2io_card_up(sp))
return IRQ_NONE;
- }
mac_control = &sp->mac_control;
config = &sp->config;
@@ -4610,73 +4588,74 @@ static irqreturn_t s2io_isr(int irq, voi
* 1. Rx of packet.
* 2. Tx complete.
* 3. Link down.
- * 4. Error in any functional blocks of the NIC.
*/
reason = readq(&bar0->general_int_status);
- if (!reason) {
- /* The interrupt was not raised by us. */
- atomic_dec(&sp->isr_cnt);
- return IRQ_NONE;
- }
- else if (unlikely(reason == S2IO_MINUS_ONE) ) {
- /* Disable device and get out */
- atomic_dec(&sp->isr_cnt);
- return IRQ_NONE;
+ if (unlikely(reason == S2IO_MINUS_ONE) ) {
+ /* Nothing much can be done. Get out */
+ return IRQ_HANDLED;
}
- if (napi) {
- if (reason & GEN_INTR_RXTRAFFIC) {
- if ( likely ( netif_rx_schedule_prep(dev)) ) {
- __netif_rx_schedule(dev);
- writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask);
+ if (reason & (GEN_INTR_RXTRAFFIC |
+ GEN_INTR_TXTRAFFIC | GEN_INTR_TXPIC))
+ {
+ writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
+
+ if (config->napi) {
+ if (reason & GEN_INTR_RXTRAFFIC) {
+ if ( likely (netif_rx_schedule_prep(dev)) ) {
+ __netif_rx_schedule(dev);
+ writeq(S2IO_MINUS_ONE,
+ &bar0->rx_traffic_mask);
+ } else
+ writeq(S2IO_MINUS_ONE,
+ &bar0->rx_traffic_int);
}
- else
+ } else {
+ /*
+ * rx_traffic_int reg is an R1 register, writing all 1's
+ * will ensure that the actual interrupt causing bit
+ * get's cleared and hence a read can be avoided.
+ */
+ if (reason & GEN_INTR_RXTRAFFIC)
writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
+
+ for (i = 0; i < config->rx_ring_num; i++)
+ rx_intr_handler(&mac_control->rings[i]);
}
- } else {
+
/*
- * Rx handler is called by default, without checking for the
- * cause of interrupt.
- * rx_traffic_int reg is an R1 register, writing all 1's
+ * tx_traffic_int reg is an R1 register, writing all 1's
* will ensure that the actual interrupt causing bit get's
* cleared and hence a read can be avoided.
*/
- if (reason & GEN_INTR_RXTRAFFIC)
- writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
+ if (reason & GEN_INTR_TXTRAFFIC)
+ writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
- for (i = 0; i < config->rx_ring_num; i++) {
- rx_intr_handler(&mac_control->rings[i]);
- }
- }
+ for (i = 0; i < config->tx_fifo_num; i++)
+ tx_intr_handler(&mac_control->fifos[i]);
- /*
- * tx_traffic_int reg is an R1 register, writing all 1's
- * will ensure that the actual interrupt causing bit get's
- * cleared and hence a read can be avoided.
- */
- if (reason & GEN_INTR_TXTRAFFIC)
- writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
+ if (reason & GEN_INTR_TXPIC)
+ s2io_txpic_intr_handle(sp);
- for (i = 0; i < config->tx_fifo_num; i++)
- tx_intr_handler(&mac_control->fifos[i]);
+ /*
+ * Reallocate the buffers from the interrupt handler itself.
+ */
+ if (!config->napi) {
+ for (i = 0; i < config->rx_ring_num; i++)
+ s2io_chk_rx_buffers(sp, i);
+ }
+ writeq(sp->general_int_mask, &bar0->general_int_mask);
+ readl(&bar0->general_int_status);
- if (reason & GEN_INTR_TXPIC)
- s2io_txpic_intr_handle(sp);
- /*
- * If the Rx buffer count is below the panic threshold then
- * reallocate the buffers from the interrupt handler itself,
- * else schedule a tasklet to reallocate the buffers.
- */
- if (!napi) {
- for (i = 0; i < config->rx_ring_num; i++)
- s2io_chk_rx_buffers(sp, i);
- }
+ return IRQ_HANDLED;
- writeq(0, &bar0->general_int_mask);
- readl(&bar0->general_int_status);
+ }
+ else if (!reason) {
+ /* The interrupt was not raised by us */
+ return IRQ_NONE;
+ }
- atomic_dec(&sp->isr_cnt);
return IRQ_HANDLED;
}
@@ -6798,7 +6777,6 @@ static int s2io_add_isr(struct s2io_nic
}
static void s2io_rem_isr(struct s2io_nic * sp)
{
- int cnt = 0;
struct net_device *dev = sp->dev;
struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
@@ -6811,6 +6789,7 @@ static void s2io_rem_isr(struct s2io_nic
int vector = sp->entries[i].vector;
void *arg = sp->s2io_entries[i].arg;
+ synchronize_irq(vector);
free_irq(vector, arg);
}
@@ -6829,16 +6808,9 @@ static void s2io_rem_isr(struct s2io_nic
pci_disable_msix(sp->pdev);
} else {
+ synchronize_irq(sp->pdev->irq);
free_irq(sp->pdev->irq, dev);
}
- /* Waiting till all Interrupt handlers are complete */
- cnt = 0;
- do {
- msleep(10);
- if (!atomic_read(&sp->isr_cnt))
- break;
- cnt++;
- } while(cnt < 5);
}
static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
@@ -7368,19 +7340,12 @@ static int s2io_verify_parm(struct pci_d
if (*dev_intr_type != INTA)
napi = 0;
-#ifndef CONFIG_PCI_MSI
- if (*dev_intr_type != INTA) {
- DBG_PRINT(ERR_DBG, "s2io: This kernel does not support"
- "MSI/MSI-X. Defaulting to INTA\n");
- *dev_intr_type = INTA;
- }
-#else
if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) {
DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. "
"Defaulting to INTA\n");
*dev_intr_type = INTA;
}
-#endif
+
if ((*dev_intr_type == MSI_X) &&
((pdev->device != PCI_DEVICE_ID_HERC_WIN) &&
(pdev->device != PCI_DEVICE_ID_HERC_UNI))) {
@@ -7538,6 +7503,8 @@ s2io_init_nic(struct pci_dev *pdev, cons
mac_control = &sp->mac_control;
config = &sp->config;
+ config->napi = napi;
+
/* Tx side parameters. */
config->tx_fifo_num = tx_fifo_num;
for (i = 0; i < MAX_TX_FIFOS; i++) {
@@ -7585,9 +7552,6 @@ s2io_init_nic(struct pci_dev *pdev, cons
for (i = 0; i < config->rx_ring_num; i++)
atomic_set(&sp->rx_bufs_left[i], 0);
- /* Initialize the number of ISRs currently running */
- atomic_set(&sp->isr_cnt, 0);
-
/* initialize the shared memory used by the NIC and the host */
if (init_shared_mem(sp)) {
DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n",
diff -Nurp 2.0.26.2-4/drivers/net/s2io.h 2.0.26.2-5/drivers/net/s2io.h
--- 2.0.26.2-4/drivers/net/s2io.h 2007-09-05 09:24:10.000000000 -0700
+++ 2.0.26.2-5/drivers/net/s2io.h 2007-09-05 09:31:30.000000000 -0700
@@ -910,7 +910,6 @@ struct s2io_nic {
u16 lro_max_aggr_per_sess;
volatile unsigned long state;
spinlock_t rx_lock;
- atomic_t isr_cnt;
u64 general_int_mask;
u64 *ufo_in_band_v;
#define VPD_STRING_LEN 80
^ permalink raw reply
* [PATCH 2.6.24 4/5]S2io: Check for device state before handling traffic
From: Sivakumar Subramani @ 2007-09-06 10:51 UTC (permalink / raw)
To: netdev, jeff; +Cc: support
- Added check to return from the traffic handling function, if the card status
is DOWN.
- Implemented Jeff's comments on incorrect return value in s2io_poll function.
Signed-off-by: Sivakumar Subramani <sivakumar.subramani@neterion.com>
Signed-off-by: Santosh Rastapur <santosh.rastapur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
---
diff -urpN patch_3/drivers/net/s2io.c patch_4/drivers/net/s2io.c
--- patch_3/drivers/net/s2io.c 2007-09-05 13:50:34.000000000 +0530
+++ patch_4/drivers/net/s2io.c 2007-09-05 14:11:17.000000000 +0530
@@ -130,6 +130,11 @@ static inline int rx_buffer_level(struct
return 0;
}
+static inline int is_s2io_card_up(const struct s2io_nic * sp)
+{
+ return test_bit(__S2IO_STATE_CARD_UP, &sp->state);
+}
+
/* Ethtool related variables and Macros. */
static char s2io_gstrings[][ETH_GSTRING_LEN] = {
"Register test\t(offline)",
@@ -2710,6 +2715,12 @@ static int s2io_poll(struct net_device *
int i;
atomic_inc(&nic->isr_cnt);
+
+ if (!is_s2io_card_up(nic)) {
+ atomic_dec(&nic->isr_cnt);
+ return 0;
+ }
+
mac_control = &nic->mac_control;
config = &nic->config;
@@ -2845,12 +2856,6 @@ static void rx_intr_handler(struct ring_
struct RxD3* rxdp3;
spin_lock(&nic->rx_lock);
- if (atomic_read(&nic->card_state) == CARD_DOWN) {
- DBG_PRINT(INTR_DBG, "%s: %s going down for reset\n",
- __FUNCTION__, dev->name);
- spin_unlock(&nic->rx_lock);
- return;
- }
get_info = ring_data->rx_curr_get_info;
get_block = get_info.block_index;
@@ -3994,7 +3999,7 @@ static int s2io_xmit(struct sk_buff *skb
}
spin_lock_irqsave(&sp->tx_lock, flags);
- if (atomic_read(&sp->card_state) == CARD_DOWN) {
+ if (!is_s2io_card_up(sp)) {
DBG_PRINT(TX_DBG, "%s: Card going down for reset\n",
dev->name);
spin_unlock_irqrestore(&sp->tx_lock, flags);
@@ -4188,6 +4193,11 @@ static irqreturn_t s2io_msix_ring_handle
atomic_inc(&sp->isr_cnt);
+ if (!is_s2io_card_up(sp)) {
+ atomic_dec(&sp->isr_cnt);
+ return IRQ_HANDLED;
+ }
+
rx_intr_handler(ring);
s2io_chk_rx_buffers(sp, ring->ring_no);
@@ -4201,6 +4211,12 @@ static irqreturn_t s2io_msix_fifo_handle
struct s2io_nic *sp = fifo->nic;
atomic_inc(&sp->isr_cnt);
+
+ if (!is_s2io_card_up(sp)) {
+ atomic_dec(&sp->isr_cnt);
+ return IRQ_HANDLED;
+ }
+
tx_intr_handler(fifo);
atomic_dec(&sp->isr_cnt);
return IRQ_HANDLED;
@@ -4308,7 +4324,7 @@ static void s2io_handle_errors(void * de
struct swStat *sw_stat = &sp->mac_control.stats_info->sw_stat;
struct xpakStat *stats = &sp->mac_control.stats_info->xpak_stat;
- if (unlikely(atomic_read(&sp->card_state) == CARD_DOWN))
+ if (!is_s2io_card_up(sp))
return;
if (pci_channel_offline(sp->pdev))
@@ -4579,6 +4595,12 @@ static irqreturn_t s2io_isr(int irq, voi
return IRQ_NONE;
atomic_inc(&sp->isr_cnt);
+
+ if (!is_s2io_card_up(sp)) {
+ atomic_dec(&sp->isr_cnt);
+ return IRQ_NONE;
+ }
+
mac_control = &sp->mac_control;
config = &sp->config;
@@ -4667,7 +4689,7 @@ static void s2io_updt_stats(struct s2io_
u64 val64;
int cnt = 0;
- if (atomic_read(&sp->card_state) == CARD_UP) {
+ if (is_s2io_card_up(sp)) {
/* Apprx 30us on a 133 MHz bus */
val64 = SET_UPDT_CLICKS(10) |
STAT_CFG_ONE_SHOT_EN | STAT_CFG_STAT_EN;
@@ -6463,7 +6485,7 @@ static void s2io_set_link(struct work_st
if (!netif_running(dev))
goto out_unlock;
- if (test_and_set_bit(0, &(nic->link_state))) {
+ if (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(nic->state))) {
/* The card is being reset, no point doing anything */
goto out_unlock;
}
@@ -6519,7 +6541,7 @@ static void s2io_set_link(struct work_st
writeq(val64, &bar0->adapter_control);
s2io_link(nic, LINK_DOWN);
}
- clear_bit(0, &(nic->link_state));
+ clear_bit(__S2IO_STATE_LINK_TASK, &(nic->state));
out_unlock:
rtnl_unlock();
@@ -6828,10 +6850,10 @@ static void do_s2io_card_down(struct s2i
del_timer_sync(&sp->alarm_timer);
/* If s2io_set_link task is executing, wait till it completes. */
- while (test_and_set_bit(0, &(sp->link_state))) {
+ while (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(sp->state))) {
msleep(50);
}
- atomic_set(&sp->card_state, CARD_DOWN);
+ clear_bit(__S2IO_STATE_CARD_UP, &sp->state);
/* disable Tx and Rx traffic on the NIC */
if (do_io)
@@ -6882,7 +6904,7 @@ static void do_s2io_card_down(struct s2i
free_rx_buffers(sp);
spin_unlock_irqrestore(&sp->rx_lock, flags);
- clear_bit(0, &(sp->link_state));
+ clear_bit(__S2IO_STATE_LINK_TASK, &(sp->state));
}
static void s2io_card_down(struct s2io_nic * sp)
@@ -6975,8 +6997,7 @@ static int s2io_card_up(struct s2io_nic
en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS);
}
-
- atomic_set(&sp->card_state, CARD_UP);
+ set_bit(__S2IO_STATE_CARD_UP, &sp->state);
return 0;
}
@@ -7705,9 +7726,8 @@ s2io_init_nic(struct pci_dev *pdev, cons
* Initialize the tasklet status and link state flags
* and the card state parameter
*/
- atomic_set(&(sp->card_state), 0);
sp->tasklet_status = 0;
- sp->link_state = 0;
+ sp->state = 0;
/* Initialize spinlocks */
spin_lock_init(&sp->tx_lock);
diff -urpN patch_3/drivers/net/s2io.h patch_4/drivers/net/s2io.h
--- patch_3/drivers/net/s2io.h 2007-09-05 13:50:37.000000000 +0530
+++ patch_4/drivers/net/s2io.h 2007-09-05 14:07:16.000000000 +0530
@@ -802,6 +802,13 @@ struct lro {
u8 saw_ts;
};
+/* These flags represent the devices temporary state */
+enum s2io_device_state_t
+{
+ __S2IO_STATE_LINK_TASK=0,
+ __S2IO_STATE_CARD_UP
+};
+
/* Structure representing one instance of the NIC */
struct s2io_nic {
int rxd_mode;
@@ -879,10 +886,6 @@ struct s2io_nic {
int task_flag;
unsigned long long start_time;
-#define CARD_DOWN 1
-#define CARD_UP 2
- atomic_t card_state;
- volatile unsigned long link_state;
struct vlan_group *vlgrp;
#define MSIX_FLG 0xA5
struct msix_entry *entries;
@@ -905,6 +908,7 @@ struct s2io_nic {
unsigned long sending_both;
u8 lro;
u16 lro_max_aggr_per_sess;
+ volatile unsigned long state;
spinlock_t rx_lock;
atomic_t isr_cnt;
u64 general_int_mask;
^ permalink raw reply
* Re: [PATCH 1/1] ipv6: corrects sended rtnetlink message
From: Thomas Graf @ 2007-09-06 10:47 UTC (permalink / raw)
To: Milan Kocian; +Cc: David Miller, netdev
In-Reply-To: <20070829215119.GB15856@wq.cz>
* Milan Kocian <milon@wq.cz> 2007-08-29 23:51
> Because RTM_NEWLINK is used to notify about device status change
> (as I see in net/core/rtnetlink.c) and RTM_DELLINK to inform about
> NETDEV_UNREGISTER. Why should it be else in ipv6 subsystem ? And
> userspace programs (quagga) suppose it. Now userspace get two rtnetlink's
> 'LINK' messages on 'ip l s down' event. First is RTM_NEWLINK from
> net/core/rtnetlink.c and second is RTM_DELLINK from ipv6.
The logic behind is quite simple, we notify via RTM_NEWLINK whenever
a device changes any of its attributes.
> quagga story:
> On NEWLINK (flag IFF_UP is down) message quagga flushes all routes from RIB
> but leaves ip adresses. On DELLINK message q. flushes routes and addresses.
> On 'ip l s up' event ipv6 sends addresses and routes again but ipv4 not
> (it sends only routes). Thus q. stays without knowledge about ipv4's addresses
> after 'ip l s down/up' commands.
>
> git change:
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=979ad663125af4be120697263038bb06ddbb83b4
It is arguable whether this change is correct, the purpose is clearly
to notify that IPv6 is no longer available on this interface without
implying anything beyond that.
Fortunately, all unregister events have the ifi_change field set to ~0U
whereas the "IPv6 disabled" notification sets the ifi_chagne field to
0 making it trivial to differ between the two cases. So quagga can
simply ignore (RTM_DELLINK && !ifi_change) notifications.
> IMHO second possibility is to remove rtnetlink notification about
> NETDEV_DOWN/_UNREGISTER from ipv6 subsystem because it is duplicate message.
Please make sure nobody is relying on this notification, IPv6 includes
more information in link messages, someone may be relying on this. If
not, feel free to remove the notification.
^ permalink raw reply
* [PATCH 2.6.24 3/5]S2io: Cleanup - removed unused variable intr_type
From: Sivakumar Subramani @ 2007-09-06 10:46 UTC (permalink / raw)
To: netdev, jeff; +Cc: support
- Removed the unused variable, intr_type, in device private structure.
Signed-off-by: Sivakumar Subramani <sivakumar.subramani@neterion.com>
Signed-off-by: Santosh Rastapur <santosh.rastapur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
---
diff -urpN patch_2/drivers/net/s2io.c patch_3/drivers/net/s2io.c
--- patch_2/drivers/net/s2io.c 2007-09-05 13:34:37.000000000 +0530
+++ patch_3/drivers/net/s2io.c 2007-09-05 13:50:34.000000000 +0530
@@ -1611,7 +1611,7 @@ static int init_nic(struct s2io_nic *nic
val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) |
RTI_DATA2_MEM_RX_UFC_B(0x2) ;
- if (nic->intr_type == MSI_X)
+ if (nic->config.intr_type == MSI_X)
val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) | \
RTI_DATA2_MEM_RX_UFC_D(0x40));
else
@@ -1749,7 +1749,7 @@ static int init_nic(struct s2io_nic *nic
static int s2io_link_fault_indication(struct s2io_nic *nic)
{
- if (nic->intr_type != INTA)
+ if (nic->config.intr_type != INTA)
return MAC_RMAC_ERR_TIMER;
if (nic->device_type == XFRAME_II_DEVICE)
return LINK_UP_DOWN_INTERRUPT;
@@ -3557,7 +3557,7 @@ static int s2io_set_swapper(struct s2io_
SWAPPER_CTRL_RXF_W_FE |
SWAPPER_CTRL_XMSI_FE |
SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
- if (sp->intr_type == INTA)
+ if (sp->config.intr_type == INTA)
val64 |= SWAPPER_CTRL_XMSI_SE;
writeq(val64, &bar0->swapper_ctrl);
#else
@@ -3580,7 +3580,7 @@ static int s2io_set_swapper(struct s2io_
SWAPPER_CTRL_RXF_W_FE |
SWAPPER_CTRL_XMSI_FE |
SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
- if (sp->intr_type == INTA)
+ if (sp->config.intr_type == INTA)
val64 |= SWAPPER_CTRL_XMSI_SE;
writeq(val64, &bar0->swapper_ctrl);
#endif
@@ -3854,7 +3854,7 @@ static int s2io_open(struct net_device *
netif_carrier_off(dev);
sp->last_link_state = 0;
- if (sp->intr_type == MSI_X) {
+ if (sp->config.intr_type == MSI_X) {
int ret = s2io_enable_msi_x(sp);
if (!ret) {
@@ -3886,12 +3886,12 @@ static int s2io_open(struct net_device *
DBG_PRINT(ERR_DBG,
"%s: MSI-X requested but failed to enable\n",
dev->name);
- sp->intr_type = INTA;
+ sp->config.intr_type = INTA;
}
}
/* NAPI doesn't work well with MSI(X) */
- if (sp->intr_type != INTA) {
+ if (sp->config.intr_type != INTA) {
if(sp->config.napi)
sp->config.napi = 0;
}
@@ -3915,7 +3915,7 @@ static int s2io_open(struct net_device *
return 0;
hw_init_failed:
- if (sp->intr_type == MSI_X) {
+ if (sp->config.intr_type == MSI_X) {
if (sp->entries) {
kfree(sp->entries);
sp->mac_control.stats_info->sw_stat.mem_freed
@@ -6700,18 +6700,18 @@ static int s2io_add_isr(struct s2io_nic
struct net_device *dev = sp->dev;
int err = 0;
- if (sp->intr_type == MSI_X)
+ if (sp->config.intr_type == MSI_X)
ret = s2io_enable_msi_x(sp);
if (ret) {
DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name);
- sp->intr_type = INTA;
+ sp->config.intr_type = INTA;
}
/* Store the values of the MSIX table in the struct s2io_nic structure */
store_xmsi_data(sp);
/* After proper initialization of H/W, register ISR */
- if (sp->intr_type == MSI_X) {
+ if (sp->config.intr_type == MSI_X) {
int i, msix_tx_cnt=0,msix_rx_cnt=0;
for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) {
@@ -6763,7 +6763,7 @@ static int s2io_add_isr(struct s2io_nic
printk("MSI-X-TX %d entries enabled\n",msix_tx_cnt);
printk("MSI-X-RX %d entries enabled\n",msix_rx_cnt);
}
- if (sp->intr_type == INTA) {
+ if (sp->config.intr_type == INTA) {
err = request_irq((int) sp->pdev->irq, s2io_isr, IRQF_SHARED,
sp->name, dev);
if (err) {
@@ -6780,7 +6780,7 @@ static void s2io_rem_isr(struct s2io_nic
struct net_device *dev = sp->dev;
struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
- if (sp->intr_type == MSI_X) {
+ if (sp->config.intr_type == MSI_X) {
int i;
u16 msi_control;
@@ -6953,7 +6953,7 @@ static int s2io_card_up(struct s2io_nic
/* Add interrupt service routine */
if (s2io_add_isr(sp) != 0) {
- if (sp->intr_type == MSI_X)
+ if (sp->config.intr_type == MSI_X)
s2io_rem_isr(sp);
s2io_reset(sp);
free_rx_buffers(sp);
@@ -6967,7 +6967,7 @@ static int s2io_card_up(struct s2io_nic
/* Enable select interrupts */
en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS);
- if (sp->intr_type != INTA)
+ if (sp->config.intr_type != INTA)
en_dis_able_nic_intrs(sp, ENA_ALL_INTRS, DISABLE_INTRS);
else {
interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
@@ -7494,7 +7494,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
if (rx_ring_mode == 2)
sp->rxd_mode = RXD_MODE_3B;
- sp->intr_type = dev_intr_type;
+ sp->config.intr_type = dev_intr_type;
if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) ||
(pdev->device == PCI_DEVICE_ID_HERC_UNI))
@@ -7774,7 +7774,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
if (napi)
DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name);
- switch(sp->intr_type) {
+ switch(sp->config.intr_type) {
case INTA:
DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name);
break;
diff -urpN patch_2/drivers/net/s2io.h patch_3/drivers/net/s2io.h
--- patch_2/drivers/net/s2io.h 2007-09-03 18:27:16.000000000 +0530
+++ patch_3/drivers/net/s2io.h 2007-09-05 13:50:37.000000000 +0530
@@ -905,11 +905,6 @@ struct s2io_nic {
unsigned long sending_both;
u8 lro;
u16 lro_max_aggr_per_sess;
-
-#define INTA 0
-#define MSI_X 2
- u8 intr_type;
-
spinlock_t rx_lock;
atomic_t isr_cnt;
u64 general_int_mask;
^ permalink raw reply
* [PATCH 2.6.24 2/5]S2io: Handle and monitor all of the device errors and alarms
From: Sivakumar Subramani @ 2007-09-06 10:43 UTC (permalink / raw)
To: netdev, jeff; +Cc: support
- Added support to poll entire set of device errors and alarams.
- A note on how device errors and alarms are handled:
- The adapter will automatically recover from uncorrectable ECC errors.
Packets containing corrupted data will be dropped (not transmitted) or tagged
as invalid before being passed to the host.
- The adapter cannot recover from any internal state machine errors. A state
machine error requires a device reset.
- Any internal error that could potentially result in .store trampling.
(undesirable PCI behaviour)is tagged as a "serious error". In such cases
the adapter will give up its ability to be a bus master. In this situation
the host will still be able to read internal device registers in order to
generate an error report. A device reset is necessary to return to normal
operation.
- In the event of a pcix data parity error, the adapter will automatically
disable itself. Adapter_En will automatically transition from '1' to '0' and
the adapter will enter its clean-up routine. Once the device has achieved
quiescence, an adapter reset should be performed.
- Replaced alarm_intr_handler() with s2io_handle_errors().
- Added statistic counters to monitor the alarms.
Signed-off-by: Sivakumar Subramani <sivakumar.subramani@neterion.com>
Signed-off-by: Santosh Rastapur <santosh.rastapur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
---
diff -urpN patch_1/drivers/net/s2io.c patch_2/drivers/net/s2io.c
--- patch_1/drivers/net/s2io.c 2007-09-05 13:34:16.000000000 +0530
+++ patch_2/drivers/net/s2io.c 2007-09-05 13:34:37.000000000 +0530
@@ -263,7 +263,14 @@ static char ethtool_driver_stats_keys[][
{"serious_err_cnt"},
{"soft_reset_cnt"},
{"fifo_full_cnt"},
- {"ring_full_cnt"},
+ {"ring_0_full_cnt"},
+ {"ring_1_full_cnt"},
+ {"ring_2_full_cnt"},
+ {"ring_3_full_cnt"},
+ {"ring_4_full_cnt"},
+ {"ring_5_full_cnt"},
+ {"ring_6_full_cnt"},
+ {"ring_7_full_cnt"},
("alarm_transceiver_temp_high"),
("alarm_transceiver_temp_low"),
("alarm_laser_bias_current_high"),
@@ -303,7 +310,24 @@ static char ethtool_driver_stats_keys[][
("rx_tcode_fcs_err_cnt"),
("rx_tcode_buf_size_err_cnt"),
("rx_tcode_rxd_corrupt_cnt"),
- ("rx_tcode_unkn_err_cnt")
+ ("rx_tcode_unkn_err_cnt"),
+ {"tda_err_cnt"},
+ {"pfc_err_cnt"},
+ {"pcc_err_cnt"},
+ {"tti_err_cnt"},
+ {"tpa_err_cnt"},
+ {"sm_err_cnt"},
+ {"lso_err_cnt"},
+ {"mac_tmac_err_cnt"},
+ {"mac_rmac_err_cnt"},
+ {"xgxs_txgxs_err_cnt"},
+ {"xgxs_rxgxs_err_cnt"},
+ {"rc_err_cnt"},
+ {"prc_pcix_err_cnt"},
+ {"rpa_err_cnt"},
+ {"rda_err_cnt"},
+ {"rti_err_cnt"},
+ {"mc_err_cnt"}
};
#define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN
@@ -1732,6 +1756,7 @@ static int s2io_link_fault_indication(st
else
return MAC_RMAC_ERR_TIMER;
}
+
/**
* do_s2io_write_bits - update alarm bits in alarm register
* @value: alarm bits
@@ -3260,135 +3285,6 @@ static void s2io_updt_xpak_counter(struc
}
/**
- * alarm_intr_handler - Alarm Interrrupt handler
- * @nic: device private variable
- * Description: If the interrupt was neither because of Rx packet or Tx
- * complete, this function is called. If the interrupt was to indicate
- * a loss of link, the OSM link status handler is invoked for any other
- * alarm interrupt the block that raised the interrupt is displayed
- * and a H/W reset is issued.
- * Return Value:
- * NONE
-*/
-
-static void alarm_intr_handler(struct s2io_nic *nic)
-{
- struct net_device *dev = (struct net_device *) nic->dev;
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- register u64 val64 = 0, err_reg = 0;
- u64 cnt;
- int i;
- if (atomic_read(&nic->card_state) == CARD_DOWN)
- return;
- if (pci_channel_offline(nic->pdev))
- return;
- nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0;
- /* Handling the XPAK counters update */
- if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) {
- /* waiting for an hour */
- nic->mac_control.stats_info->xpak_stat.xpak_timer_count++;
- } else {
- s2io_updt_xpak_counter(dev);
- /* reset the count to zero */
- nic->mac_control.stats_info->xpak_stat.xpak_timer_count = 0;
- }
-
- /* Handling link status change error Intr */
- if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) {
- err_reg = readq(&bar0->mac_rmac_err_reg);
- writeq(err_reg, &bar0->mac_rmac_err_reg);
- if (err_reg & RMAC_LINK_STATE_CHANGE_INT) {
- schedule_work(&nic->set_link_task);
- }
- }
-
- /* Handling Ecc errors */
- val64 = readq(&bar0->mc_err_reg);
- writeq(val64, &bar0->mc_err_reg);
- if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) {
- if (val64 & MC_ERR_REG_ECC_ALL_DBL) {
- nic->mac_control.stats_info->sw_stat.
- double_ecc_errs++;
- DBG_PRINT(INIT_DBG, "%s: Device indicates ",
- dev->name);
- DBG_PRINT(INIT_DBG, "double ECC error!!\n");
- if (nic->device_type != XFRAME_II_DEVICE) {
- /* Reset XframeI only if critical error */
- if (val64 & (MC_ERR_REG_MIRI_ECC_DB_ERR_0 |
- MC_ERR_REG_MIRI_ECC_DB_ERR_1)) {
- netif_stop_queue(dev);
- schedule_work(&nic->rst_timer_task);
- nic->mac_control.stats_info->sw_stat.
- soft_reset_cnt++;
- }
- }
- } else {
- nic->mac_control.stats_info->sw_stat.
- single_ecc_errs++;
- }
- }
-
- /* In case of a serious error, the device will be Reset. */
- val64 = readq(&bar0->serr_source);
- if (val64 & SERR_SOURCE_ANY) {
- nic->mac_control.stats_info->sw_stat.serious_err_cnt++;
- DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name);
- DBG_PRINT(ERR_DBG, "serious error %llx!!\n",
- (unsigned long long)val64);
- netif_stop_queue(dev);
- schedule_work(&nic->rst_timer_task);
- nic->mac_control.stats_info->sw_stat.soft_reset_cnt++;
- }
-
- /*
- * Also as mentioned in the latest Errata sheets if the PCC_FB_ECC
- * Error occurs, the adapter will be recycled by disabling the
- * adapter enable bit and enabling it again after the device
- * becomes Quiescent.
- */
- val64 = readq(&bar0->pcc_err_reg);
- writeq(val64, &bar0->pcc_err_reg);
- if (val64 & PCC_FB_ECC_DB_ERR) {
- u64 ac = readq(&bar0->adapter_control);
- ac &= ~(ADAPTER_CNTL_EN);
- writeq(ac, &bar0->adapter_control);
- ac = readq(&bar0->adapter_control);
- schedule_work(&nic->set_link_task);
- }
- /* Check for data parity error */
- val64 = readq(&bar0->pic_int_status);
- if (val64 & PIC_INT_GPIO) {
- val64 = readq(&bar0->gpio_int_reg);
- if (val64 & GPIO_INT_REG_DP_ERR_INT) {
- nic->mac_control.stats_info->sw_stat.parity_err_cnt++;
- schedule_work(&nic->rst_timer_task);
- nic->mac_control.stats_info->sw_stat.soft_reset_cnt++;
- }
- }
-
- /* Check for ring full counter */
- if (nic->device_type & XFRAME_II_DEVICE) {
- val64 = readq(&bar0->ring_bump_counter1);
- for (i=0; i<4; i++) {
- cnt = ( val64 & vBIT(0xFFFF,(i*16),16));
- cnt >>= 64 - ((i+1)*16);
- nic->mac_control.stats_info->sw_stat.ring_full_cnt
- += cnt;
- }
-
- val64 = readq(&bar0->ring_bump_counter2);
- for (i=0; i<4; i++) {
- cnt = ( val64 & vBIT(0xFFFF,(i*16),16));
- cnt >>= 64 - ((i+1)*16);
- nic->mac_control.stats_info->sw_stat.ring_full_cnt
- += cnt;
- }
- }
-
- /* Other type of interrupts are not being handled now, TODO */
-}
-
-/**
* wait_for_cmd_complete - waits for a command to complete.
* @sp : private member of the device structure, which is a pointer to the
* s2io_nic structure.
@@ -4250,8 +4146,9 @@ static void
s2io_alarm_handle(unsigned long data)
{
struct s2io_nic *sp = (struct s2io_nic *)data;
+ struct net_device *dev = sp->dev;
- alarm_intr_handler(sp);
+ s2io_handle_errors(dev);
mod_timer(&sp->alarm_timer, jiffies + HZ / 2);
}
@@ -4370,6 +4267,291 @@ static void s2io_txpic_intr_handle(struc
}
/**
+ * do_s2io_chk_alarm_bit - Check for alarm and incrment the counter
+ * @value: alarm bits
+ * @addr: address value
+ * @cnt: counter variable
+ * Description: Check for alarm and increment the counter
+ * Return Value:
+ * 1 - if alarm bit set
+ * 0 - if alarm bit is not set
+ */
+int do_s2io_chk_alarm_bit(u64 value, void __iomem * addr, u64 *cnt)
+{
+ u64 val64;
+ val64 = readq(addr);
+ if ( val64 & value ) {
+ writeq(val64, addr);
+ (*cnt)++;
+ return 1;
+ }
+ return 0;
+
+}
+
+/**
+ * s2io_handle_errors - Xframe error indication handler
+ * @nic: device private variable
+ * Description: Handle alarms such as loss of link, single or
+ * double ECC errors, critical and serious errors.
+ * Return Value:
+ * NONE
+ */
+static void s2io_handle_errors(void * dev_id)
+{
+ struct net_device *dev = (struct net_device *) dev_id;
+ struct s2io_nic *sp = dev->priv;
+ struct XENA_dev_config __iomem *bar0 = sp->bar0;
+ u64 temp64 = 0,val64=0;
+ int i = 0;
+
+ struct swStat *sw_stat = &sp->mac_control.stats_info->sw_stat;
+ struct xpakStat *stats = &sp->mac_control.stats_info->xpak_stat;
+
+ if (unlikely(atomic_read(&sp->card_state) == CARD_DOWN))
+ return;
+
+ if (pci_channel_offline(sp->pdev))
+ return;
+
+ memset(&sw_stat->ring_full_cnt, 0,
+ sizeof(sw_stat->ring_full_cnt));
+
+ /* Handling the XPAK counters update */
+ if(stats->xpak_timer_count < 72000) {
+ /* waiting for an hour */
+ stats->xpak_timer_count++;
+ } else {
+ s2io_updt_xpak_counter(dev);
+ /* reset the count to zero */
+ stats->xpak_timer_count = 0;
+ }
+
+ /* Handling link status change error Intr */
+ if (s2io_link_fault_indication(sp) == MAC_RMAC_ERR_TIMER) {
+ val64 = readq(&bar0->mac_rmac_err_reg);
+ writeq(val64, &bar0->mac_rmac_err_reg);
+ if (val64 & RMAC_LINK_STATE_CHANGE_INT)
+ schedule_work(&sp->set_link_task);
+ }
+
+ /* In case of a serious error, the device will be Reset. */
+ if (do_s2io_chk_alarm_bit(SERR_SOURCE_ANY, &bar0->serr_source,
+ &sw_stat->serious_err_cnt))
+ goto reset;
+
+ /* Check for data parity error */
+ if (do_s2io_chk_alarm_bit(GPIO_INT_REG_DP_ERR_INT, &bar0->gpio_int_reg,
+ &sw_stat->parity_err_cnt))
+ goto reset;
+
+ /* Check for ring full counter */
+ if (sp->device_type == XFRAME_II_DEVICE) {
+ val64 = readq(&bar0->ring_bump_counter1);
+ for (i=0; i<4; i++) {
+ temp64 = ( val64 & vBIT(0xFFFF,(i*16),16));
+ temp64 >>= 64 - ((i+1)*16);
+ sw_stat->ring_full_cnt[i] += temp64;
+ }
+
+ val64 = readq(&bar0->ring_bump_counter2);
+ for (i=0; i<4; i++) {
+ temp64 = ( val64 & vBIT(0xFFFF,(i*16),16));
+ temp64 >>= 64 - ((i+1)*16);
+ sw_stat->ring_full_cnt[i+4] += temp64;
+ }
+ }
+
+ val64 = readq(&bar0->txdma_int_status);
+ /*check for pfc_err*/
+ if (val64 & TXDMA_PFC_INT) {
+ if (do_s2io_chk_alarm_bit(PFC_ECC_DB_ERR | PFC_SM_ERR_ALARM|
+ PFC_MISC_0_ERR | PFC_MISC_1_ERR|
+ PFC_PCIX_ERR, &bar0->pfc_err_reg,
+ &sw_stat->pfc_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(PFC_ECC_SG_ERR, &bar0->pfc_err_reg,
+ &sw_stat->pfc_err_cnt);
+ }
+
+ /*check for tda_err*/
+ if (val64 & TXDMA_TDA_INT) {
+ if(do_s2io_chk_alarm_bit(TDA_Fn_ECC_DB_ERR | TDA_SM0_ERR_ALARM |
+ TDA_SM1_ERR_ALARM, &bar0->tda_err_reg,
+ &sw_stat->tda_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(TDA_Fn_ECC_SG_ERR | TDA_PCIX_ERR,
+ &bar0->tda_err_reg, &sw_stat->tda_err_cnt);
+ }
+ /*check for pcc_err*/
+ if (val64 & TXDMA_PCC_INT) {
+ if (do_s2io_chk_alarm_bit(PCC_SM_ERR_ALARM | PCC_WR_ERR_ALARM
+ | PCC_N_SERR | PCC_6_COF_OV_ERR
+ | PCC_7_COF_OV_ERR | PCC_6_LSO_OV_ERR
+ | PCC_7_LSO_OV_ERR | PCC_FB_ECC_DB_ERR
+ | PCC_TXB_ECC_DB_ERR, &bar0->pcc_err_reg,
+ &sw_stat->pcc_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(PCC_FB_ECC_SG_ERR | PCC_TXB_ECC_SG_ERR,
+ &bar0->pcc_err_reg, &sw_stat->pcc_err_cnt);
+ }
+
+ /*check for tti_err*/
+ if (val64 & TXDMA_TTI_INT) {
+ if (do_s2io_chk_alarm_bit(TTI_SM_ERR_ALARM, &bar0->tti_err_reg,
+ &sw_stat->tti_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(TTI_ECC_SG_ERR | TTI_ECC_DB_ERR,
+ &bar0->tti_err_reg, &sw_stat->tti_err_cnt);
+ }
+
+ /*check for lso_err*/
+ if (val64 & TXDMA_LSO_INT) {
+ if (do_s2io_chk_alarm_bit(LSO6_ABORT | LSO7_ABORT
+ | LSO6_SM_ERR_ALARM | LSO7_SM_ERR_ALARM,
+ &bar0->lso_err_reg, &sw_stat->lso_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(LSO6_SEND_OFLOW | LSO7_SEND_OFLOW,
+ &bar0->lso_err_reg, &sw_stat->lso_err_cnt);
+ }
+
+ /*check for tpa_err*/
+ if (val64 & TXDMA_TPA_INT) {
+ if (do_s2io_chk_alarm_bit(TPA_SM_ERR_ALARM, &bar0->tpa_err_reg,
+ &sw_stat->tpa_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(TPA_TX_FRM_DROP, &bar0->tpa_err_reg,
+ &sw_stat->tpa_err_cnt);
+ }
+
+ /*check for sm_err*/
+ if (val64 & TXDMA_SM_INT) {
+ if (do_s2io_chk_alarm_bit(SM_SM_ERR_ALARM, &bar0->sm_err_reg,
+ &sw_stat->sm_err_cnt))
+ goto reset;
+ }
+
+ val64 = readq(&bar0->mac_int_status);
+ if (val64 & MAC_INT_STATUS_TMAC_INT) {
+ if (do_s2io_chk_alarm_bit(TMAC_TX_BUF_OVRN | TMAC_TX_SM_ERR,
+ &bar0->mac_tmac_err_reg,
+ &sw_stat->mac_tmac_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(TMAC_ECC_SG_ERR | TMAC_ECC_DB_ERR
+ | TMAC_DESC_ECC_SG_ERR | TMAC_DESC_ECC_DB_ERR,
+ &bar0->mac_tmac_err_reg,
+ &sw_stat->mac_tmac_err_cnt);
+ }
+
+ val64 = readq(&bar0->xgxs_int_status);
+ if (val64 & XGXS_INT_STATUS_TXGXS) {
+ if (do_s2io_chk_alarm_bit(TXGXS_ESTORE_UFLOW | TXGXS_TX_SM_ERR,
+ &bar0->xgxs_txgxs_err_reg,
+ &sw_stat->xgxs_txgxs_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(TXGXS_ECC_SG_ERR | TXGXS_ECC_DB_ERR,
+ &bar0->xgxs_txgxs_err_reg,
+ &sw_stat->xgxs_txgxs_err_cnt);
+ }
+
+ val64 = readq(&bar0->rxdma_int_status);
+ if (val64 & RXDMA_INT_RC_INT_M) {
+ if (do_s2io_chk_alarm_bit(RC_PRCn_ECC_DB_ERR | RC_FTC_ECC_DB_ERR
+ | RC_PRCn_SM_ERR_ALARM |RC_FTC_SM_ERR_ALARM,
+ &bar0->rc_err_reg, &sw_stat->rc_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(RC_PRCn_ECC_SG_ERR | RC_FTC_ECC_SG_ERR
+ | RC_RDA_FAIL_WR_Rn, &bar0->rc_err_reg,
+ &sw_stat->rc_err_cnt);
+ if (do_s2io_chk_alarm_bit(PRC_PCI_AB_RD_Rn | PRC_PCI_AB_WR_Rn
+ | PRC_PCI_AB_F_WR_Rn, &bar0->prc_pcix_err_reg,
+ &sw_stat->prc_pcix_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(PRC_PCI_DP_RD_Rn | PRC_PCI_DP_WR_Rn
+ | PRC_PCI_DP_F_WR_Rn, &bar0->prc_pcix_err_reg,
+ &sw_stat->prc_pcix_err_cnt);
+ }
+
+ if (val64 & RXDMA_INT_RPA_INT_M) {
+ if (do_s2io_chk_alarm_bit(RPA_SM_ERR_ALARM | RPA_CREDIT_ERR,
+ &bar0->rpa_err_reg, &sw_stat->rpa_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(RPA_ECC_SG_ERR | RPA_ECC_DB_ERR,
+ &bar0->rpa_err_reg, &sw_stat->rpa_err_cnt);
+ }
+
+ if (val64 & RXDMA_INT_RDA_INT_M) {
+ if (do_s2io_chk_alarm_bit(RDA_RXDn_ECC_DB_ERR
+ | RDA_FRM_ECC_DB_N_AERR | RDA_SM1_ERR_ALARM
+ | RDA_SM0_ERR_ALARM | RDA_RXD_ECC_DB_SERR,
+ &bar0->rda_err_reg, &sw_stat->rda_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(RDA_RXDn_ECC_SG_ERR | RDA_FRM_ECC_SG_ERR
+ | RDA_MISC_ERR | RDA_PCIX_ERR,
+ &bar0->rda_err_reg, &sw_stat->rda_err_cnt);
+ }
+
+ if (val64 & RXDMA_INT_RTI_INT_M) {
+ if (do_s2io_chk_alarm_bit(RTI_SM_ERR_ALARM, &bar0->rti_err_reg,
+ &sw_stat->rti_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(RTI_ECC_SG_ERR | RTI_ECC_DB_ERR,
+ &bar0->rti_err_reg, &sw_stat->rti_err_cnt);
+ }
+
+ val64 = readq(&bar0->mac_int_status);
+ if (val64 & MAC_INT_STATUS_RMAC_INT) {
+ if (do_s2io_chk_alarm_bit(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR,
+ &bar0->mac_rmac_err_reg,
+ &sw_stat->mac_rmac_err_cnt))
+ goto reset;
+ do_s2io_chk_alarm_bit(RMAC_UNUSED_INT|RMAC_SINGLE_ECC_ERR|
+ RMAC_DOUBLE_ECC_ERR, &bar0->mac_rmac_err_reg,
+ &sw_stat->mac_rmac_err_cnt);
+ }
+
+ val64 = readq(&bar0->xgxs_int_status);
+ if (val64 & XGXS_INT_STATUS_RXGXS) {
+ if (do_s2io_chk_alarm_bit(RXGXS_ESTORE_OFLOW | RXGXS_RX_SM_ERR,
+ &bar0->xgxs_rxgxs_err_reg,
+ &sw_stat->xgxs_rxgxs_err_cnt))
+ goto reset;
+ }
+
+ val64 = readq(&bar0->mc_int_status);
+ if(val64 & MC_INT_STATUS_MC_INT) {
+ if (do_s2io_chk_alarm_bit(MC_ERR_REG_SM_ERR, &bar0->mc_err_reg,
+ &sw_stat->mc_err_cnt))
+ goto reset;
+
+ /* Handling Ecc errors */
+ if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) {
+ writeq(val64, &bar0->mc_err_reg);
+ if (val64 & MC_ERR_REG_ECC_ALL_DBL) {
+ sw_stat->double_ecc_errs++;
+ if (sp->device_type != XFRAME_II_DEVICE) {
+ /*
+ * Reset XframeI only if critical error
+ */
+ if (val64 &
+ (MC_ERR_REG_MIRI_ECC_DB_ERR_0 |
+ MC_ERR_REG_MIRI_ECC_DB_ERR_1))
+ goto reset;
+ }
+ } else
+ sw_stat->single_ecc_errs++;
+ }
+ }
+ return;
+
+reset:
+ netif_stop_queue(dev);
+ schedule_work(&sp->rst_timer_task);
+ sw_stat->soft_reset_cnt++;
+ return;
+}
+
+/**
* s2io_isr - ISR handler of the device .
* @irq: the irq of the device.
* @dev_id: a void pointer to the dev structure of the NIC.
@@ -5758,7 +5940,7 @@ static void s2io_get_ethtool_stats(struc
struct ethtool_stats *estats,
u64 * tmp_stats)
{
- int i = 0;
+ int i = 0, k;
struct s2io_nic *sp = dev->priv;
struct stat_block *stat_info = sp->mac_control.stats_info;
@@ -5953,7 +6135,8 @@ static void s2io_get_ethtool_stats(struc
tmp_stats[i++] = stat_info->sw_stat.serious_err_cnt;
tmp_stats[i++] = stat_info->sw_stat.soft_reset_cnt;
tmp_stats[i++] = stat_info->sw_stat.fifo_full_cnt;
- tmp_stats[i++] = stat_info->sw_stat.ring_full_cnt;
+ for (k = 0; k < MAX_RX_RINGS; k++)
+ tmp_stats[i++] = stat_info->sw_stat.ring_full_cnt[k];
tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_high;
tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_low;
tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_bias_current_high;
@@ -6010,6 +6193,23 @@ static void s2io_get_ethtool_stats(struc
tmp_stats[i++] = stat_info->sw_stat.rx_buf_size_err_cnt;
tmp_stats[i++] = stat_info->sw_stat.rx_rxd_corrupt_cnt;
tmp_stats[i++] = stat_info->sw_stat.rx_unkn_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.tda_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.pfc_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.pcc_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.tti_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.tpa_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.sm_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.lso_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.mac_tmac_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.mac_rmac_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.xgxs_txgxs_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.xgxs_rxgxs_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rc_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.prc_pcix_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rpa_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rda_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rti_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.mc_err_cnt;
}
static int s2io_ethtool_get_regs_len(struct net_device *dev)
diff -urpN patch_1/drivers/net/s2io.h patch_2/drivers/net/s2io.h
--- patch_1/drivers/net/s2io.h 2007-09-01 18:43:38.000000000 +0530
+++ patch_2/drivers/net/s2io.h 2007-09-03 18:27:16.000000000 +0530
@@ -91,7 +91,7 @@ struct swStat {
unsigned long long serious_err_cnt;
unsigned long long soft_reset_cnt;
unsigned long long fifo_full_cnt;
- unsigned long long ring_full_cnt;
+ unsigned long long ring_full_cnt[8];
/* LRO statistics */
unsigned long long clubbed_frms_cnt;
unsigned long long sending_both;
@@ -126,6 +126,26 @@ struct swStat {
unsigned long long rx_buf_size_err_cnt;
unsigned long long rx_rxd_corrupt_cnt;
unsigned long long rx_unkn_err_cnt;
+
+ /* Error/alarm statistics*/
+ unsigned long long tda_err_cnt;
+ unsigned long long pfc_err_cnt;
+ unsigned long long pcc_err_cnt;
+ unsigned long long tti_err_cnt;
+ unsigned long long lso_err_cnt;
+ unsigned long long tpa_err_cnt;
+ unsigned long long sm_err_cnt;
+ unsigned long long mac_tmac_err_cnt;
+ unsigned long long mac_rmac_err_cnt;
+ unsigned long long xgxs_txgxs_err_cnt;
+ unsigned long long xgxs_rxgxs_err_cnt;
+ unsigned long long rc_err_cnt;
+ unsigned long long prc_pcix_err_cnt;
+ unsigned long long rpa_err_cnt;
+ unsigned long long rda_err_cnt;
+ unsigned long long rti_err_cnt;
+ unsigned long long mc_err_cnt;
+
};
/* Xpak releated alarm and warnings */
@@ -1017,7 +1037,7 @@ static void free_shared_mem(struct s2io_
static int init_nic(struct s2io_nic *nic);
static void rx_intr_handler(struct ring_info *ring_data);
static void tx_intr_handler(struct fifo_info *fifo_data);
-static void alarm_intr_handler(struct s2io_nic *sp);
+static void s2io_handle_errors(void * dev_id);
static int s2io_starter(void);
static void s2io_closer(void);
^ permalink raw reply
* Re: net-26.24 broken with XFRM off
From: Noriaki TAKAMIYA @ 2007-09-06 10:01 UTC (permalink / raw)
To: dada1; +Cc: divy, davem, netdev, linux-kernel, usagi-core
In-Reply-To: <20070903193711.6A1D.NAKAM@linux-ipv6.org>
Hi,
>> Thu, 6 Sep 2007 10:13:26 +0200
>> [Subject: Re: net-26.24 broken with XFRM off]
>> Eric Dumazet <dada1@cosmosbay.com> wrote...
> Hi Divy
>
> I believe this problem is known.
>
> Please check http://marc.info/?l=linux-netdev&m=118881627028135&w=2
I'm sorry not to check more precisely.
As Eric said, this issue should be fixed by the patch attached in
the following mail.
Regards,
>> Mon, 03 Sep 2007 19:43:51 +0900
>> [Subject: Re: [-mm patch] IPV6 must select XFRM]
>> Masahide NAKAMURA <nakam@linux-ipv6.org> wrote...
> Thank you for catching this. the issue is caused with patch
> "[IPV6] XFRM: Fix connected socket to use transformation."
> which I sent to netdev.
> (a85d5450ddeb959bdf9e4603f9c06e9d79217cfa on net-2.6.24).
>
> I'd prefer to modify the original patch to use "ifdef CONFIG_XFRM"
> than changing kernel config depends. Does it make sense?
>
> Please review the attached patch.
>
> --
> Masahide NAKAMURA
--
Noriaki TAKAMIYA
^ permalink raw reply
* [PATCH 2.6.24 1/5]S2io: Enable all the error and alarm indications
From: Sivakumar Subramani @ 2007-09-06 10:21 UTC (permalink / raw)
To: netdev, jeff; +Cc: support
- Added support to unmask entire set of device errors and alarams.
Alarm interrupts are generated for a myriad of purposes, ranging from
illegal operations or requests to internal state machine errors and
uncorrectable data corruption errors. In several cases the adapter can
recover gracefully from unexpected events; however, in some cases, a device
reset may be necessary. This patch handles alarms generated by all the
blocks within the device.
The adapter generates the following types of alarms:
1. Link state transitions (local/remote fault) or other link-related
problems.
2. Problems with any device peripherals, including the EEPROM, FLASH,
etc.
3. Correctable ECC errors (single-bit errors) on internal data
structures or frame data.
4. Uncorrectable ECC errors (multi-bit errors) on internal data
structures or frame data.
5. State machine errors, which indicate that internal control
structures have become corrupted.
6. PCI related errors, including parity errors or illegal transactions.
7. Other unexpected events.
- Implemented Jeff's review comments to use do_s2io_write_bits function to avoid
duplicate codes.
Signed-off-by: Sivakumar Subramani <sivakumar.subramani@neterion.com>
Signed-off-by: Santosh Rastapur <santosh.rastapur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
---
diff -urpN org/drivers/net/s2io.c patch_1/drivers/net/s2io.c
--- org/drivers/net/s2io.c 2007-09-01 19:42:15.000000000 +0530
+++ patch_1/drivers/net/s2io.c 2007-09-05 13:34:16.000000000 +0530
@@ -892,8 +892,9 @@ static void free_shared_mem(struct s2io_
k++;
}
kfree(mac_control->rings[i].ba[j]);
- nic->mac_control.stats_info->sw_stat.mem_freed += (sizeof(struct buffAdd) *
- (rxd_count[nic->rxd_mode] + 1));
+ nic->mac_control.stats_info->sw_stat.mem_freed +=
+ (sizeof(struct buffAdd) *
+ (rxd_count[nic->rxd_mode] + 1));
}
kfree(mac_control->rings[i].ba);
nic->mac_control.stats_info->sw_stat.mem_freed +=
@@ -1731,7 +1732,150 @@ static int s2io_link_fault_indication(st
else
return MAC_RMAC_ERR_TIMER;
}
+/**
+ * do_s2io_write_bits - update alarm bits in alarm register
+ * @value: alarm bits
+ * @flag: interrupt status
+ * @addr: address value
+ * Description: update alarm bits in alarm register
+ * Return Value:
+ * NONE.
+ */
+static void do_s2io_write_bits(u64 value, int flag, void __iomem *addr)
+{
+ u64 temp64;
+
+ temp64 = readq(addr);
+ if(flag == ENABLE_INTRS)
+ temp64 &= ~((u64) value);
+ else
+ temp64 |= ((u64) value);
+ writeq(temp64, addr);
+}
+
+void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
+{
+ struct XENA_dev_config __iomem *bar0 = nic->bar0;
+ register u64 gen_int_mask = 0;
+
+ if (mask & TX_DMA_INTR) {
+
+ gen_int_mask |= TXDMA_INT_M;
+
+ do_s2io_write_bits(TXDMA_TDA_INT | TXDMA_PFC_INT |
+ TXDMA_PCC_INT | TXDMA_TTI_INT |
+ TXDMA_LSO_INT | TXDMA_TPA_INT |
+ TXDMA_SM_INT, flag, &bar0->txdma_int_mask);
+
+ do_s2io_write_bits(PFC_ECC_DB_ERR | PFC_SM_ERR_ALARM |
+ PFC_MISC_0_ERR | PFC_MISC_1_ERR |
+ PFC_PCIX_ERR | PFC_ECC_SG_ERR, flag,
+ &bar0->pfc_err_mask);
+
+ do_s2io_write_bits(TDA_Fn_ECC_DB_ERR | TDA_SM0_ERR_ALARM |
+ TDA_SM1_ERR_ALARM | TDA_Fn_ECC_SG_ERR |
+ TDA_PCIX_ERR, flag, &bar0->tda_err_mask);
+
+ do_s2io_write_bits(PCC_FB_ECC_DB_ERR | PCC_TXB_ECC_DB_ERR |
+ PCC_SM_ERR_ALARM | PCC_WR_ERR_ALARM |
+ PCC_N_SERR | PCC_6_COF_OV_ERR |
+ PCC_7_COF_OV_ERR | PCC_6_LSO_OV_ERR |
+ PCC_7_LSO_OV_ERR | PCC_FB_ECC_SG_ERR |
+ PCC_TXB_ECC_SG_ERR, flag, &bar0->pcc_err_mask);
+
+ do_s2io_write_bits(TTI_SM_ERR_ALARM | TTI_ECC_SG_ERR |
+ TTI_ECC_DB_ERR, flag, &bar0->tti_err_mask);
+
+ do_s2io_write_bits(LSO6_ABORT | LSO7_ABORT |
+ LSO6_SM_ERR_ALARM | LSO7_SM_ERR_ALARM |
+ LSO6_SEND_OFLOW | LSO7_SEND_OFLOW,
+ flag, &bar0->lso_err_mask);
+
+ do_s2io_write_bits(TPA_SM_ERR_ALARM | TPA_TX_FRM_DROP,
+ flag, &bar0->tpa_err_mask);
+
+ do_s2io_write_bits(SM_SM_ERR_ALARM, flag, &bar0->sm_err_mask);
+
+ }
+
+ if (mask & TX_MAC_INTR) {
+ gen_int_mask |= TXMAC_INT_M;
+ do_s2io_write_bits(MAC_INT_STATUS_TMAC_INT, flag,
+ &bar0->mac_int_mask);
+ do_s2io_write_bits(TMAC_TX_BUF_OVRN | TMAC_TX_SM_ERR |
+ TMAC_ECC_SG_ERR | TMAC_ECC_DB_ERR |
+ TMAC_DESC_ECC_SG_ERR | TMAC_DESC_ECC_DB_ERR,
+ flag, &bar0->mac_tmac_err_mask);
+ }
+
+ if (mask & TX_XGXS_INTR) {
+ gen_int_mask |= TXXGXS_INT_M;
+ do_s2io_write_bits(XGXS_INT_STATUS_TXGXS, flag,
+ &bar0->xgxs_int_mask);
+ do_s2io_write_bits(TXGXS_ESTORE_UFLOW | TXGXS_TX_SM_ERR |
+ TXGXS_ECC_SG_ERR | TXGXS_ECC_DB_ERR,
+ flag, &bar0->xgxs_txgxs_err_mask);
+ }
+
+ if (mask & RX_DMA_INTR) {
+ gen_int_mask |= RXDMA_INT_M;
+ do_s2io_write_bits(RXDMA_INT_RC_INT_M | RXDMA_INT_RPA_INT_M |
+ RXDMA_INT_RDA_INT_M | RXDMA_INT_RTI_INT_M,
+ flag, &bar0->rxdma_int_mask);
+ do_s2io_write_bits(RC_PRCn_ECC_DB_ERR | RC_FTC_ECC_DB_ERR |
+ RC_PRCn_SM_ERR_ALARM | RC_FTC_SM_ERR_ALARM |
+ RC_PRCn_ECC_SG_ERR | RC_FTC_ECC_SG_ERR |
+ RC_RDA_FAIL_WR_Rn, flag, &bar0->rc_err_mask);
+ do_s2io_write_bits(PRC_PCI_AB_RD_Rn | PRC_PCI_AB_WR_Rn |
+ PRC_PCI_AB_F_WR_Rn | PRC_PCI_DP_RD_Rn |
+ PRC_PCI_DP_WR_Rn | PRC_PCI_DP_F_WR_Rn, flag,
+ &bar0->prc_pcix_err_mask);
+ do_s2io_write_bits(RPA_SM_ERR_ALARM | RPA_CREDIT_ERR |
+ RPA_ECC_SG_ERR | RPA_ECC_DB_ERR, flag,
+ &bar0->rpa_err_mask);
+ do_s2io_write_bits(RDA_RXDn_ECC_DB_ERR | RDA_FRM_ECC_DB_N_AERR |
+ RDA_SM1_ERR_ALARM | RDA_SM0_ERR_ALARM |
+ RDA_RXD_ECC_DB_SERR | RDA_RXDn_ECC_SG_ERR |
+ RDA_FRM_ECC_SG_ERR | RDA_MISC_ERR|RDA_PCIX_ERR,
+ flag, &bar0->rda_err_mask);
+ do_s2io_write_bits(RTI_SM_ERR_ALARM |
+ RTI_ECC_SG_ERR | RTI_ECC_DB_ERR,
+ flag, &bar0->rti_err_mask);
+ }
+
+ if (mask & RX_MAC_INTR) {
+ gen_int_mask |= RXMAC_INT_M;
+ do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag,
+ &bar0->mac_int_mask);
+ do_s2io_write_bits(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
+ RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR |
+ RMAC_DOUBLE_ECC_ERR |
+ RMAC_LINK_STATE_CHANGE_INT,
+ flag, &bar0->mac_rmac_err_mask);
+ }
+
+ if (mask & RX_XGXS_INTR)
+ {
+ gen_int_mask |= RXXGXS_INT_M;
+ do_s2io_write_bits(XGXS_INT_STATUS_RXGXS, flag,
+ &bar0->xgxs_int_mask);
+ do_s2io_write_bits(RXGXS_ESTORE_OFLOW | RXGXS_RX_SM_ERR, flag,
+ &bar0->xgxs_rxgxs_err_mask);
+ }
+
+ if (mask & MC_INTR) {
+ gen_int_mask |= MC_INT_M;
+ do_s2io_write_bits(MC_INT_MASK_MC_INT, flag, &bar0->mc_int_mask);
+ do_s2io_write_bits(MC_ERR_REG_SM_ERR | MC_ERR_REG_ECC_ALL_SNG |
+ MC_ERR_REG_ECC_ALL_DBL | PLL_LOCK_N, flag,
+ &bar0->mc_err_mask);
+ }
+ nic->general_int_mask = gen_int_mask;
+
+ /* Remove this line when alarm interrupts are enabled */
+ nic->general_int_mask = 0;
+}
/**
* en_dis_able_nic_intrs - Enable or Disable the interrupts
* @nic: device private variable,
@@ -1746,17 +1890,16 @@ static int s2io_link_fault_indication(st
static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
{
struct XENA_dev_config __iomem *bar0 = nic->bar0;
- register u64 val64 = 0, temp64 = 0;
+ register u64 temp64 = 0, intr_mask = 0;
+
+ intr_mask = nic->general_int_mask;
/* Top level interrupt classification */
/* PIC Interrupts */
- if ((mask & (TX_PIC_INTR | RX_PIC_INTR))) {
+ if (mask & TX_PIC_INTR) {
/* Enable PIC Intrs in the general intr mask register */
- val64 = TXPIC_INT_M;
+ intr_mask |= TXPIC_INT_M;
if (flag == ENABLE_INTRS) {
- temp64 = readq(&bar0->general_int_mask);
- temp64 &= ~((u64) val64);
- writeq(temp64, &bar0->general_int_mask);
/*
* If Hercules adapter enable GPIO otherwise
* disable all PCIX, Flash, MDIO, IIC and GPIO
@@ -1765,64 +1908,25 @@ static void en_dis_able_nic_intrs(struct
*/
if (s2io_link_fault_indication(nic) ==
LINK_UP_DOWN_INTERRUPT ) {
- temp64 = readq(&bar0->pic_int_mask);
- temp64 &= ~((u64) PIC_INT_GPIO);
- writeq(temp64, &bar0->pic_int_mask);
- temp64 = readq(&bar0->gpio_int_mask);
- temp64 &= ~((u64) GPIO_INT_MASK_LINK_UP);
- writeq(temp64, &bar0->gpio_int_mask);
- } else {
+ do_s2io_write_bits(PIC_INT_GPIO, flag,
+ &bar0->pic_int_mask);
+ do_s2io_write_bits(GPIO_INT_MASK_LINK_UP, flag,
+ &bar0->gpio_int_mask);
+ } else
writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask);
- }
- /*
- * No MSI Support is available presently, so TTI and
- * RTI interrupts are also disabled.
- */
} else if (flag == DISABLE_INTRS) {
/*
* Disable PIC Intrs in the general
* intr mask register
*/
writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask);
- temp64 = readq(&bar0->general_int_mask);
- val64 |= temp64;
- writeq(val64, &bar0->general_int_mask);
- }
- }
-
- /* MAC Interrupts */
- /* Enabling/Disabling MAC interrupts */
- if (mask & (TX_MAC_INTR | RX_MAC_INTR)) {
- val64 = TXMAC_INT_M | RXMAC_INT_M;
- if (flag == ENABLE_INTRS) {
- temp64 = readq(&bar0->general_int_mask);
- temp64 &= ~((u64) val64);
- writeq(temp64, &bar0->general_int_mask);
- /*
- * All MAC block error interrupts are disabled for now
- * TODO
- */
- } else if (flag == DISABLE_INTRS) {
- /*
- * Disable MAC Intrs in the general intr mask register
- */
- writeq(DISABLE_ALL_INTRS, &bar0->mac_int_mask);
- writeq(DISABLE_ALL_INTRS,
- &bar0->mac_rmac_err_mask);
-
- temp64 = readq(&bar0->general_int_mask);
- val64 |= temp64;
- writeq(val64, &bar0->general_int_mask);
}
}
/* Tx traffic interrupts */
if (mask & TX_TRAFFIC_INTR) {
- val64 = TXTRAFFIC_INT_M;
+ intr_mask |= TXTRAFFIC_INT_M;
if (flag == ENABLE_INTRS) {
- temp64 = readq(&bar0->general_int_mask);
- temp64 &= ~((u64) val64);
- writeq(temp64, &bar0->general_int_mask);
/*
* Enable all the Tx side interrupts
* writing 0 Enables all 64 TX interrupt levels
@@ -1834,19 +1938,13 @@ static void en_dis_able_nic_intrs(struct
* register.
*/
writeq(DISABLE_ALL_INTRS, &bar0->tx_traffic_mask);
- temp64 = readq(&bar0->general_int_mask);
- val64 |= temp64;
- writeq(val64, &bar0->general_int_mask);
}
}
/* Rx traffic interrupts */
if (mask & RX_TRAFFIC_INTR) {
- val64 = RXTRAFFIC_INT_M;
+ intr_mask |= RXTRAFFIC_INT_M;
if (flag == ENABLE_INTRS) {
- temp64 = readq(&bar0->general_int_mask);
- temp64 &= ~((u64) val64);
- writeq(temp64, &bar0->general_int_mask);
/* writing 0 Enables all 8 RX interrupt levels */
writeq(0x0, &bar0->rx_traffic_mask);
} else if (flag == DISABLE_INTRS) {
@@ -1855,11 +1953,17 @@ static void en_dis_able_nic_intrs(struct
* register.
*/
writeq(DISABLE_ALL_INTRS, &bar0->rx_traffic_mask);
- temp64 = readq(&bar0->general_int_mask);
- val64 |= temp64;
- writeq(val64, &bar0->general_int_mask);
}
}
+
+ temp64 = readq(&bar0->general_int_mask);
+ if (flag == ENABLE_INTRS)
+ temp64 &= ~((u64) intr_mask);
+ else
+ temp64 = DISABLE_ALL_INTRS;
+ writeq(temp64, &bar0->general_int_mask);
+
+ nic->general_int_mask = readq(&bar0->general_int_mask);
}
/**
@@ -2063,14 +2167,6 @@ static int start_nic(struct s2io_nic *ni
writeq(val64, &bar0->adapter_control);
/*
- * Clearing any possible Link state change interrupts that
- * could have popped up just before Enabling the card.
- */
- val64 = readq(&bar0->mac_rmac_err_reg);
- if (val64)
- writeq(val64, &bar0->mac_rmac_err_reg);
-
- /*
* Verify if the device is ready to be enabled, if so enable
* it.
*/
@@ -2223,9 +2319,9 @@ static void stop_nic(struct s2io_nic *ni
config = &nic->config;
/* Disable all interrupts */
+ en_dis_err_alarms(nic, ENA_ALL_INTRS, DISABLE_INTRS);
interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
- interruptible |= TX_PIC_INTR | RX_PIC_INTR;
- interruptible |= TX_MAC_INTR | RX_MAC_INTR;
+ interruptible |= TX_PIC_INTR;
en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS);
/* Clearing Adapter_En bit of ADAPTER_CONTROL Register */
@@ -6670,12 +6766,12 @@ static int s2io_card_up(struct s2io_nic
tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev);
/* Enable select interrupts */
+ en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS);
if (sp->intr_type != INTA)
en_dis_able_nic_intrs(sp, ENA_ALL_INTRS, DISABLE_INTRS);
else {
interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
- interruptible |= TX_PIC_INTR | RX_PIC_INTR;
- interruptible |= TX_MAC_INTR | RX_MAC_INTR;
+ interruptible |= TX_PIC_INTR;
en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS);
}
diff -urpN org/drivers/net/s2io.h patch_1/drivers/net/s2io.h
--- org/drivers/net/s2io.h 2007-09-01 19:42:15.000000000 +0530
+++ patch_1/drivers/net/s2io.h 2007-09-01 18:43:38.000000000 +0530
@@ -892,6 +892,7 @@ struct s2io_nic {
spinlock_t rx_lock;
atomic_t isr_cnt;
+ u64 general_int_mask;
u64 *ufo_in_band_v;
#define VPD_STRING_LEN 80
u8 product_name[VPD_STRING_LEN];
diff -urpN org/drivers/net/s2io-regs.h patch_1/drivers/net/s2io-regs.h
--- org/drivers/net/s2io-regs.h 2007-09-01 19:42:15.000000000 +0530
+++ patch_1/drivers/net/s2io-regs.h 2007-09-01 18:43:38.000000000 +0530
@@ -325,33 +325,66 @@ struct XENA_dev_config {
#define TXDMA_TPA_INT BIT(5)
#define TXDMA_SM_INT BIT(6)
u64 pfc_err_reg;
+#define PFC_ECC_SG_ERR BIT(7)
+#define PFC_ECC_DB_ERR BIT(15)
+#define PFC_SM_ERR_ALARM BIT(23)
+#define PFC_MISC_0_ERR BIT(31)
+#define PFC_MISC_1_ERR BIT(32)
+#define PFC_PCIX_ERR BIT(39)
u64 pfc_err_mask;
u64 pfc_err_alarm;
u64 tda_err_reg;
+#define TDA_Fn_ECC_SG_ERR vBIT(0xff,0,8)
+#define TDA_Fn_ECC_DB_ERR vBIT(0xff,8,8)
+#define TDA_SM0_ERR_ALARM BIT(22)
+#define TDA_SM1_ERR_ALARM BIT(23)
+#define TDA_PCIX_ERR BIT(39)
u64 tda_err_mask;
u64 tda_err_alarm;
u64 pcc_err_reg;
-#define PCC_FB_ECC_DB_ERR vBIT(0xFF, 16, 8)
+#define PCC_FB_ECC_SG_ERR vBIT(0xFF,0,8)
+#define PCC_TXB_ECC_SG_ERR vBIT(0xFF,8,8)
+#define PCC_FB_ECC_DB_ERR vBIT(0xFF,16, 8)
+#define PCC_TXB_ECC_DB_ERR vBIT(0xff,24,8)
+#define PCC_SM_ERR_ALARM vBIT(0xff,32,8)
+#define PCC_WR_ERR_ALARM vBIT(0xff,40,8)
+#define PCC_N_SERR vBIT(0xff,48,8)
+#define PCC_6_COF_OV_ERR BIT(56)
+#define PCC_7_COF_OV_ERR BIT(57)
+#define PCC_6_LSO_OV_ERR BIT(58)
+#define PCC_7_LSO_OV_ERR BIT(59)
#define PCC_ENABLE_FOUR vBIT(0x0F,0,8)
-
u64 pcc_err_mask;
u64 pcc_err_alarm;
u64 tti_err_reg;
+#define TTI_ECC_SG_ERR BIT(7)
+#define TTI_ECC_DB_ERR BIT(15)
+#define TTI_SM_ERR_ALARM BIT(23)
u64 tti_err_mask;
u64 tti_err_alarm;
u64 lso_err_reg;
+#define LSO6_SEND_OFLOW BIT(12)
+#define LSO7_SEND_OFLOW BIT(13)
+#define LSO6_ABORT BIT(14)
+#define LSO7_ABORT BIT(15)
+#define LSO6_SM_ERR_ALARM BIT(22)
+#define LSO7_SM_ERR_ALARM BIT(23)
u64 lso_err_mask;
u64 lso_err_alarm;
u64 tpa_err_reg;
+#define TPA_TX_FRM_DROP BIT(7)
+#define TPA_SM_ERR_ALARM BIT(23)
+
u64 tpa_err_mask;
u64 tpa_err_alarm;
u64 sm_err_reg;
+#define SM_SM_ERR_ALARM BIT(15)
u64 sm_err_mask;
u64 sm_err_alarm;
@@ -450,22 +483,52 @@ struct XENA_dev_config {
#define RXDMA_INT_RTI_INT_M BIT(3)
u64 rda_err_reg;
+#define RDA_RXDn_ECC_SG_ERR vBIT(0xFF,0,8)
+#define RDA_RXDn_ECC_DB_ERR vBIT(0xFF,8,8)
+#define RDA_FRM_ECC_SG_ERR BIT(23)
+#define RDA_FRM_ECC_DB_N_AERR BIT(31)
+#define RDA_SM1_ERR_ALARM BIT(38)
+#define RDA_SM0_ERR_ALARM BIT(39)
+#define RDA_MISC_ERR BIT(47)
+#define RDA_PCIX_ERR BIT(55)
+#define RDA_RXD_ECC_DB_SERR BIT(63)
u64 rda_err_mask;
u64 rda_err_alarm;
u64 rc_err_reg;
+#define RC_PRCn_ECC_SG_ERR vBIT(0xFF,0,8)
+#define RC_PRCn_ECC_DB_ERR vBIT(0xFF,8,8)
+#define RC_FTC_ECC_SG_ERR BIT(23)
+#define RC_FTC_ECC_DB_ERR BIT(31)
+#define RC_PRCn_SM_ERR_ALARM vBIT(0xFF,32,8)
+#define RC_FTC_SM_ERR_ALARM BIT(47)
+#define RC_RDA_FAIL_WR_Rn vBIT(0xFF,48,8)
u64 rc_err_mask;
u64 rc_err_alarm;
u64 prc_pcix_err_reg;
+#define PRC_PCI_AB_RD_Rn vBIT(0xFF,0,8)
+#define PRC_PCI_DP_RD_Rn vBIT(0xFF,8,8)
+#define PRC_PCI_AB_WR_Rn vBIT(0xFF,16,8)
+#define PRC_PCI_DP_WR_Rn vBIT(0xFF,24,8)
+#define PRC_PCI_AB_F_WR_Rn vBIT(0xFF,32,8)
+#define PRC_PCI_DP_F_WR_Rn vBIT(0xFF,40,8)
u64 prc_pcix_err_mask;
u64 prc_pcix_err_alarm;
u64 rpa_err_reg;
+#define RPA_ECC_SG_ERR BIT(7)
+#define RPA_ECC_DB_ERR BIT(15)
+#define RPA_FLUSH_REQUEST BIT(22)
+#define RPA_SM_ERR_ALARM BIT(23)
+#define RPA_CREDIT_ERR BIT(31)
u64 rpa_err_mask;
u64 rpa_err_alarm;
u64 rti_err_reg;
+#define RTI_ECC_SG_ERR BIT(7)
+#define RTI_ECC_DB_ERR BIT(15)
+#define RTI_SM_ERR_ALARM BIT(23)
u64 rti_err_mask;
u64 rti_err_alarm;
@@ -582,17 +645,43 @@ struct XENA_dev_config {
#define MAC_INT_STATUS_RMAC_INT BIT(1)
u64 mac_tmac_err_reg;
-#define TMAC_ERR_REG_TMAC_ECC_DB_ERR BIT(15)
-#define TMAC_ERR_REG_TMAC_TX_BUF_OVRN BIT(23)
-#define TMAC_ERR_REG_TMAC_TX_CRI_ERR BIT(31)
+#define TMAC_ECC_SG_ERR BIT(7)
+#define TMAC_ECC_DB_ERR BIT(15)
+#define TMAC_TX_BUF_OVRN BIT(23)
+#define TMAC_TX_CRI_ERR BIT(31)
+#define TMAC_TX_SM_ERR BIT(39)
+#define TMAC_DESC_ECC_SG_ERR BIT(47)
+#define TMAC_DESC_ECC_DB_ERR BIT(55)
+
u64 mac_tmac_err_mask;
u64 mac_tmac_err_alarm;
u64 mac_rmac_err_reg;
-#define RMAC_ERR_REG_RX_BUFF_OVRN BIT(0)
-#define RMAC_ERR_REG_RTS_ECC_DB_ERR BIT(14)
-#define RMAC_ERR_REG_ECC_DB_ERR BIT(15)
-#define RMAC_LINK_STATE_CHANGE_INT BIT(31)
+#define RMAC_RX_BUFF_OVRN BIT(0)
+#define RMAC_FRM_RCVD_INT BIT(1)
+#define RMAC_UNUSED_INT BIT(2)
+#define RMAC_RTS_PNUM_ECC_SG_ERR BIT(5)
+#define RMAC_RTS_DS_ECC_SG_ERR BIT(6)
+#define RMAC_RD_BUF_ECC_SG_ERR BIT(7)
+#define RMAC_RTH_MAP_ECC_SG_ERR BIT(8)
+#define RMAC_RTH_SPDM_ECC_SG_ERR BIT(9)
+#define RMAC_RTS_VID_ECC_SG_ERR BIT(10)
+#define RMAC_DA_SHADOW_ECC_SG_ERR BIT(11)
+#define RMAC_RTS_PNUM_ECC_DB_ERR BIT(13)
+#define RMAC_RTS_DS_ECC_DB_ERR BIT(14)
+#define RMAC_RD_BUF_ECC_DB_ERR BIT(15)
+#define RMAC_RTH_MAP_ECC_DB_ERR BIT(16)
+#define RMAC_RTH_SPDM_ECC_DB_ERR BIT(17)
+#define RMAC_RTS_VID_ECC_DB_ERR BIT(18)
+#define RMAC_DA_SHADOW_ECC_DB_ERR BIT(19)
+#define RMAC_LINK_STATE_CHANGE_INT BIT(31)
+#define RMAC_RX_SM_ERR BIT(39)
+#define RMAC_SINGLE_ECC_ERR (BIT(5) | BIT(6) | BIT(7) |\
+ BIT(8) | BIT(9) | BIT(10)|\
+ BIT(11))
+#define RMAC_DOUBLE_ECC_ERR (BIT(13) | BIT(14) | BIT(15) |\
+ BIT(16) | BIT(17) | BIT(18)|\
+ BIT(19))
u64 mac_rmac_err_mask;
u64 mac_rmac_err_alarm;
@@ -750,6 +839,7 @@ struct XENA_dev_config {
BIT(17) | BIT(19))
#define MC_ERR_REG_ECC_ALL_DBL (BIT(10) | BIT(11) | BIT(12) |\
BIT(13) | BIT(18) | BIT(20))
+#define PLL_LOCK_N BIT(39)
u64 mc_err_mask;
u64 mc_err_alarm;
@@ -823,11 +913,17 @@ struct XENA_dev_config {
#define XGXS_INT_MASK_RXGXS BIT(1)
u64 xgxs_txgxs_err_reg;
-#define TXGXS_ECC_DB_ERR BIT(15)
+#define TXGXS_ECC_SG_ERR BIT(7)
+#define TXGXS_ECC_DB_ERR BIT(15)
+#define TXGXS_ESTORE_UFLOW BIT(31)
+#define TXGXS_TX_SM_ERR BIT(39)
+
u64 xgxs_txgxs_err_mask;
u64 xgxs_txgxs_err_alarm;
u64 xgxs_rxgxs_err_reg;
+#define RXGXS_ESTORE_OFLOW BIT(7)
+#define RXGXS_RX_SM_ERR BIT(39)
u64 xgxs_rxgxs_err_mask;
u64 xgxs_rxgxs_err_alarm;
^ permalink raw reply
* Re: net-26.24 broken with XFRM off
From: David Miller @ 2007-09-06 9:50 UTC (permalink / raw)
To: dada1; +Cc: divy, netdev, linux-kernel, takamiya
In-Reply-To: <20070906101326.34a81abb.dada1@cosmosbay.com>
From: Eric Dumazet <dada1@cosmosbay.com>
Date: Thu, 6 Sep 2007 10:13:26 +0200
> I believe this problem is known.
>
> Please check http://marc.info/?l=linux-netdev&m=118881627028135&w=2
I'll toss that fix into the tree, thanks.
^ permalink raw reply
* Re: [PATCH -mm 1/2] 3c59x: Fix uninitialized variable bug
From: Satyam Sharma @ 2007-09-06 9:55 UTC (permalink / raw)
To: Mark Hindley
Cc: Steffen Klassert, Linux Kernel Mailing List,
Linux Netdev Mailing List, Jeff Garzik
In-Reply-To: <20070904085331.GH5944@hindley.org.uk>
On Tue, 4 Sep 2007, Mark Hindley wrote:
> On Tue, Sep 04, 2007 at 02:09:47PM +0530, Satyam Sharma wrote:
> > Hi Steffen,
> >
> >
> > On Tue, 4 Sep 2007, Steffen Klassert wrote:
> >
> > > On Tue, Sep 04, 2007 at 03:45:55AM +0530, Satyam Sharma wrote:
> > > >
> > > > drivers/net/3c59x.c: In function 'vortex_up':
> > > > drivers/net/3c59x.c:1495: warning: 'err' may be used uninitialized in this function
> > >
> > > This came in with the recently applied 3c59x-check-return-of-pci_enable_device patch
> > > from Mark Hindley. I just compiled it on a PCI only machine so far, therefore I did
> > > not notice the warning yet.
> >
> > Hmm, the .config I built with had PCI=y as well. Probably a compiler
> > version difference -- Jeff also mentioned yesterday that some newer
> > GCC versions fail to warn about uninitialized variables cases.
> >
>
> Sorry, this is my bad. I have just checked: there is no warning with gcc
> 4.2 or 4.1, but 3.3 emits the warning.
This is a GCC bug (regression, actually, as you've found out) -- no two
ways about it. Although different from the kind Jeff mentioned couple days
back -- that was about wising GCC up to false positives and /not/ emitting
warnings. But here a genuine problem was not complained about, so this is
more serious. Do you plan to open up a bug at gcc.gnu.org/bugzilla/ ?
Satyam
^ permalink raw reply
* Re: BUG: scheduling while atomic: ifconfig/0x00000002/4170
From: Satyam Sharma @ 2007-09-06 8:41 UTC (permalink / raw)
To: Herbert Xu
Cc: Florian Lohoff, Linux Kernel Mailing List, Netdev,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, Michal Piotrowski,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
yi.zhu-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <20070906082301.GB21929-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
On Thu, 6 Sep 2007, Herbert Xu wrote:
> On Thu, Sep 06, 2007 at 10:32:33AM +0530, Satyam Sharma wrote:
> >
> > > > [ 382.529041] [<c02c8abc>] dev_close+0x24/0x67
> > > > [ 382.529052] [<e01f402b>] ieee80211_master_stop+0x4a/0x6d [mac80211]
>
> This is where the bug is. You cannot call dev_close from an
> atomic context as i33380211_master_stop does it within spin
> locks.
Doh, of course! I must be blind ... and wait_for_completion()'s
might_sleep() clearly didn't trigger earlier because Florian must've
had CONFIG_DEBUG_SPINLOCK_SLEEP off in his .config ...
^ permalink raw reply
* Re: BUG: scheduling while atomic: ifconfig/0x00000002/4170
From: Florian Lohoff @ 2007-09-06 8:38 UTC (permalink / raw)
To: Satyam Sharma
Cc: Herbert Xu, Linux Kernel Mailing List, Netdev, linux-wireless,
Michal Piotrowski, ipw3945-devel, yi.zhu
In-Reply-To: <alpine.LFD.0.999.0709061409120.3781@enigma.security.iitk.ac.in>
[-- Attachment #1: Type: text/plain, Size: 949 bytes --]
On Thu, Sep 06, 2007 at 02:11:46PM +0530, Satyam Sharma wrote:
> On Thu, 6 Sep 2007, Herbert Xu wrote:
>
> > On Thu, Sep 06, 2007 at 10:32:33AM +0530, Satyam Sharma wrote:
> > >
> > > > > [ 382.529041] [<c02c8abc>] dev_close+0x24/0x67
> > > > > [ 382.529052] [<e01f402b>] ieee80211_master_stop+0x4a/0x6d [mac80211]
> >
> > This is where the bug is. You cannot call dev_close from an
> > atomic context as i33380211_master_stop does it within spin
> > locks.
>
> Doh, of course! I must be blind ... and wait_for_completion()'s
> might_sleep() clearly didn't trigger earlier because Florian must've
> had CONFIG_DEBUG_SPINLOCK_SLEEP off in his .config ...
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
Exactly ...
Flo
--
Florian Lohoff flo@rfc822.org +49-171-2280134
Those who would give up a little freedom to get a little
security shall soon have neither - Benjamin Franklin
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: BUG: scheduling while atomic: ifconfig/0x00000002/4170
From: Herbert Xu @ 2007-09-06 8:23 UTC (permalink / raw)
To: Satyam Sharma
Cc: Florian Lohoff, Linux Kernel Mailing List, Netdev,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, Michal Piotrowski,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
yi.zhu-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <alpine.LFD.0.999.0709060923340.26804-cF9xTIDbLT5E1qDFBaZ7QYsk13R+tSIrn9A1Ff6Mc9Q@public.gmane.org>
On Thu, Sep 06, 2007 at 10:32:33AM +0530, Satyam Sharma wrote:
>
> > > [ 382.529041] [<c02c8abc>] dev_close+0x24/0x67
> > > [ 382.529052] [<e01f402b>] ieee80211_master_stop+0x4a/0x6d [mac80211]
This is where the bug is. You cannot call dev_close from an
atomic context as i33380211_master_stop does it within spin
locks.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: BUG: scheduling while atomic: ifconfig/0x00000002/4170
From: Herbert Xu @ 2007-09-06 8:20 UTC (permalink / raw)
To: Satyam Sharma
Cc: Florian Lohoff, Linux Kernel Mailing List, Netdev,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, Michal Piotrowski,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
yi.zhu-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <alpine.LFD.0.999.0709060923340.26804-cF9xTIDbLT5E1qDFBaZ7QYsk13R+tSIrn9A1Ff6Mc9Q@public.gmane.org>
On Thu, Sep 06, 2007 at 10:32:33AM +0530, Satyam Sharma wrote:
>
> Probably tangential, but Herbert, is the call to synchronize_rcu() in
> dev_deactivate() really correct?
Yes it's still correct as of today's tree. Of course patches
such as preemptible RCU may change things but they'll need to
audit this anyway.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: net-26.24 broken with XFRM off
From: Eric Dumazet @ 2007-09-06 8:13 UTC (permalink / raw)
To: Divy Le Ray; +Cc: David Miller, netdev, linux-kernel, takamiya
In-Reply-To: <46DFAB7F.7060406@chelsio.com>
On Thu, 06 Sep 2007 00:25:51 -0700
Divy Le Ray <divy@chelsio.com> wrote:
> Hi Dave,
>
> I get this error compiling net-2.6.24 with XFRM off:
>
> [root@aries net-2.6.24]# make O=/opt/build/net-2.6.24
> fatal: corrupted pack file
> .git/objects/pack/pack-39c494e9d4c6488e5911ee5c06926450679e6b78.pack
> fatal: corrupted pack file
> .git/objects/pack/pack-39c494e9d4c6488e5911ee5c06926450679e6b78.pack
> Using /mnt/net-2.6.24 as source for kernel
> GEN /opt/build/net-2.6.24/Makefile
> CHK include/linux/version.h
> CHK include/linux/utsrelease.h
> CALL /mnt/net-2.6.24/scripts/checksyscalls.sh
> CHK include/linux/compile.h
> GEN .version
> CHK include/linux/compile.h
> UPD include/linux/compile.h
> CC init/version.o
> LD init/built-in.o
> LD .tmp_vmlinux1
> net/built-in.o(.text+0x73ac2): In function `inet6_csk_xmit':
> : undefined reference to `flow_cache_genid'
> net/built-in.o(.text+0x73b9e): In function `inet6_csk_xmit':
> : undefined reference to `flow_cache_genid'
> make[1]: *** [.tmp_vmlinux1] Error 1
> make: *** [_all] Error 2
>
> I believe this commit introduced it:
> commit a85d5450ddeb959bdf9e4603f9c06e9d79217cfa
> Author: Noriaki TAKAMIYA <takamiya@po.ntts.co.jp>
> Date: Fri Aug 24 23:31:39 2007 -0700
>
> [IPV6] XFRM: Fix connected socket to use transformation.
>
Hi Divy
I believe this problem is known.
Please check http://marc.info/?l=linux-netdev&m=118881627028135&w=2
Eric
^ permalink raw reply
* net-26.24 broken with XFRM off
From: Divy Le Ray @ 2007-09-06 7:25 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-kernel, takamiya
Hi Dave,
I get this error compiling net-2.6.24 with XFRM off:
[root@aries net-2.6.24]# make O=/opt/build/net-2.6.24
fatal: corrupted pack file
.git/objects/pack/pack-39c494e9d4c6488e5911ee5c06926450679e6b78.pack
fatal: corrupted pack file
.git/objects/pack/pack-39c494e9d4c6488e5911ee5c06926450679e6b78.pack
Using /mnt/net-2.6.24 as source for kernel
GEN /opt/build/net-2.6.24/Makefile
CHK include/linux/version.h
CHK include/linux/utsrelease.h
CALL /mnt/net-2.6.24/scripts/checksyscalls.sh
CHK include/linux/compile.h
GEN .version
CHK include/linux/compile.h
UPD include/linux/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1
net/built-in.o(.text+0x73ac2): In function `inet6_csk_xmit':
: undefined reference to `flow_cache_genid'
net/built-in.o(.text+0x73b9e): In function `inet6_csk_xmit':
: undefined reference to `flow_cache_genid'
make[1]: *** [.tmp_vmlinux1] Error 1
make: *** [_all] Error 2
I believe this commit introduced it:
commit a85d5450ddeb959bdf9e4603f9c06e9d79217cfa
Author: Noriaki TAKAMIYA <takamiya@po.ntts.co.jp>
Date: Fri Aug 24 23:31:39 2007 -0700
[IPV6] XFRM: Fix connected socket to use transformation.
Cheers,
Divy
^ permalink raw reply
* Re: [PATCH] [sis900] convert to NAPI, WAS Re: pktgen terminating condition
From: Mandeep Singh Baines @ 2007-09-06 5:06 UTC (permalink / raw)
To: jamal
Cc: James Chapman, Mandeep Singh Baines, Daniele Venzano, davem,
rick.jones2, msb, netdev, grundler, robert.olsson, jeff, nhorman
In-Reply-To: <1189002087.4228.26.camel@localhost>
jamal (hadi@cyberus.ca) wrote:
> On Wed, 2007-05-09 at 14:55 +0100, James Chapman wrote:
>
> > Thanks Jamal. Yes, I'd already read your paper. I think my idea is
> > different to the ideas described in your paper
>
> I am hoping you can pick from the lessons of what has been tried and
> failed and the justification for critiqueing something as "Failed".
> If you have - i feel i accomplished something useful writting the paper.
>
> > and I'm in the process of
> > writing it up as an RFC to post to netdev.
>
> Please cc me if you want my feedback - I am backlogged by about 3000
> messages on netdev.
>
> > Briefly though, the driver's
> > ->poll() holds off doing netif_rx_complete() for 1-2 jiffies and keeps
> > itself in poll_on mode for that time, consuming no quota.
> > The net_rx
> > softirq processing loop is modified to detect the case when the only
> > devices in its poll list are doing no work (consuming no quota). The
> > driver's ->poll() samples jiffies while it is considering when to do the
> > netif_rx_complete() like your Parked state - no timers are used.
>
> Ok, so the difference seems to be you actually poll instead for those
> jiffies instead starting a timer in the parked state - is that right?
>
> > If I missed that this approach has already been tried before and
> > rejected, please let me know. I see better throughput and latency in my
> > packet forwarding and LAN setups using it.
>
> If you read the paper: There are no issues with high throughput - NAPI
> kicks in.
> The challenge to be overcome is at low traffic, if you have a real fast
> processor your cpu-cycles-used/bits-processed ratio is high....
I'm not sure cpu-cycles-used/bits-processed is the correct metric to use.
An alternative would be to look at cpu-cycles-used/unit-time (i.e.
CPU utilization or load) for a given bit-rate or packet-rate. This would
make an interesting graph.
At low packet-rate, CPU utilization is low so doing extra work per packet
is probably OK. Utilizing 2% of CPU vesus 1% is negligible. But at higher
rate, when there is more CPU utilization, using 40% of CPU versus 60% is
significant. I think the absolute different in CPU utilization is more
important than the relative difference. iow, 2% versus 1%, even though
a 2x difference in cpu-cycles/packet, is negligible compared to 40%
versus 60%.
> If you are polling (softirqs have high prio and depending on the cpu,
> there could be a few gazillion within those 1-2 jiffies), then isnt the
> end result still a high cpu-cycles used?
> Thats what the timer tries to avoid (do nothing until some deffered
> point).
Using a timer might also behave better in a tick-less (CONFIG_NO_HZ)
configuration.
> If you waste cpu cycles and poll, I can see that (to emphasize: For
> FastCPU-LowTraffic scenario), you will end up _not_ having latency
> issues i pointed out, but you surely have digressed from the original
> goal which is to address the cpu abuse at low traffic (because you abuse
> more cpu).
>
> One thing that may be valuable is to show that the timers and polls are
> not much different in terms of cpu abuse (It's theoretically not true,
> but reality may not match).
> The other thing is now hrestimers are on, can you try using a piece of
> hardware that can get those kicked and see if you see any useful results
> on latency.
>
> cheers,
> jamal
>
^ 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