* [PATCH v6] ipv6: fix problem with expired dst cache
From: Gao feng @ 2012-04-06 10:13 UTC (permalink / raw)
To: netdev; +Cc: davem, Gao feng
In-Reply-To: <1330064404-24763-1-git-send-email-gaofeng@cn.fujitsu.com>
If the ipv6 dst cache which copy from the dst generated by ICMPV6 RA packet.
this dst cache will not check expire because it has no RTF_EXPIRES flag.
So this dst cache will always be used until the dst gc run.
Change the struct dst_entry,add a union contains new pointer from and expires.
When rt6_info.rt6i_flags has no RTF_EXPIRES flag,the dst.expires has no use.
we can use this field to point to where the dst cache copy from.
The dst.from is only used in IPV6.
rt6_check_expired check if rt6_info.dst.from is expired.
ip6_rt_copy only set dst.from when the ort has flag RTF_ADDRCONF
and RTF_DEFAULT.then hold the ort.
ip6_dst_destroy release the ort.
Add some functions to operate the RTF_EXPIRES flag and expires(from) together.
and change the code to use these new adding functions.
Changes from v5:
modify ip6_route_add and ndisc_router_discovery to use new adding functions.
Only set dst.from when the ort has flag RTF_ADDRCONF
and RTF_DEFAULT.then hold the ort.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
include/net/dst.h | 6 +++-
include/net/ip6_fib.h | 42 +++++++++++++++++++++++++++++
net/ipv6/addrconf.c | 9 ++----
net/ipv6/ip6_fib.c | 9 +++---
net/ipv6/ndisc.c | 3 +-
net/ipv6/route.c | 71 ++++++++++++++++++++++++++++++------------------
6 files changed, 99 insertions(+), 41 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 59c5d18..ff4da42 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -36,7 +36,11 @@ struct dst_entry {
struct net_device *dev;
struct dst_ops *ops;
unsigned long _metrics;
- unsigned long expires;
+ union {
+ unsigned long expires;
+ /* point to where the dst_entry copied from */
+ struct dst_entry *from;
+ };
struct dst_entry *path;
struct neighbour __rcu *_neighbour;
#ifdef CONFIG_XFRM
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index b26bb81..c64778f 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -123,6 +123,48 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
return ((struct rt6_info *)dst)->rt6i_idev;
}
+static inline void rt6_clean_expires(struct rt6_info *rt)
+{
+ if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from)
+ dst_release(rt->dst.from);
+
+ rt->rt6i_flags &= ~RTF_EXPIRES;
+ rt->dst.expires = 0;
+}
+
+static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires)
+{
+ if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from)
+ dst_release(rt->dst.from);
+
+ rt->rt6i_flags |= RTF_EXPIRES;
+ rt->dst.expires = expires;
+}
+
+static inline void rt6_update_expires(struct rt6_info *rt, int timeout)
+{
+ if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from)
+ dst_release(rt->dst.from);
+
+ dst_set_expires(&rt->dst, timeout);
+ rt->rt6i_flags |= RTF_EXPIRES;
+}
+
+static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
+{
+ struct dst_entry *new = (struct dst_entry *) from;
+
+ if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) {
+ if (new == rt->dst.from)
+ return;
+ dst_release(rt->dst.from);
+ }
+
+ rt->rt6i_flags &= ~RTF_EXPIRES;
+ rt->dst.from = new;
+ dst_hold(new);
+}
+
struct fib6_walker_t {
struct list_head lh;
struct fib6_node *root, *node;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6a3bb60..7d5cb97 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -803,8 +803,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
ip6_del_rt(rt);
rt = NULL;
} else if (!(rt->rt6i_flags & RTF_EXPIRES)) {
- rt->dst.expires = expires;
- rt->rt6i_flags |= RTF_EXPIRES;
+ rt6_set_expires(rt, expires);
}
}
dst_release(&rt->dst);
@@ -1887,11 +1886,9 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
rt = NULL;
} else if (addrconf_finite_timeout(rt_expires)) {
/* not infinity */
- rt->dst.expires = jiffies + rt_expires;
- rt->rt6i_flags |= RTF_EXPIRES;
+ rt6_set_expires(rt, jiffies + rt_expires);
} else {
- rt->rt6i_flags &= ~RTF_EXPIRES;
- rt->dst.expires = 0;
+ rt6_clean_expires(rt);
}
} else if (valid_lft) {
clock_t expires = 0;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 5b27fbc..dbf6c10 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -673,11 +673,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
&rt->rt6i_gateway)) {
if (!(iter->rt6i_flags & RTF_EXPIRES))
return -EEXIST;
- iter->dst.expires = rt->dst.expires;
- if (!(rt->rt6i_flags & RTF_EXPIRES)) {
- iter->rt6i_flags &= ~RTF_EXPIRES;
- iter->dst.expires = 0;
- }
+ if (!(rt->rt6i_flags & RTF_EXPIRES))
+ rt6_clean_expires(iter);
+ else
+ rt6_set_expires(iter, rt->dst.expires);
return -EEXIST;
}
}
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 3dcdb81..176b469 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1264,8 +1264,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
}
if (rt)
- rt->dst.expires = jiffies + (HZ * lifetime);
-
+ rt6_set_expires(rt, jiffies + (HZ * lifetime));
if (ra_msg->icmph.icmp6_hop_limit) {
in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
if (rt)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 3992e26..27068be 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -62,7 +62,7 @@
#include <linux/sysctl.h>
#endif
-static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
+static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
const struct in6_addr *dest);
static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
static unsigned int ip6_default_advmss(const struct dst_entry *dst);
@@ -285,6 +285,10 @@ static void ip6_dst_destroy(struct dst_entry *dst)
rt->rt6i_idev = NULL;
in6_dev_put(idev);
}
+
+ if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from)
+ dst_release(dst->from);
+
if (peer) {
rt->rt6i_peer = NULL;
inet_putpeer(peer);
@@ -329,8 +333,17 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
static __inline__ int rt6_check_expired(const struct rt6_info *rt)
{
- return (rt->rt6i_flags & RTF_EXPIRES) &&
- time_after(jiffies, rt->dst.expires);
+ struct rt6_info *ort = NULL;
+
+ if (rt->rt6i_flags & RTF_EXPIRES) {
+ if (time_after(jiffies, rt->dst.expires))
+ return 1;
+ } else if (rt->dst.from) {
+ ort = (struct rt6_info *) rt->dst.from;
+ return (ort->rt6i_flags & RTF_EXPIRES) &&
+ time_after(jiffies, ort->dst.expires);
+ }
+ return 0;
}
static inline int rt6_need_strict(const struct in6_addr *daddr)
@@ -620,12 +633,11 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
(rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
if (rt) {
- if (!addrconf_finite_timeout(lifetime)) {
- rt->rt6i_flags &= ~RTF_EXPIRES;
- } else {
- rt->dst.expires = jiffies + HZ * lifetime;
- rt->rt6i_flags |= RTF_EXPIRES;
- }
+ if (!addrconf_finite_timeout(lifetime))
+ rt6_clean_expires(rt);
+ else
+ rt6_set_expires(rt, jiffies + HZ * lifetime);
+
dst_release(&rt->dst);
}
return 0;
@@ -730,7 +742,7 @@ int ip6_ins_rt(struct rt6_info *rt)
return __ip6_ins_rt(rt, &info);
}
-static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort,
+static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort,
const struct in6_addr *daddr,
const struct in6_addr *saddr)
{
@@ -954,10 +966,10 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
rt->rt6i_idev = ort->rt6i_idev;
if (rt->rt6i_idev)
in6_dev_hold(rt->rt6i_idev);
- rt->dst.expires = 0;
rt->rt6i_gateway = ort->rt6i_gateway;
- rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES;
+ rt->rt6i_flags = ort->rt6i_flags;
+ rt6_clean_expires(rt);
rt->rt6i_metric = 0;
memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
@@ -1019,10 +1031,9 @@ static void ip6_link_failure(struct sk_buff *skb)
rt = (struct rt6_info *) skb_dst(skb);
if (rt) {
- if (rt->rt6i_flags & RTF_CACHE) {
- dst_set_expires(&rt->dst, 0);
- rt->rt6i_flags |= RTF_EXPIRES;
- } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT))
+ if (rt->rt6i_flags & RTF_CACHE)
+ rt6_update_expires(rt, 0);
+ else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT))
rt->rt6i_node->fn_sernum = -1;
}
}
@@ -1289,9 +1300,12 @@ int ip6_route_add(struct fib6_config *cfg)
}
rt->dst.obsolete = -1;
- rt->dst.expires = (cfg->fc_flags & RTF_EXPIRES) ?
- jiffies + clock_t_to_jiffies(cfg->fc_expires) :
- 0;
+
+ if (cfg->fc_flags & RTF_EXPIRES)
+ rt6_set_expires(rt, jiffies +
+ clock_t_to_jiffies(cfg->fc_expires));
+ else
+ rt6_clean_expires(rt);
if (cfg->fc_protocol == RTPROT_UNSPEC)
cfg->fc_protocol = RTPROT_BOOT;
@@ -1736,8 +1750,8 @@ again:
features |= RTAX_FEATURE_ALLFRAG;
dst_metric_set(&rt->dst, RTAX_FEATURES, features);
}
- dst_set_expires(&rt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires);
- rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES;
+ rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires);
+ rt->rt6i_flags |= RTF_MODIFIED;
goto out;
}
@@ -1765,9 +1779,8 @@ again:
* which is 10 mins. After 10 mins the decreased pmtu is expired
* and detecting PMTU increase will be automatically happened.
*/
- dst_set_expires(&nrt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires);
- nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES;
-
+ rt6_update_expires(nrt, net->ipv6.sysctl.ip6_rt_mtu_expires);
+ nrt->rt6i_flags |= RTF_DYNAMIC;
ip6_ins_rt(nrt);
}
out:
@@ -1799,7 +1812,7 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad
* Misc support functions
*/
-static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
+static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
const struct in6_addr *dest)
{
struct net *net = dev_net(ort->dst.dev);
@@ -1819,10 +1832,14 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
if (rt->rt6i_idev)
in6_dev_hold(rt->rt6i_idev);
rt->dst.lastuse = jiffies;
- rt->dst.expires = 0;
rt->rt6i_gateway = ort->rt6i_gateway;
- rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES;
+ rt->rt6i_flags = ort->rt6i_flags;
+ if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ==
+ (RTF_DEFAULT | RTF_ADDRCONF))
+ rt6_set_from(rt, ort);
+ else
+ rt6_clean_expires(rt);
rt->rt6i_metric = 0;
#ifdef CONFIG_IPV6_SUBTREES
--
1.7.7.6
^ permalink raw reply related
* Re: [E1000-devel] e1000e interface hang on 82574L
From: Chris Boot @ 2012-04-06 10:17 UTC (permalink / raw)
To: Nix; +Cc: Wyborny, Carolyn, e1000-devel, netdev, lkml, Bjorn Helgaas,
linux-pci
In-Reply-To: <87ehsov6ot.fsf@spindle.srvr.nix>
On 19 Mar 2012, at 17:31, Nix wrote:
> On 19 Mar 2012, Carolyn Wyborny said:
>
>>> you'll see that I tested that, and it doesn't work :( even if it did
>>> work, it shouldn't be needed: the driver attempts to turn off PCIe ASPM
>>> on affected NICs, and fails, apparently because *something* turns it
>>> back on again.
>>>
>> The driver attempts to disable L0s state, not the entire feature. It
>
> It tries to disable L1 state as well (or it did when I tested this last,
> although I suspect you're right and it may leave L1 turned on these
> days: judging by the contents of e1000_82574_info, anyway.)
>
>> is also required that the device upstream on the bus from the 82574L
>> have this disabled. Yes, I agree there appears to be something in the
>> os that either ren-enables or fails to disable the feature on the
>> upstream device, as desired. Platforms/systems also appear to vary in
>> this regard, so the solutions may vary a bit as well.
>>
>> Its worth trying your solution as well if what I suggested doesn't
>> work, but there is not one solution that fits all, unfortunately.
>
> I don't *have* a solution. :( 'setpci by hand some unknown amount of
> time after booting once the interface has stabilized' hardly counts as a
> solution of any sort. It's, at best, a workaround that lets me use my
> systems without hourly lockups until a real solution is found.
>
> (To clarify: manual setpci to force off the ASPM bits is the only thing
> that works for me. The driver's automatic disabling of L0s and L1
> doesn't work: nor does booting with pcie_aspm=off. In both cases, I end
> up with both L0s and L1 turned on, and a lockup some time later, unless
> I setpci the bits off by hand.)
Well, with that setpci incantation run against the NIC and its upstream device to disable ASPM L1s (setpci -s <dev> CAP_EXP+10.b=40), everything has been working very well indeed. Is there something the e1000e driver could do to disable L1s as well as L0s if we know there's a problem with them for these devices?
Adding Bjorn Helgaas and linux-pci to CCs to try to get the ball rolling some more, as this is crippling without the fixes.
Cheers,
Chris
--
Chris Boot
bootc@bootc.net
^ permalink raw reply
* Re: [PATCH net-next #2 10/39] fealnx: stop using net_device.{base_addr, irq}.
From: David Miller @ 2012-04-06 10:21 UTC (permalink / raw)
To: romieu; +Cc: netdev
In-Reply-To: <7db239c57d31d1d3fdc73e22b27ed9c46fc1da65.1333704409.git.romieu@fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 6 Apr 2012 12:06:24 +0200
> - if (request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev))
> - return -EAGAIN;
> + rc = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
> + if (rc < 0)
> + goto out;
Please at least preserve the test, make it "if (rc)"
^ permalink raw reply
* Re: [PATCH net-next #2 27/39] smsc9420: stop using net_device.{base_addr, irq}.
From: David Miller @ 2012-04-06 10:23 UTC (permalink / raw)
To: romieu; +Cc: netdev, steve.glendinning
In-Reply-To: <722b2708e6b621a33fe8f778ea35e1f0ddb4636a.1333704409.git.romieu@fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 6 Apr 2012 12:06:41 +0200
> - if (request_irq(dev->irq, smsc9420_isr, IRQF_SHARED | IRQF_DISABLED,
> - DRV_NAME, pd)) {
> - smsc_warn(IFUP, "Unable to use IRQ = %d", dev->irq);
> - result = -ENODEV;
> + result = request_irq(irq, smsc9420_isr, IRQF_SHARED | IRQF_DISABLED,
> + DRV_NAME, pd);
> + if (result < 0) {
> + smsc_warn(IFUP, "Unable to use IRQ = %d", irq);
Another case where you should preserve the nature of
the test, make this "if (result)"
^ permalink raw reply
* Re: [PATCH net-next #2 32/39] epic100: stop using net_device.{base_addr, irq} and convert to __iomem.
From: David Miller @ 2012-04-06 10:25 UTC (permalink / raw)
To: romieu; +Cc: netdev
In-Reply-To: <6b7afbabfb5dc03aca2fea47cae8db27239bb589.1333704409.git.romieu@fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 6 Apr 2012 12:06:46 +0200
> napi_enable(&ep->napi);
> - if ((retval = request_irq(dev->irq, epic_interrupt, IRQF_SHARED, dev->name, dev))) {
> + rc = request_irq(irq, epic_interrupt, IRQF_SHARED, dev->name, dev);
> + if (rc < 0) {
Please preserve the test: "if (rc)"
^ permalink raw reply
* Re: [PATCH net-next #2 00/39] net_device.{base_addr, irq} removal update
From: David Miller @ 2012-04-06 10:26 UTC (permalink / raw)
To: romieu
Cc: netdev, gallatin, andy, chris.snook, venza, DavidLv,
grantgrundler, ionut, jcliburn, jdmason, mason, mchan,
stas.yakovlev, steve.glendinning, thockin
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 6 Apr 2012 12:06:14 +0200
> If there are no further changes, I'll rebase and send a single pull request
> for the series including Grant's Acked-by once he says it is ok.
Besides the request_irq() return value test issues, this series
seems fine to me.
^ permalink raw reply
* Re: ipv6: tunnel: hang when destroying ipv6 tunnel
From: Tetsuo Handa @ 2012-04-06 11:44 UTC (permalink / raw)
To: levinsasha928, garlick, ericvh
Cc: oleg, eric.dumazet, davem, kuznet, jmorris, yoshfuji, kaber,
netdev, linux-kernel, davej
In-Reply-To: <201204052329.EBH52139.FFOLQMOJSVHOFt@I-love.SAKURA.ne.jp>
Tetsuo Handa wrote:
> Most suspicious change is net/9p/client.c because it is changing handling of
> ERESTARTSYS case.
>
> --- linux-3.3.1/net/9p/client.c
> +++ linux-next/net/9p/client.c
> @@ -740,10 +740,18 @@
> c->status = Disconnected;
> goto reterr;
> }
> +again:
> /* Wait for the response */
> err = wait_event_interruptible(*req->wq,
> req->status >= REQ_STATUS_RCVD);
>
> + if ((err == -ERESTARTSYS) && (c->status == Connected)
> + && (type == P9_TFLUSH)) {
> + sigpending = 1;
> + clear_thread_flag(TIF_SIGPENDING);
> + goto again;
> + }
> +
I think this loop is bad with regard to response to SIGKILL.
If wait_event_interruptible() was interrupted by SIGKILL, it will
spin until req->status >= REQ_STATUS_RCVD becomes true.
Rather,
if ((c->status == Connected) && (type == P9_TFLUSH))
err = wait_event_killable(*req->wq,
req->status >= REQ_STATUS_RCVD);
else
err = wait_event_interruptible(*req->wq,
req->status >= REQ_STATUS_RCVD);
would be safer.
> error:
> /*
> * Fid is not valid even after a failed clunk
> + * If interrupted, retry once then give up and
> + * leak fid until umount.
> */
> - p9_fid_destroy(fid);
> + if (err == -ERESTARTSYS) {
> + if (retries++ == 0)
> + goto again;
I think it is possible that the process is interrupted again upon retrying.
I suspect the handling of err == -ERESTARTSYS case when retries != 0.
It is returning without calling p9_fid_destroy(), which will be
unexpected behaviour for the various callers.
> + } else
> + p9_fid_destroy(fid);
> return err;
> }
> EXPORT_SYMBOL(p9_client_clunk);
^ permalink raw reply
* Re: [PATCH net-next #2 35/39] myri10ge: stop using net_device.{base_addr, irq}.
From: Andrew Gallatin @ 2012-04-06 11:48 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev, David Miller, Jon Mason
In-Reply-To: <a5a6d0922ea55d7c8e7792633135e8cb94ccd1c2.1333704409.git.romieu@fr.zoreil.com>
On 04/06/12 06:06, Francois Romieu wrote:
> Signed-off-by: Francois Romieu<romieu@fr.zoreil.com>
> Cc: Jon Mason<mason@myri.com>
> Cc: Andrew Gallatin<gallatin@myri.com>
> ---
> drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 7 ++-----
> 1 files changed, 2 insertions(+), 5 deletions(-)
>
Acked-by: Andrew Gallatin<gallatin@myri.com>
^ permalink raw reply
* Re: [E1000-devel] e1000e interface hang on 82574L
From: Bjorn Helgaas @ 2012-04-06 12:12 UTC (permalink / raw)
To: Chris Boot
Cc: Nix, Wyborny, Carolyn, e1000-devel, netdev, lkml, linux-pci,
Matthew Garrett
In-Reply-To: <1590F833-7D40-42FE-8FA2-6DCCADF9C6B0@bootc.net>
On Fri, Apr 6, 2012 at 4:17 AM, Chris Boot <bootc@bootc.net> wrote:
> On 19 Mar 2012, at 17:31, Nix wrote:
>
>> On 19 Mar 2012, Carolyn Wyborny said:
>>
>>>> you'll see that I tested that, and it doesn't work :( even if it did
>>>> work, it shouldn't be needed: the driver attempts to turn off PCIe ASPM
>>>> on affected NICs, and fails, apparently because *something* turns it
>>>> back on again.
>>>>
>>> The driver attempts to disable L0s state, not the entire feature. It
>>
>> It tries to disable L1 state as well (or it did when I tested this last,
>> although I suspect you're right and it may leave L1 turned on these
>> days: judging by the contents of e1000_82574_info, anyway.)
>>
>>> is also required that the device upstream on the bus from the 82574L
>>> have this disabled. Yes, I agree there appears to be something in the
>>> os that either ren-enables or fails to disable the feature on the
>>> upstream device, as desired. Platforms/systems also appear to vary in
>>> this regard, so the solutions may vary a bit as well.
>>>
>>> Its worth trying your solution as well if what I suggested doesn't
>>> work, but there is not one solution that fits all, unfortunately.
>>
>> I don't *have* a solution. :( 'setpci by hand some unknown amount of
>> time after booting once the interface has stabilized' hardly counts as a
>> solution of any sort. It's, at best, a workaround that lets me use my
>> systems without hourly lockups until a real solution is found.
>>
>> (To clarify: manual setpci to force off the ASPM bits is the only thing
>> that works for me. The driver's automatic disabling of L0s and L1
>> doesn't work: nor does booting with pcie_aspm=off. In both cases, I end
>> up with both L0s and L1 turned on, and a lockup some time later, unless
>> I setpci the bits off by hand.)
>
>
> Well, with that setpci incantation run against the NIC and its upstream device to disable ASPM L1s (setpci -s <dev> CAP_EXP+10.b=40), everything has been working very well indeed. Is there something the e1000e driver could do to disable L1s as well as L0s if we know there's a problem with them for these devices?
>
> Adding Bjorn Helgaas and linux-pci to CCs to try to get the ball rolling some more, as this is crippling without the fixes.
[+cc Matthew Garrett for ASPM stuff]
If I understand correctly, e1000e attempts to disable ASPM to work
around an 82574L hardware erratum, but the PCI core either doesn't
disable ASPM or it gets re-enabled somehow.
^ permalink raw reply
* Re: e1000e interface hang on 82574L
From: Henrique de Moraes Holschuh @ 2012-04-06 13:41 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Chris Boot, e1000-devel, netdev, lkml, Nix, linux-pci,
Matthew Garrett
In-Reply-To: <CAErSpo4TJ-9NsD5QTpFi9fsnD9qHt7+Tr5jJHQPuS7vg6ghq_w@mail.gmail.com>
On Fri, 06 Apr 2012, Bjorn Helgaas wrote:
> On Fri, Apr 6, 2012 at 4:17 AM, Chris Boot <bootc@bootc.net> wrote:
> > On 19 Mar 2012, at 17:31, Nix wrote:
> >
> >> On 19 Mar 2012, Carolyn Wyborny said:
> >>
> >>>> you'll see that I tested that, and it doesn't work :( even if it
> >>>> did work, it shouldn't be needed: the driver attempts to turn off
> >>>> PCIe ASPM on affected NICs, and fails, apparently because
> >>>> *something* turns it back on again.
> >>>>
> >>> The driver attempts to disable L0s state, not the entire feature.
> >>> It
> >>
> >> It tries to disable L1 state as well (or it did when I tested this
> >> last, although I suspect you're right and it may leave L1 turned on
> >> these days: judging by the contents of e1000_82574_info, anyway.)
> >>
> >>> is also required that the device upstream on the bus from the
> >>> 82574L have this disabled. Yes, I agree there appears to be
> >>> something in the os that either ren-enables or fails to disable
> >>> the feature on the upstream device, as desired. Platforms/systems
> >>> also appear to vary in this regard, so the solutions may vary a
> >>> bit as well.
> >>>
> >>> Its worth trying your solution as well if what I suggested doesn't
> >>> work, but there is not one solution that fits all, unfortunately.
> >>
> >> I don't *have* a solution. :( 'setpci by hand some unknown amount
> >> of time after booting once the interface has stabilized' hardly
> >> counts as a solution of any sort. It's, at best, a workaround that
> >> lets me use my systems without hourly lockups until a real solution
> >> is found.
> >>
> >> (To clarify: manual setpci to force off the ASPM bits is the only
> >> thing that works for me. The driver's automatic disabling of L0s
> >> and L1 doesn't work: nor does booting with pcie_aspm=off. In both
> >> cases, I end up with both L0s and L1 turned on, and a lockup some
> >> time later, unless I setpci the bits off by hand.)
> >
> >
> > Well, with that setpci incantation run against the NIC and its
> > upstream device to disable ASPM L1s (setpci -s <dev>
> > CAP_EXP+10.b=40), everything has been working very well indeed. Is
> > there something the e1000e driver could do to disable L1s as well as
> > L0s if we know there's a problem with them for these devices?
> >
> > Adding Bjorn Helgaas and linux-pci to CCs to try to get the ball
> > rolling some more, as this is crippling without the fixes.
>
> [+cc Matthew Garrett for ASPM stuff]
>
> If I understand correctly, e1000e attempts to disable ASPM to work
> around an 82574L hardware erratum, but the PCI core either doesn't
> disable ASPM or it gets re-enabled somehow.
You probably need to disable it upstream of the 82574L as well. Here
(SuperMicro C7X58) I managed to get it to be stable by telling the BIOS
to disable L0s and L1 system-wide.
But not all BIOSes will have that option...
--
"One disk to rule them all, One disk to find them. One disk to bring
them all and in the darkness grind them. In the Land of Redmond
where the shadows lie." -- The Silicon Valley Tarot
Henrique Holschuh
------------------------------------------------------------------------------
For Developers, A Lot Can Happen In A Second.
Boundary is the first to Know...and Tell You.
Monitor Your Applications in Ultra-Fine Resolution. Try it FREE!
http://p.sf.net/sfu/Boundary-d2dvs2
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: e1000e interface hang on 82574L
From: Chris Boot @ 2012-04-06 13:48 UTC (permalink / raw)
To: Henrique de Moraes Holschuh
Cc: e1000-devel, netdev, lkml, Nix, linux-pci, Bjorn Helgaas,
Matthew Garrett
In-Reply-To: <20120406134144.GA22526@khazad-dum.debian.net>
On 6 Apr 2012, at 14:41, Henrique de Moraes Holschuh <hmh@hmh.eng.br> wrote:
> On Fri, 06 Apr 2012, Bjorn Helgaas wrote:
>> On Fri, Apr 6, 2012 at 4:17 AM, Chris Boot <bootc@bootc.net> wrote:
>>> On 19 Mar 2012, at 17:31, Nix wrote:
>>>
>>>> On 19 Mar 2012, Carolyn Wyborny said:
>>>>
>>>>>> you'll see that I tested that, and it doesn't work :( even if it
>>>>>> did work, it shouldn't be needed: the driver attempts to turn off
>>>>>> PCIe ASPM on affected NICs, and fails, apparently because
>>>>>> *something* turns it back on again.
>>>>>>
>>>>> The driver attempts to disable L0s state, not the entire feature.
>>>>> It
>>>>
>>>> It tries to disable L1 state as well (or it did when I tested this
>>>> last, although I suspect you're right and it may leave L1 turned on
>>>> these days: judging by the contents of e1000_82574_info, anyway.)
>>>>
>>>>> is also required that the device upstream on the bus from the
>>>>> 82574L have this disabled. Yes, I agree there appears to be
>>>>> something in the os that either ren-enables or fails to disable
>>>>> the feature on the upstream device, as desired. Platforms/systems
>>>>> also appear to vary in this regard, so the solutions may vary a
>>>>> bit as well.
>>>>>
>>>>> Its worth trying your solution as well if what I suggested doesn't
>>>>> work, but there is not one solution that fits all, unfortunately.
>>>>
>>>> I don't *have* a solution. :( 'setpci by hand some unknown amount
>>>> of time after booting once the interface has stabilized' hardly
>>>> counts as a solution of any sort. It's, at best, a workaround that
>>>> lets me use my systems without hourly lockups until a real solution
>>>> is found.
>>>>
>>>> (To clarify: manual setpci to force off the ASPM bits is the only
>>>> thing that works for me. The driver's automatic disabling of L0s
>>>> and L1 doesn't work: nor does booting with pcie_aspm=off. In both
>>>> cases, I end up with both L0s and L1 turned on, and a lockup some
>>>> time later, unless I setpci the bits off by hand.)
>>>
>>>
>>> Well, with that setpci incantation run against the NIC and its
>>> upstream device to disable ASPM L1s (setpci -s <dev>
>>> CAP_EXP+10.b=40), everything has been working very well indeed. Is
>>> there something the e1000e driver could do to disable L1s as well as
>>> L0s if we know there's a problem with them for these devices?
>>>
>>> Adding Bjorn Helgaas and linux-pci to CCs to try to get the ball
>>> rolling some more, as this is crippling without the fixes.
>>
>> [+cc Matthew Garrett for ASPM stuff]
>>
>> If I understand correctly, e1000e attempts to disable ASPM to work
>> around an 82574L hardware erratum, but the PCI core either doesn't
>> disable ASPM or it gets re-enabled somehow.
>
> You probably need to disable it upstream of the 82574L as well. Here
> (SuperMicro C7X58) I managed to get it to be stable by telling the BIOS
> to disable L0s and L1 system-wide.
>
> But not all BIOSes will have that option...
This is not something I can really do as ASPM makes a real difference to power consumption across the system, and I have a strict power budget to adhere to (else I will be charged more to host my servers). Disabling it for the NIC and upstream device is enough to make it stable, and doesn't increase power consumption by enough to matter.
The driver seems to disable ASPM L0s just fine, but L1s are not disabled on the NIC nor are they on the upstream device. If e1000e can't do it maybe we can do so using a PCI quirk or something?
Cheers,
Chris
--
Chris Boot
bootc@bootc.net
------------------------------------------------------------------------------
For Developers, A Lot Can Happen In A Second.
Boundary is the first to Know...and Tell You.
Monitor Your Applications in Ultra-Fine Resolution. Try it FREE!
http://p.sf.net/sfu/Boundary-d2dvs2
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* yield() in netlink_broadcast_filtered
From: Fredrick @ 2012-04-06 14:11 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet
I see there is a yield being called from
netlink_broadcast_filtered.
.....
int netlink_broadcast_filtered(...)
{
....
if (info.delivered) {
if (info.congested && (allocation & __GFP_WAIT))
yield();
return 0;
}
return -ESRCH;
}
.....
But I don't see the point of calling it.
After the yield, there is nothing being done.
It just returns. So why yield ?
Why can't it simply return?
-Fredrick
^ permalink raw reply
* Re: yield() in netlink_broadcast_filtered
From: Stephen Hemminger @ 2012-04-06 15:05 UTC (permalink / raw)
To: Fredrick; +Cc: netdev, eric.dumazet
In-Reply-To: <4F7EF9AC.8050305@zoho.com>
On Fri, 06 Apr 2012 07:11:56 -0700
Fredrick <fjohnber@zoho.com> wrote:
>
>
> I see there is a yield being called from
> netlink_broadcast_filtered.
> .....
> int netlink_broadcast_filtered(...)
> {
> ....
> if (info.delivered) {
> if (info.congested && (allocation & __GFP_WAIT))
> yield();
> return 0;
> }
> return -ESRCH;
> }
> .....
>
> But I don't see the point of calling it.
> After the yield, there is nothing being done.
> It just returns. So why yield ?
> Why can't it simply return?
>
Because without that yield it is easily possible for one process
to generate lots of netlink messages and overrun the consumers.
The yield allows the now ready listening processes to run.
There is no good mechanism to totally prevent overrunning the
socket of processes reading for netlink events, but this yield()
is good enough to avoid the problem with the typical case.
The example we are familar with is a full route table (1M routes)
and a link change causing a routing flap.
^ permalink raw reply
* Re: [PATCH net-next #2 17/39] bnx2: stop using net_device.{base_addr, irq}.
From: Michael Chan @ 2012-04-06 15:07 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev, David Miller
In-Reply-To: <3958bafae0bfb262eda364adebf21aebb25af69a.1333704409.git.romieu@fr.zoreil.com>
On Fri, 2012-04-06 at 12:06 +0200, Francois Romieu wrote:
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Michael Chan <mchan@broadcom.com>
Acked-by: Michael Chan <mchan@broadcom.com>
^ permalink raw reply
* Re: Expose ltr/obff interface by sysfs
From: Jesse Barnes @ 2012-04-06 15:26 UTC (permalink / raw)
To: Hao, Xudong
Cc: linux-pci@vger.kernel.org, netdev@vger.kernel.org,
e1000-devel@lists.sourceforge.net
In-Reply-To: <403610A45A2B5242BD291EDAE8B37D300FD0A434@SHSMSX102.ccr.corp.intel.com>
[-- Attachment #1: Type: text/plain, Size: 1673 bytes --]
On Fri, 6 Apr 2012 02:43:59 +0000
"Hao, Xudong" <xudong.hao@intel.com> wrote:
> Hi,
>
> I'm working on virtualization Xen/KVM. I saw there are ltr/obff enabling/disabling function in pci.c, but no called till now. I want to know if anybody(driver developer) are working for using it? Can driver change the LTR latency value dynamically?
I believe the value is writable, but I'd expect some devices to
misbehave if the value were programmed too high. Performance would
also suffer if the value were set too high, at least for IOPS sensitive
devices.
> /*
> LTR(Latency tolerance reporting) allows devices to send messages to the root complex indicating their latency tolerance for snooped & unsnooped memory transactions.
> OBFF (optimized buffer flush/fill), where supported, can help improve energy efficiency by giving devices information about when interrupts and other activity will have a reduced power impact.
> */
>
> One way to control ltr/obff is used by driver, however, I'm considering that in virtualization, how guest OS driver control them. I have an idea that expose an inode interface by sysfs, like "reset" inode implemented in pci-sysfs.c, so that system user/administrator can enable/disable ltr/obff or set latency value on userspace, but not limited on driver. Comments?
Given how device specific these extensions are, I'd expect you'd need
to know about each specific device anyway, which is why I think the
control belongs in the driver. I don't see why you'd need to
enable/disable/change these functions when assigning a device from one
guest to another...
--
Jesse Barnes, Intel Open Source Technology Center
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
From: Glauber Costa @ 2012-04-06 15:49 UTC (permalink / raw)
To: KAMEZAWA Hiroyuki; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F750FE8.2030800@jp.fujitsu.com>
[-- Attachment #1: Type: text/plain, Size: 1297 bytes --]
On 03/30/2012 05:44 AM, KAMEZAWA Hiroyuki wrote:
> Maybe what we can do before lsf/mm summit will be this (avoid warning.)
> This patch is onto linus's git tree. Patch description is updated.
>
> Thanks.
> -Kame
> ==
> From 4ab80f84bbcb02a790342426c1de84aeb17fcbe9 Mon Sep 17 00:00:00 2001
> From: KAMEZAWA Hiroyuki<kamezawa.hiroyu@jp.fujitsu.com>
> Date: Thu, 29 Mar 2012 14:59:04 +0900
> Subject: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
>
> tcp memcontrol starts accouting after res->limit is set. So, if a sockets
> starts before setting res->limit, there are already used resource.
> At setting res->limit, accounting starts. The resource will be uncharged
> and make res_counter below 0 because they are not charged.
> This causes warning.
>
Kame,
Please test the following patch and see if it fixes your problems (I
tested locally, and it triggers me no warnings running the test script
you provided + an inbound scp -r copy of an iso directory from a remote
machine)
When you are reviewing, keep in mind that we're likely to have the same
problems with slab jump labels - since the slab pages will outlive the
cgroup as well, and it might be worthy to keep this in mind, and provide
a central point for the jump labels to be set of on cgroup destruction.
[-- Attachment #2: 0001-decrement-static-keys-on-real-destroy-time.patch --]
[-- Type: text/x-patch, Size: 3892 bytes --]
>From c40bbd69cbb655b6389c2398ce89abb06e64910d Mon Sep 17 00:00:00 2001
From: Glauber Costa <glommer@parallels.com>
Date: Wed, 4 Apr 2012 21:08:38 +0400
Subject: [PATCH] decrement static keys on real destroy time
We call the destroy function when a cgroup starts to be removed,
such as by a rmdir event.
However, because of our reference counters, some objects are still
inflight. Right now, we are decrementing the static_keys at destroy()
time, meaning that if we get rid of the last static_key reference,
some objects will still have charges, but the code to properly
uncharge them won't be run.
This becomes a problem specially if it is ever enabled again, because
now new charges will be added to the staled charges making keeping
it pretty much impossible.
Signed-off-by: Glauber Costa <glommer@parallels.com>
---
include/net/tcp_memcontrol.h | 2 ++
mm/memcontrol.c | 15 +++++++++++++++
net/ipv4/tcp_memcontrol.c | 10 ++++------
3 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/include/net/tcp_memcontrol.h b/include/net/tcp_memcontrol.h
index 7df18bc..5a2b915 100644
--- a/include/net/tcp_memcontrol.h
+++ b/include/net/tcp_memcontrol.h
@@ -9,6 +9,8 @@ struct tcp_memcontrol {
/* those two are read-mostly, leave them at the end */
long tcp_prot_mem[3];
int tcp_memory_pressure;
+ /* if this cgroup was ever limited, having static_keys activated */
+ bool limited;
};
struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 64a1bcd..74b757b 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -442,6 +442,15 @@ void sock_release_memcg(struct sock *sk)
}
}
+static void disarm_static_keys(struct mem_cgroup *memcg)
+{
+#ifdef CONFIG_INET
+ if (memcg->tcp_mem.limited)
+ static_key_slow_dec(&memcg_socket_limit_enabled);
+#endif
+}
+
+
#ifdef CONFIG_INET
struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg)
{
@@ -452,6 +461,11 @@ struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg)
}
EXPORT_SYMBOL(tcp_proto_cgroup);
#endif /* CONFIG_INET */
+#else
+static inline void disarm_static_keys(struct mem_cgroup *memcg)
+{
+}
+
#endif /* CONFIG_CGROUP_MEM_RES_CTLR_KMEM */
static void drain_all_stock_async(struct mem_cgroup *memcg);
@@ -4883,6 +4897,7 @@ static void __mem_cgroup_put(struct mem_cgroup *memcg, int count)
{
if (atomic_sub_and_test(count, &memcg->refcnt)) {
struct mem_cgroup *parent = parent_mem_cgroup(memcg);
+ disarm_static_keys(memcg);
__mem_cgroup_free(memcg);
if (parent)
mem_cgroup_put(parent);
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
index 1517037..93555ab 100644
--- a/net/ipv4/tcp_memcontrol.c
+++ b/net/ipv4/tcp_memcontrol.c
@@ -41,6 +41,7 @@ int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
tcp->tcp_prot_mem[1] = net->ipv4.sysctl_tcp_mem[1];
tcp->tcp_prot_mem[2] = net->ipv4.sysctl_tcp_mem[2];
tcp->tcp_memory_pressure = 0;
+ tcp->limited = false;
parent_cg = tcp_prot.proto_cgroup(parent);
if (parent_cg)
@@ -74,9 +75,6 @@ void tcp_destroy_cgroup(struct mem_cgroup *memcg)
percpu_counter_destroy(&tcp->tcp_sockets_allocated);
val = res_counter_read_u64(&tcp->tcp_memory_allocated, RES_LIMIT);
-
- if (val != RESOURCE_MAX)
- static_key_slow_dec(&memcg_socket_limit_enabled);
}
EXPORT_SYMBOL(tcp_destroy_cgroup);
@@ -107,10 +105,10 @@ static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
tcp->tcp_prot_mem[i] = min_t(long, val >> PAGE_SHIFT,
net->ipv4.sysctl_tcp_mem[i]);
- if (val == RESOURCE_MAX && old_lim != RESOURCE_MAX)
- static_key_slow_dec(&memcg_socket_limit_enabled);
- else if (old_lim == RESOURCE_MAX && val != RESOURCE_MAX)
+ if (old_lim == RESOURCE_MAX && !tcp->limited) {
static_key_slow_inc(&memcg_socket_limit_enabled);
+ tcp->limited = true;
+ }
return 0;
}
--
1.7.7.6
^ permalink raw reply related
* (unknown),
From: Mr.Vincent Cheng Hoi. @ 2012-04-06 15:51 UTC (permalink / raw)
--
Good day,
I am Mr.Vincent Cheng Hoi Chuen, GBS, JP Chairman of the Hong Kong and
Shanghai Banking Corporation Limited. I have a business proposal of USD
$22,500,000.00. Your earliest response to this letter will be appreciated.
Best Regards,
Mr.Vincent Cheng Hoi.
^ permalink raw reply
* Re: [RFC] net/hsr: Add support for IEC 62439-3 High-availability Seamless Redundancy
From: Arvid Brodin @ 2012-04-06 15:51 UTC (permalink / raw)
To: David Miller; +Cc: shemminger, netdev, balferreira, arvid.brodin
In-Reply-To: <20120404.202109.2046106039992811660.davem@davemloft.net>
David Miller wrote:
> From: Stephen Hemminger <shemminger@vyatta.com>
> Date: Wed, 4 Apr 2012 16:55:59 -0700
>
>> That isn't so bad, doing a memcpy versus a structure copy.
>
> GCC is going to inline the memcpy and thus we'll still do the
> unaligned accesses. This change therefore won't fix the problem.
Well, it does work for me, with gcc-4.2.2-compiled linux-2.6.37 running
on an AVR32 board.
Just out of curiosity, what's the mechanism behind this inline
assignment that turns the memcpy into an unaligned access? If gcc is
"smart" enough to detect a bunch of char * accesses and turn them
into unaligned 32-bit accesses, isn't that a bug in gcc?
Or will this only happen on archs which __HAVE_ARCH_MEMCPY? (But looking
at a couple of arch/xxx/lib/string.c, these too seem to take alignment
into account.)
--
Arvid Brodin
Enea Services Stockholm AB - since February 16 a part of Xdin in the Alten
Group. Soon we will be working under the common brand Xdin. Read more at
www.xdin.com.
^ permalink raw reply
* [PATCH v2 0/2] update memcg to break its need of populate
From: Glauber Costa @ 2012-04-06 16:04 UTC (permalink / raw)
To: Tejun Heo
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Li Zefan, kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A
Hi Tejun and Li,
I am reposting the same series I've posted recently, just rebased
(two minor conflits) ontop of your last tree.
Let me know if this is acceptable.
Glauber Costa (2):
cgroup: pass struct mem_cgroup instead of struct cgroup to socket
memcg
cgroup: get rid of populate for memcg
include/net/sock.h | 12 ++++++------
include/net/tcp_memcontrol.h | 4 ++--
mm/memcontrol.c | 32 ++++++++++----------------------
net/core/sock.c | 10 +++++-----
net/ipv4/tcp_memcontrol.c | 6 ++----
5 files changed, 25 insertions(+), 39 deletions(-)
--
1.7.7.6
^ permalink raw reply
* [PATCH v2 1/2] cgroup: pass struct mem_cgroup instead of struct cgroup to socket memcg
From: Glauber Costa @ 2012-04-06 16:04 UTC (permalink / raw)
To: Tejun Heo
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Li Zefan, kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A, Glauber Costa,
Li Zefan
In-Reply-To: <1333728250-14248-1-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
The only reason cgroup was used, was to be consistent with the populate()
interface. Now that we're getting rid of it, not only we no longer need
it, but we also *can't* call it this way.
Since we will no longer rely on populate(), this will be called from
create(). During create, the association between struct mem_cgroup
and struct cgroup does not yet exist, since cgroup internals hasn't
yet initialized its bookkeeping. This means we would not be able
to draw the memcg pointer from the cgroup pointer in these
functions, which is highly undesirable.
Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
include/net/sock.h | 12 ++++++------
include/net/tcp_memcontrol.h | 4 ++--
mm/memcontrol.c | 24 +++++++++---------------
net/core/sock.c | 10 +++++-----
net/ipv4/tcp_memcontrol.c | 6 ++----
5 files changed, 24 insertions(+), 32 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index a6ba1f8..b3ebe6b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -70,16 +70,16 @@
struct cgroup;
struct cgroup_subsys;
#ifdef CONFIG_NET
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp);
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg);
#else
static inline
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
static inline
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp)
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg)
{
}
#endif
@@ -900,9 +900,9 @@ struct proto {
* This function has to setup any files the protocol want to
* appear in the kmem cgroup filesystem.
*/
- int (*init_cgroup)(struct cgroup *cgrp,
+ int (*init_cgroup)(struct mem_cgroup *memcg,
struct cgroup_subsys *ss);
- void (*destroy_cgroup)(struct cgroup *cgrp);
+ void (*destroy_cgroup)(struct mem_cgroup *memcg);
struct cg_proto *(*proto_cgroup)(struct mem_cgroup *memcg);
#endif
};
diff --git a/include/net/tcp_memcontrol.h b/include/net/tcp_memcontrol.h
index 48410ff..7df18bc 100644
--- a/include/net/tcp_memcontrol.h
+++ b/include/net/tcp_memcontrol.h
@@ -12,8 +12,8 @@ struct tcp_memcontrol {
};
struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg);
-int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void tcp_destroy_cgroup(struct cgroup *cgrp);
+int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
+void tcp_destroy_cgroup(struct mem_cgroup *memcg);
unsigned long long tcp_max_memory(const struct mem_cgroup *memcg);
void tcp_prot_mem(struct mem_cgroup *memcg, long val, int idx);
#endif /* _TCP_MEMCG_H */
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index bef1142..704054d 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4640,29 +4640,22 @@ static int mem_control_numa_stat_open(struct inode *unused, struct file *file)
#endif /* CONFIG_NUMA */
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
-static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
+static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
- /*
- * Part of this would be better living in a separate allocation
- * function, leaving us with just the cgroup tree population work.
- * We, however, depend on state such as network's proto_list that
- * is only initialized after cgroup creation. I found the less
- * cumbersome way to deal with it to defer it all to populate time
- */
- return mem_cgroup_sockets_init(cont, ss);
+ return mem_cgroup_sockets_init(memcg, ss);
};
-static void kmem_cgroup_destroy(struct cgroup *cont)
+static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
{
- mem_cgroup_sockets_destroy(cont);
+ mem_cgroup_sockets_destroy(memcg);
}
#else
-static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
+static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
-static void kmem_cgroup_destroy(struct cgroup *cont)
+static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
{
}
#endif
@@ -5034,7 +5027,7 @@ static void mem_cgroup_destroy(struct cgroup *cont)
{
struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
- kmem_cgroup_destroy(cont);
+ kmem_cgroup_destroy(memcg);
mem_cgroup_put(memcg);
}
@@ -5042,7 +5035,8 @@ static void mem_cgroup_destroy(struct cgroup *cont)
static int mem_cgroup_populate(struct cgroup_subsys *ss,
struct cgroup *cont)
{
- return register_kmem_files(cont, ss);
+ struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
+ return register_kmem_files(memcg, ss);
}
#ifdef CONFIG_MMU
diff --git a/net/core/sock.c b/net/core/sock.c
index b2e14c0..878f744 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -140,7 +140,7 @@ static DEFINE_MUTEX(proto_list_mutex);
static LIST_HEAD(proto_list);
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
struct proto *proto;
int ret = 0;
@@ -148,7 +148,7 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
mutex_lock(&proto_list_mutex);
list_for_each_entry(proto, &proto_list, node) {
if (proto->init_cgroup) {
- ret = proto->init_cgroup(cgrp, ss);
+ ret = proto->init_cgroup(memcg, ss);
if (ret)
goto out;
}
@@ -159,19 +159,19 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
out:
list_for_each_entry_continue_reverse(proto, &proto_list, node)
if (proto->destroy_cgroup)
- proto->destroy_cgroup(cgrp);
+ proto->destroy_cgroup(memcg);
mutex_unlock(&proto_list_mutex);
return ret;
}
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp)
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg)
{
struct proto *proto;
mutex_lock(&proto_list_mutex);
list_for_each_entry_reverse(proto, &proto_list, node)
if (proto->destroy_cgroup)
- proto->destroy_cgroup(cgrp);
+ proto->destroy_cgroup(memcg);
mutex_unlock(&proto_list_mutex);
}
#endif
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
index 8f1753d..1517037 100644
--- a/net/ipv4/tcp_memcontrol.c
+++ b/net/ipv4/tcp_memcontrol.c
@@ -18,7 +18,7 @@ static void memcg_tcp_enter_memory_pressure(struct sock *sk)
}
EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure);
-int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
/*
* The root cgroup does not use res_counters, but rather,
@@ -28,7 +28,6 @@ int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
struct res_counter *res_parent = NULL;
struct cg_proto *cg_proto, *parent_cg;
struct tcp_memcontrol *tcp;
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
struct mem_cgroup *parent = parent_mem_cgroup(memcg);
struct net *net = current->nsproxy->net_ns;
@@ -61,9 +60,8 @@ int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
}
EXPORT_SYMBOL(tcp_init_cgroup);
-void tcp_destroy_cgroup(struct cgroup *cgrp)
+void tcp_destroy_cgroup(struct mem_cgroup *memcg)
{
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
struct cg_proto *cg_proto;
struct tcp_memcontrol *tcp;
u64 val;
--
1.7.7.6
^ permalink raw reply related
* [PATCH v2 2/2] cgroup: get rid of populate for memcg
From: Glauber Costa @ 2012-04-06 16:04 UTC (permalink / raw)
To: Tejun Heo
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Li Zefan, kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A, Glauber Costa,
Li Zefan
In-Reply-To: <1333728250-14248-1-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
The last man standing justifying the need for populate() is the
sock memcg initialization functions. Now that we are able to pass
a struct mem_cgroup instead of a struct cgroup to the socket
initialization, there is nothing that stops us from initializing
everything in create().
Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
mm/memcontrol.c | 16 +++++-----------
1 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 704054d..64a1bcd 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4640,7 +4640,7 @@ static int mem_control_numa_stat_open(struct inode *unused, struct file *file)
#endif /* CONFIG_NUMA */
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
-static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
+static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return mem_cgroup_sockets_init(memcg, ss);
};
@@ -4650,7 +4650,7 @@ static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
mem_cgroup_sockets_destroy(memcg);
}
#else
-static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
+static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
@@ -5010,7 +5010,9 @@ mem_cgroup_create(struct cgroup *cont)
memcg->move_charge_at_immigrate = 0;
mutex_init(&memcg->thresholds_lock);
spin_lock_init(&memcg->move_lock);
- return &memcg->css;
+
+ if (!memcg_init_kmem(memcg, &mem_cgroup_subsys))
+ return &memcg->css;
free_out:
__mem_cgroup_free(memcg);
return ERR_PTR(error);
@@ -5032,13 +5034,6 @@ static void mem_cgroup_destroy(struct cgroup *cont)
mem_cgroup_put(memcg);
}
-static int mem_cgroup_populate(struct cgroup_subsys *ss,
- struct cgroup *cont)
-{
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
- return register_kmem_files(memcg, ss);
-}
-
#ifdef CONFIG_MMU
/* Handlers for move charge at task migration. */
#define PRECHARGE_COUNT_AT_ONCE 256
@@ -5622,7 +5617,6 @@ struct cgroup_subsys mem_cgroup_subsys = {
.create = mem_cgroup_create,
.pre_destroy = mem_cgroup_pre_destroy,
.destroy = mem_cgroup_destroy,
- .populate = mem_cgroup_populate,
.can_attach = mem_cgroup_can_attach,
.cancel_attach = mem_cgroup_cancel_attach,
.attach = mem_cgroup_move_task,
--
1.7.7.6
^ permalink raw reply related
* Re: e1000e interface hang on 82574L
From: Nix @ 2012-04-06 16:04 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Chris Boot, e1000-devel, netdev, lkml, linux-pci, Matthew Garrett
In-Reply-To: <CAErSpo4TJ-9NsD5QTpFi9fsnD9qHt7+Tr5jJHQPuS7vg6ghq_w@mail.gmail.com>
On 6 Apr 2012, Bjorn Helgaas outgrape:
> If I understand correctly, e1000e attempts to disable ASPM to work
> around an 82574L hardware erratum, but the PCI core either doesn't
> disable ASPM or it gets re-enabled somehow.
It gets re-enabled. If you explicitly do a setpci in the boot process to
turn ASPM off on the interface, after doing your 'ip link up' and routing
initialization, by the end of the boot process ASPM is back on again.
I speculate that the stabilization of the interface (as indicated by the
link-enabled message) has somehow flipped ASPM on, but I have no actual
evidence for when this re-enabling happens. I just know it does.
--
NULL && (void)
------------------------------------------------------------------------------
For Developers, A Lot Can Happen In A Second.
Boundary is the first to Know...and Tell You.
Monitor Your Applications in Ultra-Fine Resolution. Try it FREE!
http://p.sf.net/sfu/Boundary-d2dvs2
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: e1000e interface hang on 82574L
From: Nix @ 2012-04-06 16:05 UTC (permalink / raw)
To: Henrique de Moraes Holschuh
Cc: Chris Boot, e1000-devel, netdev, lkml, linux-pci, Bjorn Helgaas,
Matthew Garrett
In-Reply-To: <20120406134144.GA22526@khazad-dum.debian.net>
On 6 Apr 2012, Henrique de Moraes Holschuh outgrape:
> You probably need to disable it upstream of the 82574L as well. Here
> (SuperMicro C7X58) I managed to get it to be stable by telling the BIOS
> to disable L0s and L1 system-wide.
>
> But not all BIOSes will have that option...
Indeed not :( the Tyan S7010 mobo in my headless server can't do it.
--
NULL && (void)
------------------------------------------------------------------------------
For Developers, A Lot Can Happen In A Second.
Boundary is the first to Know...and Tell You.
Monitor Your Applications in Ultra-Fine Resolution. Try it FREE!
http://p.sf.net/sfu/Boundary-d2dvs2
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* [PATCH] [IPv6]: Treat ND option 31 as userland (DNSSL support)
From: Alexey I. Froloff @ 2012-04-06 15:50 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
As specified in RFC6106, DNSSL option contains one or more domain names
of DNS suffixes. 8-bit identifier of the DNSSL option type as assigned
by the IANA is 31. This option should also be treated as userland.
Signed-off-by: Alexey I. Froloff <raorn@raorn.name>
---
include/net/ndisc.h | 1 +
net/ipv6/ndisc.c | 4 +++-
2 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 6f9c25a..c02b6ad 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -34,6 +34,7 @@ enum {
__ND_OPT_ARRAY_MAX,
ND_OPT_ROUTE_INFO = 24, /* RFC4191 */
ND_OPT_RDNSS = 25, /* RFC5006 */
+ ND_OPT_DNSSL = 31, /* RFC6106 */
__ND_OPT_MAX
};
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 3dcdb81..d04c6eb 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -15,6 +15,7 @@
/*
* Changes:
*
+ * Alexey I. Froloff : RFC6106 (DNSSL) support
* Pierre Ynard : export userland ND options
* through netlink (RDNSS support)
* Lars Fenneberg : fixed MTU setting on receipt
@@ -228,7 +229,8 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
static inline int ndisc_is_useropt(struct nd_opt_hdr *opt)
{
- return opt->nd_opt_type == ND_OPT_RDNSS;
+ return opt->nd_opt_type == ND_OPT_RDNSS ||
+ opt->nd_opt_type == ND_OPT_DNSSL;
}
static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur,
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH net-next #2 33/39] dmfe: stop using net_device.{base_addr, irq} and convert to __iomem.
From: Grant Grundler @ 2012-04-06 16:31 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev, David Miller, Grant Grundler
In-Reply-To: <83b453d5ea2df18d0af1a760e458c5b649415bfd.1333704409.git.romieu@fr.zoreil.com>
On Fri, Apr 6, 2012 at 3:06 AM, Francois Romieu <romieu@fr.zoreil.com> wrote:
> This is a pure PCI driver, no ISA here.
>
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Grant Grundler <grundler@parisc-linux.org>
Acked-by: Grant Grundler <grundler@parisc-linux.org>
I want to point out one potential bug below (that can be fixed later
if necessary.)
> ---
> drivers/net/ethernet/dec/tulip/dmfe.c | 295 +++++++++++++++++----------------
> 1 files changed, 153 insertions(+), 142 deletions(-)
>
> diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c
> index 1eccf49..0ef5b68 100644
> --- a/drivers/net/ethernet/dec/tulip/dmfe.c
> +++ b/drivers/net/ethernet/dec/tulip/dmfe.c
> @@ -150,6 +150,12 @@
> #define DMFE_TX_TIMEOUT ((3*HZ)/2) /* tx packet time-out time 1.5 s" */
> #define DMFE_TX_KICK (HZ/2) /* tx packet Kick-out time 0.5 s" */
>
> +#define dw32(reg, val) iowrite32(val, ioaddr + (reg))
> +#define dw16(reg, val) iowrite16(val, ioaddr + (reg))
> +#define dr32(reg) ioread32(ioaddr + (reg))
> +#define dr16(reg) ioread16(ioaddr + (reg))
> +#define dr8(reg) ioread8(ioaddr + (reg))
> +
> #define DMFE_DBUG(dbug_now, msg, value) \
> do { \
> if (dmfe_debug || (dbug_now)) \
> @@ -178,14 +184,6 @@
>
> #define SROM_V41_CODE 0x14
>
> -#define SROM_CLK_WRITE(data, ioaddr) \
> - outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \
> - udelay(5); \
> - outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr); \
> - udelay(5); \
> - outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \
> - udelay(5);
> -
> #define __CHK_IO_SIZE(pci_id, dev_rev) \
> (( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x30) ) ? \
> DM9102A_IO_SIZE: DM9102_IO_SIZE)
> @@ -213,11 +211,11 @@ struct rx_desc {
> struct dmfe_board_info {
> u32 chip_id; /* Chip vendor/Device ID */
> u8 chip_revision; /* Chip revision */
> - struct DEVICE *next_dev; /* next device */
> + struct net_device *next_dev; /* next device */
> struct pci_dev *pdev; /* PCI device */
> spinlock_t lock;
>
> - long ioaddr; /* I/O base address */
> + void __iomem *ioaddr; /* I/O base address */
> u32 cr0_data;
> u32 cr5_data;
> u32 cr6_data;
> @@ -320,20 +318,20 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *, struct DEVICE *);
> static int dmfe_stop(struct DEVICE *);
> static void dmfe_set_filter_mode(struct DEVICE *);
> static const struct ethtool_ops netdev_ethtool_ops;
> -static u16 read_srom_word(long ,int);
> +static u16 read_srom_word(void __iomem *, int);
> static irqreturn_t dmfe_interrupt(int , void *);
> #ifdef CONFIG_NET_POLL_CONTROLLER
> static void poll_dmfe (struct net_device *dev);
> #endif
> -static void dmfe_descriptor_init(struct net_device *, unsigned long);
> +static void dmfe_descriptor_init(struct net_device *);
> static void allocate_rx_buffer(struct net_device *);
> -static void update_cr6(u32, unsigned long);
> +static void update_cr6(u32, void __iomem *);
> static void send_filter_frame(struct DEVICE *);
> static void dm9132_id_table(struct DEVICE *);
> -static u16 phy_read(unsigned long, u8, u8, u32);
> -static void phy_write(unsigned long, u8, u8, u16, u32);
> -static void phy_write_1bit(unsigned long, u32);
> -static u16 phy_read_1bit(unsigned long);
> +static u16 phy_read(void __iomem *, u8, u8, u32);
> +static void phy_write(void __iomem *, u8, u8, u16, u32);
> +static void phy_write_1bit(void __iomem *, u32);
> +static u16 phy_read_1bit(void __iomem *);
> static u8 dmfe_sense_speed(struct dmfe_board_info *);
> static void dmfe_process_mode(struct dmfe_board_info *);
> static void dmfe_timer(unsigned long);
> @@ -462,14 +460,16 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
> db->buf_pool_dma_start = db->buf_pool_dma_ptr;
>
> db->chip_id = ent->driver_data;
> - db->ioaddr = pci_resource_start(pdev, 0);
> + /* IO type range. */
> + db->ioaddr = pci_iomap(pdev, 0, 0);
> + if (!db->ioaddr)
> + goto err_out_free_buf;
> +
> db->chip_revision = pdev->revision;
> db->wol_mode = 0;
>
> db->pdev = pdev;
>
> - dev->base_addr = db->ioaddr;
> - dev->irq = pdev->irq;
> pci_set_drvdata(pdev, dev);
> dev->netdev_ops = &netdev_ops;
> dev->ethtool_ops = &netdev_ethtool_ops;
> @@ -484,9 +484,10 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
> db->chip_type = 0;
>
> /* read 64 word srom data */
> - for (i = 0; i < 64; i++)
> + for (i = 0; i < 64; i++) {
> ((__le16 *) db->srom)[i] =
> cpu_to_le16(read_srom_word(db->ioaddr, i));
> + }
>
> /* Set Node address */
> for (i = 0; i < 6; i++)
> @@ -494,16 +495,18 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
>
> err = register_netdev (dev);
> if (err)
> - goto err_out_free_buf;
> + goto err_out_unmap;
>
> dev_info(&dev->dev, "Davicom DM%04lx at pci%s, %pM, irq %d\n",
> ent->driver_data >> 16,
> - pci_name(pdev), dev->dev_addr, dev->irq);
> + pci_name(pdev), dev->dev_addr, pdev->irq);
>
> pci_set_master(pdev);
>
> return 0;
>
> +err_out_unmap:
> + pci_iounmap(pdev, db->ioaddr);
> err_out_free_buf:
> pci_free_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
> db->buf_pool_ptr, db->buf_pool_dma_ptr);
> @@ -532,7 +535,7 @@ static void __devexit dmfe_remove_one (struct pci_dev *pdev)
> if (dev) {
>
> unregister_netdev(dev);
> -
> + pci_iounmap(db->pdev, db->ioaddr);
> pci_free_consistent(db->pdev, sizeof(struct tx_desc) *
> DESC_ALL_CNT + 0x20, db->desc_pool_ptr,
> db->desc_pool_dma_ptr);
> @@ -555,13 +558,13 @@ static void __devexit dmfe_remove_one (struct pci_dev *pdev)
>
> static int dmfe_open(struct DEVICE *dev)
> {
> - int ret;
> struct dmfe_board_info *db = netdev_priv(dev);
> + const int irq = db->pdev->irq;
> + int ret;
>
> DMFE_DBUG(0, "dmfe_open", 0);
>
> - ret = request_irq(dev->irq, dmfe_interrupt,
> - IRQF_SHARED, dev->name, dev);
> + ret = request_irq(irq, dmfe_interrupt, IRQF_SHARED, dev->name, dev);
> if (ret)
> return ret;
>
> @@ -615,14 +618,14 @@ static int dmfe_open(struct DEVICE *dev)
> static void dmfe_init_dm910x(struct DEVICE *dev)
> {
> struct dmfe_board_info *db = netdev_priv(dev);
> - unsigned long ioaddr = db->ioaddr;
> + void __iomem *ioaddr = db->ioaddr;
>
> DMFE_DBUG(0, "dmfe_init_dm910x()", 0);
>
> /* Reset DM910x MAC controller */
> - outl(DM910X_RESET, ioaddr + DCR0); /* RESET MAC */
> + dw32(DCR0, DM910X_RESET); /* RESET MAC */
> udelay(100);
If this driver supports devices that offer MMIO BARs, the dw32()
followed by udelay() won't work the same way outl()/udelay() worked.
See http://www.parisc-linux.org/~grundler/talks/ols_2002/4_3MMIO_is_harder.html
for explanation of problem and how to fix this (It's simple enough).
Ugh..since I wrote "Porting to ZX1" 10 years ago, the link to the tg3
patch is dead (long live bitkeeper!). I think it was this patch:
http://permalink.gmane.org/gmane.linux.kernel.commits.2-4/7007
You might find modeling after this patch to be helpful.
thanks,
grant
> - outl(db->cr0_data, ioaddr + DCR0);
> + dw32(DCR0, db->cr0_data);
> udelay(5);
>
> /* Phy addr : DM910(A)2/DM9132/9801, phy address = 1 */
> @@ -633,12 +636,12 @@ static void dmfe_init_dm910x(struct DEVICE *dev)
> db->media_mode = dmfe_media_mode;
>
> /* RESET Phyxcer Chip by GPR port bit 7 */
> - outl(0x180, ioaddr + DCR12); /* Let bit 7 output port */
> + dw32(DCR12, 0x180); /* Let bit 7 output port */
> if (db->chip_id == PCI_DM9009_ID) {
> - outl(0x80, ioaddr + DCR12); /* Issue RESET signal */
> + dw32(DCR12, 0x80); /* Issue RESET signal */
> mdelay(300); /* Delay 300 ms */
> }
> - outl(0x0, ioaddr + DCR12); /* Clear RESET signal */
> + dw32(DCR12, 0x0); /* Clear RESET signal */
>
> /* Process Phyxcer Media Mode */
> if ( !(db->media_mode & 0x10) ) /* Force 1M mode */
> @@ -649,7 +652,7 @@ static void dmfe_init_dm910x(struct DEVICE *dev)
> db->op_mode = db->media_mode; /* Force Mode */
>
> /* Initialize Transmit/Receive decriptor and CR3/4 */
> - dmfe_descriptor_init(dev, ioaddr);
> + dmfe_descriptor_init(dev);
>
> /* Init CR6 to program DM910x operation */
> update_cr6(db->cr6_data, ioaddr);
> @@ -662,10 +665,10 @@ static void dmfe_init_dm910x(struct DEVICE *dev)
>
> /* Init CR7, interrupt active bit */
> db->cr7_data = CR7_DEFAULT;
> - outl(db->cr7_data, ioaddr + DCR7);
> + dw32(DCR7, db->cr7_data);
>
> /* Init CR15, Tx jabber and Rx watchdog timer */
> - outl(db->cr15_data, ioaddr + DCR15);
> + dw32(DCR15, db->cr15_data);
>
> /* Enable DM910X Tx/Rx function */
> db->cr6_data |= CR6_RXSC | CR6_TXSC | 0x40000;
> @@ -682,6 +685,7 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
> struct DEVICE *dev)
> {
> struct dmfe_board_info *db = netdev_priv(dev);
> + void __iomem *ioaddr = db->ioaddr;
> struct tx_desc *txptr;
> unsigned long flags;
>
> @@ -707,7 +711,7 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
> }
>
> /* Disable NIC interrupt */
> - outl(0, dev->base_addr + DCR7);
> + dw32(DCR7, 0);
>
> /* transmit this packet */
> txptr = db->tx_insert_ptr;
> @@ -721,11 +725,11 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
> if ( (!db->tx_queue_cnt) && (db->tx_packet_cnt < TX_MAX_SEND_CNT) ) {
> txptr->tdes0 = cpu_to_le32(0x80000000); /* Set owner bit */
> db->tx_packet_cnt++; /* Ready to send */
> - outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */
> + dw32(DCR1, 0x1); /* Issue Tx polling */
> dev->trans_start = jiffies; /* saved time stamp */
> } else {
> db->tx_queue_cnt++; /* queue TX packet */
> - outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */
> + dw32(DCR1, 0x1); /* Issue Tx polling */
> }
>
> /* Tx resource check */
> @@ -734,7 +738,7 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
>
> /* Restore CR7 to enable interrupt */
> spin_unlock_irqrestore(&db->lock, flags);
> - outl(db->cr7_data, dev->base_addr + DCR7);
> + dw32(DCR7, db->cr7_data);
>
> /* free this SKB */
> dev_kfree_skb(skb);
> @@ -751,7 +755,7 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
> static int dmfe_stop(struct DEVICE *dev)
> {
> struct dmfe_board_info *db = netdev_priv(dev);
> - unsigned long ioaddr = dev->base_addr;
> + void __iomem *ioaddr = db->ioaddr;
>
> DMFE_DBUG(0, "dmfe_stop", 0);
>
> @@ -762,12 +766,12 @@ static int dmfe_stop(struct DEVICE *dev)
> del_timer_sync(&db->timer);
>
> /* Reset & stop DM910X board */
> - outl(DM910X_RESET, ioaddr + DCR0);
> + dw32(DCR0, DM910X_RESET);
> udelay(5);
> - phy_write(db->ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);
> + phy_write(ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);
>
> /* free interrupt */
> - free_irq(dev->irq, dev);
> + free_irq(db->pdev->irq, dev);
>
> /* free allocated rx buffer */
> dmfe_free_rxbuffer(db);
> @@ -794,7 +798,7 @@ static irqreturn_t dmfe_interrupt(int irq, void *dev_id)
> {
> struct DEVICE *dev = dev_id;
> struct dmfe_board_info *db = netdev_priv(dev);
> - unsigned long ioaddr = dev->base_addr;
> + void __iomem *ioaddr = db->ioaddr;
> unsigned long flags;
>
> DMFE_DBUG(0, "dmfe_interrupt()", 0);
> @@ -802,15 +806,15 @@ static irqreturn_t dmfe_interrupt(int irq, void *dev_id)
> spin_lock_irqsave(&db->lock, flags);
>
> /* Got DM910X status */
> - db->cr5_data = inl(ioaddr + DCR5);
> - outl(db->cr5_data, ioaddr + DCR5);
> + db->cr5_data = dr32(DCR5);
> + dw32(DCR5, db->cr5_data);
> if ( !(db->cr5_data & 0xc1) ) {
> spin_unlock_irqrestore(&db->lock, flags);
> return IRQ_HANDLED;
> }
>
> /* Disable all interrupt in CR7 to solve the interrupt edge problem */
> - outl(0, ioaddr + DCR7);
> + dw32(DCR7, 0);
>
> /* Check system status */
> if (db->cr5_data & 0x2000) {
> @@ -838,11 +842,11 @@ static irqreturn_t dmfe_interrupt(int irq, void *dev_id)
> if (db->dm910x_chk_mode & 0x2) {
> db->dm910x_chk_mode = 0x4;
> db->cr6_data |= 0x100;
> - update_cr6(db->cr6_data, db->ioaddr);
> + update_cr6(db->cr6_data, ioaddr);
> }
>
> /* Restore CR7 to enable interrupt mask */
> - outl(db->cr7_data, ioaddr + DCR7);
> + dw32(DCR7, db->cr7_data);
>
> spin_unlock_irqrestore(&db->lock, flags);
> return IRQ_HANDLED;
> @@ -858,11 +862,14 @@ static irqreturn_t dmfe_interrupt(int irq, void *dev_id)
>
> static void poll_dmfe (struct net_device *dev)
> {
> + struct dmfe_board_info *db = netdev_priv(dev);
> + const int irq = db->pdev->irq;
> +
> /* disable_irq here is not very nice, but with the lockless
> interrupt handler we have no other choice. */
> - disable_irq(dev->irq);
> - dmfe_interrupt (dev->irq, dev);
> - enable_irq(dev->irq);
> + disable_irq(irq);
> + dmfe_interrupt (irq, dev);
> + enable_irq(irq);
> }
> #endif
>
> @@ -873,7 +880,7 @@ static void poll_dmfe (struct net_device *dev)
> static void dmfe_free_tx_pkt(struct DEVICE *dev, struct dmfe_board_info * db)
> {
> struct tx_desc *txptr;
> - unsigned long ioaddr = dev->base_addr;
> + void __iomem *ioaddr = db->ioaddr;
> u32 tdes0;
>
> txptr = db->tx_remove_ptr;
> @@ -897,7 +904,7 @@ static void dmfe_free_tx_pkt(struct DEVICE *dev, struct dmfe_board_info * db)
> db->tx_fifo_underrun++;
> if ( !(db->cr6_data & CR6_SFT) ) {
> db->cr6_data = db->cr6_data | CR6_SFT;
> - update_cr6(db->cr6_data, db->ioaddr);
> + update_cr6(db->cr6_data, ioaddr);
> }
> }
> if (tdes0 & 0x0100)
> @@ -924,7 +931,7 @@ static void dmfe_free_tx_pkt(struct DEVICE *dev, struct dmfe_board_info * db)
> txptr->tdes0 = cpu_to_le32(0x80000000); /* Set owner bit */
> db->tx_packet_cnt++; /* Ready to send */
> db->tx_queue_cnt--;
> - outl(0x1, ioaddr + DCR1); /* Issue Tx polling */
> + dw32(DCR1, 0x1); /* Issue Tx polling */
> dev->trans_start = jiffies; /* saved time stamp */
> }
>
> @@ -1087,12 +1094,7 @@ static void dmfe_ethtool_get_drvinfo(struct net_device *dev,
>
> strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
> strlcpy(info->version, DRV_VERSION, sizeof(info->version));
> - if (np->pdev)
> - strlcpy(info->bus_info, pci_name(np->pdev),
> - sizeof(info->bus_info));
> - else
> - sprintf(info->bus_info, "EISA 0x%lx %d",
> - dev->base_addr, dev->irq);
> + strlcpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info));
> }
>
> static int dmfe_ethtool_set_wol(struct net_device *dev,
> @@ -1132,10 +1134,11 @@ static const struct ethtool_ops netdev_ethtool_ops = {
>
> static void dmfe_timer(unsigned long data)
> {
> + struct net_device *dev = (struct net_device *)data;
> + struct dmfe_board_info *db = netdev_priv(dev);
> + void __iomem *ioaddr = db->ioaddr;
> u32 tmp_cr8;
> unsigned char tmp_cr12;
> - struct DEVICE *dev = (struct DEVICE *) data;
> - struct dmfe_board_info *db = netdev_priv(dev);
> unsigned long flags;
>
> int link_ok, link_ok_phy;
> @@ -1148,11 +1151,10 @@ static void dmfe_timer(unsigned long data)
> db->first_in_callback = 1;
> if (db->chip_type && (db->chip_id==PCI_DM9102_ID)) {
> db->cr6_data &= ~0x40000;
> - update_cr6(db->cr6_data, db->ioaddr);
> - phy_write(db->ioaddr,
> - db->phy_addr, 0, 0x1000, db->chip_id);
> + update_cr6(db->cr6_data, ioaddr);
> + phy_write(ioaddr, db->phy_addr, 0, 0x1000, db->chip_id);
> db->cr6_data |= 0x40000;
> - update_cr6(db->cr6_data, db->ioaddr);
> + update_cr6(db->cr6_data, ioaddr);
> db->timer.expires = DMFE_TIMER_WUT + HZ * 2;
> add_timer(&db->timer);
> spin_unlock_irqrestore(&db->lock, flags);
> @@ -1167,7 +1169,7 @@ static void dmfe_timer(unsigned long data)
> db->dm910x_chk_mode = 0x4;
>
> /* Dynamic reset DM910X : system error or transmit time-out */
> - tmp_cr8 = inl(db->ioaddr + DCR8);
> + tmp_cr8 = dr32(DCR8);
> if ( (db->interval_rx_cnt==0) && (tmp_cr8) ) {
> db->reset_cr8++;
> db->wait_reset = 1;
> @@ -1177,7 +1179,7 @@ static void dmfe_timer(unsigned long data)
> /* TX polling kick monitor */
> if ( db->tx_packet_cnt &&
> time_after(jiffies, dev_trans_start(dev) + DMFE_TX_KICK) ) {
> - outl(0x1, dev->base_addr + DCR1); /* Tx polling again */
> + dw32(DCR1, 0x1); /* Tx polling again */
>
> /* TX Timeout */
> if (time_after(jiffies, dev_trans_start(dev) + DMFE_TX_TIMEOUT) ) {
> @@ -1200,9 +1202,9 @@ static void dmfe_timer(unsigned long data)
>
> /* Link status check, Dynamic media type change */
> if (db->chip_id == PCI_DM9132_ID)
> - tmp_cr12 = inb(db->ioaddr + DCR9 + 3); /* DM9132 */
> + tmp_cr12 = dr8(DCR9 + 3); /* DM9132 */
> else
> - tmp_cr12 = inb(db->ioaddr + DCR12); /* DM9102/DM9102A */
> + tmp_cr12 = dr8(DCR12); /* DM9102/DM9102A */
>
> if ( ((db->chip_id == PCI_DM9102_ID) &&
> (db->chip_revision == 0x30)) ||
> @@ -1251,7 +1253,7 @@ static void dmfe_timer(unsigned long data)
> /* 10/100M link failed, used 1M Home-Net */
> db->cr6_data|=0x00040000; /* bit18=1, MII */
> db->cr6_data&=~0x00000200; /* bit9=0, HD mode */
> - update_cr6(db->cr6_data, db->ioaddr);
> + update_cr6(db->cr6_data, ioaddr);
> }
> } else if (!netif_carrier_ok(dev)) {
>
> @@ -1288,17 +1290,18 @@ static void dmfe_timer(unsigned long data)
> * Re-initialize DM910X board
> */
>
> -static void dmfe_dynamic_reset(struct DEVICE *dev)
> +static void dmfe_dynamic_reset(struct net_device *dev)
> {
> struct dmfe_board_info *db = netdev_priv(dev);
> + void __iomem *ioaddr = db->ioaddr;
>
> DMFE_DBUG(0, "dmfe_dynamic_reset()", 0);
>
> /* Sopt MAC controller */
> db->cr6_data &= ~(CR6_RXSC | CR6_TXSC); /* Disable Tx/Rx */
> - update_cr6(db->cr6_data, dev->base_addr);
> - outl(0, dev->base_addr + DCR7); /* Disable Interrupt */
> - outl(inl(dev->base_addr + DCR5), dev->base_addr + DCR5);
> + update_cr6(db->cr6_data, ioaddr);
> + dw32(DCR7, 0); /* Disable Interrupt */
> + dw32(DCR5, dr32(DCR5));
>
> /* Disable upper layer interface */
> netif_stop_queue(dev);
> @@ -1364,9 +1367,10 @@ static void dmfe_reuse_skb(struct dmfe_board_info *db, struct sk_buff * skb)
> * Using Chain structure, and allocate Tx/Rx buffer
> */
>
> -static void dmfe_descriptor_init(struct net_device *dev, unsigned long ioaddr)
> +static void dmfe_descriptor_init(struct net_device *dev)
> {
> struct dmfe_board_info *db = netdev_priv(dev);
> + void __iomem *ioaddr = db->ioaddr;
> struct tx_desc *tmp_tx;
> struct rx_desc *tmp_rx;
> unsigned char *tmp_buf;
> @@ -1379,7 +1383,7 @@ static void dmfe_descriptor_init(struct net_device *dev, unsigned long ioaddr)
> /* tx descriptor start pointer */
> db->tx_insert_ptr = db->first_tx_desc;
> db->tx_remove_ptr = db->first_tx_desc;
> - outl(db->first_tx_desc_dma, ioaddr + DCR4); /* TX DESC address */
> + dw32(DCR4, db->first_tx_desc_dma); /* TX DESC address */
>
> /* rx descriptor start pointer */
> db->first_rx_desc = (void *)db->first_tx_desc +
> @@ -1389,7 +1393,7 @@ static void dmfe_descriptor_init(struct net_device *dev, unsigned long ioaddr)
> sizeof(struct tx_desc) * TX_DESC_CNT;
> db->rx_insert_ptr = db->first_rx_desc;
> db->rx_ready_ptr = db->first_rx_desc;
> - outl(db->first_rx_desc_dma, ioaddr + DCR3); /* RX DESC address */
> + dw32(DCR3, db->first_rx_desc_dma); /* RX DESC address */
>
> /* Init Transmit chain */
> tmp_buf = db->buf_pool_start;
> @@ -1431,14 +1435,14 @@ static void dmfe_descriptor_init(struct net_device *dev, unsigned long ioaddr)
> * Firstly stop DM910X , then written value and start
> */
>
> -static void update_cr6(u32 cr6_data, unsigned long ioaddr)
> +static void update_cr6(u32 cr6_data, void __iomem *ioaddr)
> {
> u32 cr6_tmp;
>
> cr6_tmp = cr6_data & ~0x2002; /* stop Tx/Rx */
> - outl(cr6_tmp, ioaddr + DCR6);
> + dw32(DCR6, cr6_tmp);
> udelay(5);
> - outl(cr6_data, ioaddr + DCR6);
> + dw32(DCR6, cr6_data);
> udelay(5);
> }
>
> @@ -1448,24 +1452,19 @@ static void update_cr6(u32 cr6_data, unsigned long ioaddr)
> * This setup frame initialize DM910X address filter mode
> */
>
> -static void dm9132_id_table(struct DEVICE *dev)
> +static void dm9132_id_table(struct net_device *dev)
> {
> + struct dmfe_board_info *db = netdev_priv(dev);
> + void __iomem *ioaddr = db->ioaddr + 0xc0;
> + u16 *addrptr = (u16 *)dev->dev_addr;
> struct netdev_hw_addr *ha;
> - u16 * addrptr;
> - unsigned long ioaddr = dev->base_addr+0xc0; /* ID Table */
> - u32 hash_val;
> u16 i, hash_table[4];
>
> - DMFE_DBUG(0, "dm9132_id_table()", 0);
> -
> /* Node address */
> - addrptr = (u16 *) dev->dev_addr;
> - outw(addrptr[0], ioaddr);
> - ioaddr += 4;
> - outw(addrptr[1], ioaddr);
> - ioaddr += 4;
> - outw(addrptr[2], ioaddr);
> - ioaddr += 4;
> + for (i = 0; i < 3; i++) {
> + dw16(0, addrptr[i]);
> + ioaddr += 4;
> + }
>
> /* Clear Hash Table */
> memset(hash_table, 0, sizeof(hash_table));
> @@ -1475,13 +1474,14 @@ static void dm9132_id_table(struct DEVICE *dev)
>
> /* the multicast address in Hash Table : 64 bits */
> netdev_for_each_mc_addr(ha, dev) {
> - hash_val = cal_CRC((char *) ha->addr, 6, 0) & 0x3f;
> + u32 hash_val = cal_CRC((char *)ha->addr, 6, 0) & 0x3f;
> +
> hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
> }
>
> /* Write the hash table to MAC MD table */
> for (i = 0; i < 4; i++, ioaddr += 4)
> - outw(hash_table[i], ioaddr);
> + dw16(0, hash_table[i]);
> }
>
>
> @@ -1490,7 +1490,7 @@ static void dm9132_id_table(struct DEVICE *dev)
> * This setup frame initialize DM910X address filter mode
> */
>
> -static void send_filter_frame(struct DEVICE *dev)
> +static void send_filter_frame(struct net_device *dev)
> {
> struct dmfe_board_info *db = netdev_priv(dev);
> struct netdev_hw_addr *ha;
> @@ -1535,12 +1535,14 @@ static void send_filter_frame(struct DEVICE *dev)
>
> /* Resource Check and Send the setup packet */
> if (!db->tx_packet_cnt) {
> + void __iomem *ioaddr = db->ioaddr;
> +
> /* Resource Empty */
> db->tx_packet_cnt++;
> txptr->tdes0 = cpu_to_le32(0x80000000);
> - update_cr6(db->cr6_data | 0x2000, dev->base_addr);
> - outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */
> - update_cr6(db->cr6_data, dev->base_addr);
> + update_cr6(db->cr6_data | 0x2000, ioaddr);
> + dw32(DCR1, 0x1); /* Issue Tx polling */
> + update_cr6(db->cr6_data, ioaddr);
> dev->trans_start = jiffies;
> } else
> db->tx_queue_cnt++; /* Put in TX queue */
> @@ -1575,43 +1577,55 @@ static void allocate_rx_buffer(struct net_device *dev)
> db->rx_insert_ptr = rxptr;
> }
>
> +static void srom_clk_write(void __iomem *ioaddr, u32 data)
> +{
> + static const u32 cmd[] = {
> + CR9_SROM_READ | CR9_SRCS,
> + CR9_SROM_READ | CR9_SRCS | CR9_SRCLK,
> + CR9_SROM_READ | CR9_SRCS
> + };
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(cmd); i++) {
> + dw32(DCR9, data | cmd[i]);
> + udelay(5);
> + }
> +}
>
> /*
> * Read one word data from the serial ROM
> */
> -
> -static u16 read_srom_word(long ioaddr, int offset)
> +static u16 read_srom_word(void __iomem *ioaddr, int offset)
> {
> + u16 srom_data;
> int i;
> - u16 srom_data = 0;
> - long cr9_ioaddr = ioaddr + DCR9;
>
> - outl(CR9_SROM_READ, cr9_ioaddr);
> - outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
> + dw32(DCR9, CR9_SROM_READ);
> + dw32(DCR9, CR9_SROM_READ | CR9_SRCS);
>
> /* Send the Read Command 110b */
> - SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
> - SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
> - SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr);
> + srom_clk_write(ioaddr, SROM_DATA_1);
> + srom_clk_write(ioaddr, SROM_DATA_1);
> + srom_clk_write(ioaddr, SROM_DATA_0);
>
> /* Send the offset */
> for (i = 5; i >= 0; i--) {
> srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0;
> - SROM_CLK_WRITE(srom_data, cr9_ioaddr);
> + srom_clk_write(ioaddr, srom_data);
> }
>
> - outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
> + dw32(DCR9, CR9_SROM_READ | CR9_SRCS);
>
> for (i = 16; i > 0; i--) {
> - outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr);
> + dw32(DCR9, CR9_SROM_READ | CR9_SRCS | CR9_SRCLK);
> udelay(5);
> srom_data = (srom_data << 1) |
> - ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 : 0);
> - outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
> + ((dr32(DCR9) & CR9_CRDOUT) ? 1 : 0);
> + dw32(DCR9, CR9_SROM_READ | CR9_SRCS);
> udelay(5);
> }
>
> - outl(CR9_SROM_READ, cr9_ioaddr);
> + dw32(DCR9, CR9_SROM_READ);
> return srom_data;
> }
>
> @@ -1620,13 +1634,14 @@ static u16 read_srom_word(long ioaddr, int offset)
> * Auto sense the media mode
> */
>
> -static u8 dmfe_sense_speed(struct dmfe_board_info * db)
> +static u8 dmfe_sense_speed(struct dmfe_board_info *db)
> {
> + void __iomem *ioaddr = db->ioaddr;
> u8 ErrFlag = 0;
> u16 phy_mode;
>
> /* CR6 bit18=0, select 10/100M */
> - update_cr6( (db->cr6_data & ~0x40000), db->ioaddr);
> + update_cr6(db->cr6_data & ~0x40000, ioaddr);
>
> phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
> phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
> @@ -1665,11 +1680,12 @@ static u8 dmfe_sense_speed(struct dmfe_board_info * db)
>
> static void dmfe_set_phyxcer(struct dmfe_board_info *db)
> {
> + void __iomem *ioaddr = db->ioaddr;
> u16 phy_reg;
>
> /* Select 10/100M phyxcer */
> db->cr6_data &= ~0x40000;
> - update_cr6(db->cr6_data, db->ioaddr);
> + update_cr6(db->cr6_data, ioaddr);
>
> /* DM9009 Chip: Phyxcer reg18 bit12=0 */
> if (db->chip_id == PCI_DM9009_ID) {
> @@ -1765,18 +1781,15 @@ static void dmfe_process_mode(struct dmfe_board_info *db)
> * Write a word to Phy register
> */
>
> -static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset,
> +static void phy_write(void __iomem *ioaddr, u8 phy_addr, u8 offset,
> u16 phy_data, u32 chip_id)
> {
> u16 i;
> - unsigned long ioaddr;
>
> if (chip_id == PCI_DM9132_ID) {
> - ioaddr = iobase + 0x80 + offset * 4;
> - outw(phy_data, ioaddr);
> + dw16(0x80 + offset * 4, phy_data);
> } else {
> /* DM9102/DM9102A Chip */
> - ioaddr = iobase + DCR9;
>
> /* Send 33 synchronization clock to Phy controller */
> for (i = 0; i < 35; i++)
> @@ -1816,19 +1829,16 @@ static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset,
> * Read a word data from phy register
> */
>
> -static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, u32 chip_id)
> +static u16 phy_read(void __iomem *ioaddr, u8 phy_addr, u8 offset, u32 chip_id)
> {
> int i;
> u16 phy_data;
> - unsigned long ioaddr;
>
> if (chip_id == PCI_DM9132_ID) {
> /* DM9132 Chip */
> - ioaddr = iobase + 0x80 + offset * 4;
> - phy_data = inw(ioaddr);
> + phy_data = dr16(0x80 + offset * 4);
> } else {
> /* DM9102/DM9102A Chip */
> - ioaddr = iobase + DCR9;
>
> /* Send 33 synchronization clock to Phy controller */
> for (i = 0; i < 35; i++)
> @@ -1870,13 +1880,13 @@ static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, u32 chip_id)
> * Write one bit data to Phy Controller
> */
>
> -static void phy_write_1bit(unsigned long ioaddr, u32 phy_data)
> +static void phy_write_1bit(void __iomem *ioaddr, u32 phy_data)
> {
> - outl(phy_data, ioaddr); /* MII Clock Low */
> + dw32(DCR9, phy_data); /* MII Clock Low */
> udelay(1);
> - outl(phy_data | MDCLKH, ioaddr); /* MII Clock High */
> + dw32(DCR9, phy_data | MDCLKH); /* MII Clock High */
> udelay(1);
> - outl(phy_data, ioaddr); /* MII Clock Low */
> + dw32(DCR9, phy_data); /* MII Clock Low */
> udelay(1);
> }
>
> @@ -1885,14 +1895,14 @@ static void phy_write_1bit(unsigned long ioaddr, u32 phy_data)
> * Read one bit phy data from PHY controller
> */
>
> -static u16 phy_read_1bit(unsigned long ioaddr)
> +static u16 phy_read_1bit(void __iomem *ioaddr)
> {
> u16 phy_data;
>
> - outl(0x50000, ioaddr);
> + dw32(DCR9, 0x50000);
> udelay(1);
> - phy_data = ( inl(ioaddr) >> 19 ) & 0x1;
> - outl(0x40000, ioaddr);
> + phy_data = (dr32(DCR9) >> 19) & 0x1;
> + dw32(DCR9, 0x40000);
> udelay(1);
>
> return phy_data;
> @@ -1978,7 +1988,7 @@ static void dmfe_parse_srom(struct dmfe_board_info * db)
>
> /* Check DM9801 or DM9802 present or not */
> db->HPNA_present = 0;
> - update_cr6(db->cr6_data|0x40000, db->ioaddr);
> + update_cr6(db->cr6_data | 0x40000, db->ioaddr);
> tmp_reg = phy_read(db->ioaddr, db->phy_addr, 3, db->chip_id);
> if ( ( tmp_reg & 0xfff0 ) == 0xb900 ) {
> /* DM9801 or DM9802 present */
> @@ -2095,6 +2105,7 @@ static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state)
> {
> struct net_device *dev = pci_get_drvdata(pci_dev);
> struct dmfe_board_info *db = netdev_priv(dev);
> + void __iomem *ioaddr = db->ioaddr;
> u32 tmp;
>
> /* Disable upper layer interface */
> @@ -2102,11 +2113,11 @@ static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state)
>
> /* Disable Tx/Rx */
> db->cr6_data &= ~(CR6_RXSC | CR6_TXSC);
> - update_cr6(db->cr6_data, dev->base_addr);
> + update_cr6(db->cr6_data, ioaddr);
>
> /* Disable Interrupt */
> - outl(0, dev->base_addr + DCR7);
> - outl(inl (dev->base_addr + DCR5), dev->base_addr + DCR5);
> + dw32(DCR7, 0);
> + dw32(DCR5, dr32(DCR5));
>
> /* Fre RX buffers */
> dmfe_free_rxbuffer(db);
> --
> 1.7.7.6
>
^ 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