* Re: netlink NETLINK_ROUTE failure & Can the kernel really handle IPv6 properly
From: Ulf Samuelsson @ 2014-10-03 5:59 UTC (permalink / raw)
To: Dan Williams, Ulf samuelsson; +Cc: Hannes Frederic Sowa, Linux Netdev List
In-Reply-To: <1412264648.7227.9.camel@dcbw.local>
On 10/02/2014 05:44 PM, Dan Williams wrote:
> On Thu, 2014-10-02 at 14:38 +0200, Ulf samuelsson wrote:
>> This is the significant code, and it is wrong.
>>
>> static struct notifier_block my_ipv6_address_notifier =
>> {
>> my_ipv6_address_notifier_cb,
>> NULL,
>> 0
>> };
>>
>> register_inet6addr_notifier (&my_ipv6_address_notifier );
>>
>> int
>> my_ipv6_address_notifier_cb (struct notifier_block *self,
>> unsigned long event, void *val)
>> {
>> struct inet6_ifaddr *ifaddr = (struct inet6_ifaddr *)val;
>>
>>
>> /* We are only interested in address add/delete events */
>> /* IPv6 address add comes as NETDEV_UP and delete comes as
>> * NETDEV_DOWN
>> */
>> if ((event != NETDEV_UP) && (event != NETDEV_DOWN))
>> return ret;
>>
>> if (ifaddr == NULL)
>> return ret;
>> /* Now that we are sure that it is a IPv6 address being added deleted,
>> * verify that it is a link local address.
>> */
>> if (!IPV6_IS_ADDR_LINKLOCAL (&ifaddr->addr))
>> {
>> return ret;
>> }
>> ...
>> send_message_to_app(LINK_LOCAL_UP, ip);
>> ...
>> return ret;
>> }
>>
>>
>> Application tries to send message to "ip" and fails, because the link-local adress is still
>> in "tentative state"
> It seems to me that a better architecture would be to have the app
> itself listen for RTM_NEWADDR netlink event and look for lack of
> IFA_F_TENTATIVE in the IFA_FLAGS attribute. Using a kernel module to do
> the same thing seems pretty wrong.
>
> Dan
Thanks, Maybe you are right but I do not have all the details.
The kernel module is part of a driver for a Broadcom router chip.
The guys writing the driver might want to know as well.
I will see what they say.
Best Regards,
Ulf Samuelsson
>> Best Regards
>> Ulf Samuelsson
>> ulf@emagii.com
>> +46 (722) 427 437
>>
>>
>>> 1 okt 2014 kl. 23:30 skrev Hannes Frederic Sowa <hannes@stressinduktion.org>:
>>>
>>> Hello,
>>>
>>>> On Wed, Oct 1, 2014, at 22:28, Ulf Samuelsson wrote:
>>>> BTW, the problem I am trying to solve is how to connect to an I/F with
>>>> an IPv6 link-local address.
>>>>
>>>> An existing kernel module waits for a NETDEV_UP event, and then tries to
>>>> communicate
>>>> with the link-local address.
>>>>
>>>> This will fail, because (according to a colleague) the I/F enters a
>>>> "tentative" state,
>>>> where it is trying to decide if it is unique or not.
>>>> It will remain in that state for 1-2 seconds, and only afterwards is the
>>>> link-local address
>>>> available for normal use.
>>>>
>>>> The guys writing the module, claim that the kernel is using NETDEV_UP.
>>>> There is very little code in the kernel using NETLINK_ROUTE, even in
>>>> latest stable.
>>>> It is using NETDEV_UP.
>>>>
>>>> If my colleague is right, the kernel really cannot handle IPv6
>>>> link-local addresses properly.
>>> Sorry, I cannot really follow you, can you send example code or be a bit
>>> more precise?
>>>
>>> Thanks,
>>> Hannes
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* <Reply ASAP>
From: Mr. James @ 2014-10-02 20:54 UTC (permalink / raw)
To: Recipients
Sequel to your non-response to my previous email, I am re-sending this to you again thus; A deceased client of mine who died of a heart-related ailment about 3 years ago left behind some funds which I want you to assist in retriving and distributing. Reply so I can give you details on what is needed to be done.
Regards,
James.
^ permalink raw reply
* Re: [RFC PATCH linux 2/2] fs/proc: use a hash table for the directory entries
From: Nicolas Dichtel @ 2014-10-03 7:28 UTC (permalink / raw)
To: Eric W. Biederman, Alexey Dobriyan
Cc: netdev, linux-kernel, davem, akpm, rui.xiang, viro, oleg,
gorcunov, kirill.shutemov, grant.likely, tytso, Thierry Herbelot
In-Reply-To: <87h9zmji3q.fsf@x220.int.ebiederm.org>
Le 02/10/2014 23:07, Eric W. Biederman a écrit :
> Alexey Dobriyan <adobriyan@gmail.com> writes:
>
>> On Thu, Oct 02, 2014 at 11:01:50AM -0700, Eric W. Biederman wrote:
>>> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>>>
>>>> From: Thierry Herbelot <thierry.herbelot@6wind.com>
>>>>
>>>> The current implementation for the directories in /proc is using a single
>>>> linked list. This is slow when handling directories with large numbers of
>>>> entries (eg netdevice-related entries when lots of tunnels are opened).
>>>>
>>>> This patch enables multiple linked lists. A hash based on the entry name is
>>>> used to select the linked list for one given entry.
>>>>
>>>> The speed creation of netdevices is faster as shorter linked lists must be
>>>> scanned when adding a new netdevice.
>>>
>>> Is the directory of primary concern /proc/net/dev/snmp6 ?
>>>
>>> Unless I have configured my networking stack weird by mistake that
>>> is the only directory under /proc/net that grows when we add an
>>> interface.
>>>
>>> I just want to make certain I am seeing the same things that you are
>>> seeing.
>>>
>>> I feel silly for overlooking this directory when the rest of the
>>> scalability work was done.
>>
>> Slowdown comes from "duplicate name" check:
>>
>> for (tmp = dir->subdir; tmp; tmp = tmp->next)
>> if (strcmp(tmp->name, dp->name) == 0) {
>> WARN(1, "proc_dir_entry '%s/%s' already registered\n",
>> dir->name, dp->name);
>> break;
>> }
>>
>> Removal can be made O(1) after switching to doubly-linked list.
>
> Yes. There is the however unfortunate fact that proc directories exist
> to be used. If we don't switch to a better data structure than a linked
> list the actual use will then opening of the files under
> /proc/net/dev/snmp6/ will become O(N^2). Which doesn't help much
> (assuming those files are good for something).
>
> If those files aren't actually useful we should just make registering
> them a config option. Deprecate them strongly and let only people who
> need extreme backwards compatibility enable them.
>
> Alexey do you know that those files aren't useful? Unless we know
> otherwise we should make those files useful.
This was proposed and nacked in a first version:
http://thread.gmane.org/gmane.linux.network/285840/
Regards,
Nicolas
^ permalink raw reply
* Re: HW bridging support using notifiers?
From: Jiri Pirko @ 2014-10-03 7:53 UTC (permalink / raw)
To: Scott Feldman
Cc: Florian Fainelli, netdev, davem, stephen, andy, tgraf, nbd,
john.r.fastabend, edumazet, vyasevic, buytenh
In-Reply-To: <A97C2083-CFD9-4238-9C43-97EF43200124@cumulusnetworks.com>
Fri, Oct 03, 2014 at 07:13:35AM CEST, sfeldma@cumulusnetworks.com wrote:
>
>On Oct 2, 2014, at 6:48 PM, Florian Fainelli <f.fainelli@gmail.com> wrote:
>
>> Hi all,
>>
>> I am taking a look at adding HW bridging support to DSA, in way that's
>> usable outside of DSA.
>>
>> Lennert's approach in 2008 [1] looks conceptually good to me,as he
>> noted, it uses a bunch of new ndo's which is not only limiting to one
>> ndo implementer per struct net_device, but also is mostly consuming the
>> information from the bridge layer, while the ndo is an action
>>
>> So here's what I am up to now:
>>
>> - use the NETDEV_JOIN notifier to discover when a bridge port is added
>> - use the NETDEV_LEAVE notifier, still need to verify this does not
>> break netconsole as indicated in net/bridge/br_if.c
>
>I can’t find a NETDEV_LEAVE...is this new?
>
>For this, rocker is using netdev_notifier and watching for NETDEV_CHANGEUPPER. On CHANGEUPPER, use netdev_master_upper_dev_get(dev) to get master. If master and master rtnl_link_ops->kind is “bridge”, then dev port is in bridge; otherwise port is not in bridge. Of course, master could be “openvswitch”, if the driver swings both ways.
I agree that NETDEV_CHANGEUPPER should be used for this.
>
>Would this approach work for DSA?
>
>> - use the NETDEV_CHANGEINFODATA notifier to notify about STP state changes
>>
>> Now, this raises a bunch of questions:
>>
>> - we would need a getter to return the stp state of a given network
>> device when called with NETDEV_CHANGEINFODATA, is that acceptable? This
>> would be the first function exported by the bridge layer to expose
>> internal data
>>
>> NB: this also raises the question of the race condition and locking
>> within br_set_stp_state() and when the network devices notifier callback
>> runs
>>
>> - or do we need a new network device notifier accepting an opaque
>> pointer which could provide us with the data we what, something like
>> this: call_netdevices_notifier_data(NETDEV_CHANGEINFODATA, dev, info),
>> where info would be a structure/union telling what's this data about
>>
>
>We need STP state change notification for rocker also, so we can install/remove STP/ARP filters on port state change. Netdev_notifier would work. I was also thinking about using Jiri’s ndo_swdev_flow_install/remove to install/remove the STP filters on the port, rather than using netdev_notifier. In other words, does the HW bridge driver need to know the STP state or can it be dumb (stateless) and told when to accept STP BPDUs, or not, using swdev_flow construct:
>
> dst_mac 01:80:c2:00:00:00 lasp 0x4242 in_port <port ifindex> actions output <br ifindex>
>
>and later when reaching LEARNING state:
>
> dst_mac ff:ff:ff:ff:ff:ff eth_type ARP in_port <port ifindex> actions output <br ifindex>
>
>and finally when reaching FORWARDING state, the learned/static bridge fdbs:
>
> dst_mac <neigh_mac> in_port <br ifindex> actions output <port ifindex>
>
>So driver doesn’t really know what STP is; it’s just installs/removes port filter when told to, using the common ndo_swdev_flow API. The smarts stay in the bridge driver.
>
>
>> Let me know what you think, thanks!
>>
>> [1]: http://patchwork.ozlabs.org/patch/16578/
>> --
>> Florian
>
>
>-scott
>
>
>
^ permalink raw reply
* Re: bug: race in team_{notify_peers,mcast_rejoin} scheduling
From: Jiri Pirko @ 2014-10-03 8:04 UTC (permalink / raw)
To: Joe Lawrence; +Cc: netdev
In-Reply-To: <20141002145028.2f62838c@jlaw-desktop.mno.stratus.com>
Thu, Oct 02, 2014 at 08:50:28PM CEST, joe.lawrence@stratus.com wrote:
>Hello Jiri,
>
>Occasionally on boot I noticed that team_notify_peers_work would get
>*very* busy.
>
>With the following debugging added to team_notify_peers:
>
> netdev_info(team->dev, "%s(%p)\n", __func__, team);
> dump_stack();
>
>I saw the following:
>
>% dmesg | grep -e 'team[0-9]: team_notify_peers' -e 'port_enable' -e 'port_disable'
>[ 68.340861] team0: team_notify_peers(ffff88104ffa4de0)
>[ 68.743264] [<ffffffffa034fd38>] team_port_enable.part.40+0x78/0x90 [team]
>[ 69.622395] team0: team_notify_peers(ffff88104ffa4de0)
>[ 69.966758] [<ffffffffa034ef63>] team_port_disable+0x123/0x160 [team]
>[ 71.099263] team0: team_notify_peers(ffff88104ffa4de0)
>[ 71.466243] [<ffffffffa034fd38>] team_port_enable.part.40+0x78/0x90 [team]
>[ 72.383788] team0: team_notify_peers(ffff88104ffa4de0)
>[ 72.744778] [<ffffffffa034ef63>] team_port_disable+0x123/0x160 [team]
>[ 73.476190] team0: team_notify_peers(ffff88104ffa4de0)
>[ 73.830592] [<ffffffffa034fd38>] team_port_enable.part.40+0x78/0x90 [team]
>[ 74.796738] team1: team_notify_peers(ffff88104f5df080)
>[ 75.165577] [<ffffffffa034fd38>] team_port_enable.part.40+0x78/0x90 [team]
>[ 75.694968] team1: team_notify_peers(ffff88104f5df080)
>[ 75.694984] [<ffffffffa034ef63>] team_port_disable+0x123/0x160 [team]
>[ 77.316488] team1: team_notify_peers(ffff88104f5df080)
>[ 77.663122] [<ffffffffa034fd38>] team_port_enable.part.40+0x78/0x90 [team]
>[ 78.470488] team1: team_notify_peers(ffff88104f5df080)
>[ 78.814722] [<ffffffffa034ef63>] team_port_disable+0x123/0x160 [team]
>[ 82.690765] team2: team_notify_peers(ffff88083d24df40)
>[ 83.083540] [<ffffffffa034fd38>] team_port_enable.part.40+0x78/0x90 [team]
>[ 83.942458] team2: team_notify_peers(ffff88083d24df40)
>[ 84.286446] [<ffffffffa034ef63>] team_port_disable+0x123/0x160 [team]
>[ 86.089955] team3: team_notify_peers(ffff88083fd14de0)
>[ 86.453495] [<ffffffffa034fd38>] team_port_enable.part.40+0x78/0x90 [team]
>[ 87.267773] team3: team_notify_peers(ffff88083fd14de0)
>[ 87.610203] [<ffffffffa034ef63>] team_port_disable+0x123/0x160 [team]
>
>which shows team_port_enable/disable getting invoked in short
>succession. When looking at one of the team's
>notify_peers.count_pending value, I saw that it was negative and slowly
>counting down from 0xffff...ffff!
>
>This lead me believe that there is a race condition present in
>the .count_pending pattern that both team_notify_peers and
>team_mcast_rejoin employ.
>
>Can you comment on the following patch/workaround?
Well, I can't see a better solution. Adding is fine here I believe.
Acked-by: Jiri Pirko <jiri@resnulli.us>
Please send to patch with my ack and with:
Fixes: fc423ff00df3a19554414ee ("team: add peer notification")
So it can be pushed to stable.
Thanks!
>
>Thanks,
>
>-- Joe
>
>-->8-- -->8-- -->8--
>
>From b11d7dcd051a2f141c1eec0a43c4a4ddf0361d10 Mon Sep 17 00:00:00 2001
>From: Joe Lawrence <joe.lawrence@stratus.com>
>Date: Thu, 2 Oct 2014 14:24:26 -0400
>Subject: [PATCH] team: avoid race condition in scheduling delayed work
>
>When team_notify_peers and team_mcast_rejoin are called, they both reset
>their respective .count_pending atomic variable. Then when the actual
>worker function is executed, the variable is atomically decremented.
>This pattern introduces a potential race condition where the
>.count_pending rolls over and the worker function keeps rescheduling
>until .count_pending decrements to zero again:
>
>THREAD 1 THREAD 2
>======== ========
>team_notify_peers(teamX)
> atomic_set count_pending = 1
> schedule_delayed_work
> team_notify_peers(teamX)
> atomic_set count_pending = 1
>team_notify_peers_work
> atomic_dec_and_test
> count_pending = 0
> (return)
> schedule_delayed_work
> team_notify_peers_work
> atomic_dec_and_test
> count_pending = -1
> schedule_delayed_work
> (repeat until count_pending = 0)
>
>Instead of assigning a new value to .count_pending, use atomic_add to
>tack-on the additional desired worker function invocations.
>
>Signed-off-by: Joe Lawrence <joe.lawrence@stratus.com>
>---
> drivers/net/team/team.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
>index d46df38..2b87e3f 100644
>--- a/drivers/net/team/team.c
>+++ b/drivers/net/team/team.c
>@@ -647,7 +647,7 @@ static void team_notify_peers(struct team *team)
> {
> if (!team->notify_peers.count || !netif_running(team->dev))
> return;
>- atomic_set(&team->notify_peers.count_pending, team->notify_peers.count);
>+ atomic_add(team->notify_peers.count, &team->notify_peers.count_pending);
> schedule_delayed_work(&team->notify_peers.dw, 0);
> }
>
>@@ -687,7 +687,7 @@ static void team_mcast_rejoin(struct team *team)
> {
> if (!team->mcast_rejoin.count || !netif_running(team->dev))
> return;
>- atomic_set(&team->mcast_rejoin.count_pending, team->mcast_rejoin.count);
>+ atomic_add(team->mcast_rejoin.count, &team->mcast_rejoin.count_pending);
> schedule_delayed_work(&team->mcast_rejoin.dw, 0);
> }
>
>--
>1.7.10.4
>
>
>
^ permalink raw reply
* [PATCH net] ematch: Fix the matching of inverted containers (again).
From: Ignacy Gawędzki @ 2014-10-03 8:06 UTC (permalink / raw)
To: netdev
The result of a negated container has to be inverted before checking for
early ending.
Signed-off-by: Ignacy Gawędzki <ignacy.gawedzki@green-communications.fr>
---
net/sched/ematch.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index ad57f44..300ecf6 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -526,11 +526,12 @@ pop_stack:
match_idx = stack[--stackp];
cur_match = tcf_em_get_match(tree, match_idx);
- if (tcf_em_early_end(cur_match, res)) {
- if (tcf_em_is_inverted(cur_match))
- res = !res;
+ if (tcf_em_is_inverted(cur_match))
+ res = !res;
+
+ if (tcf_em_early_end(cur_match, res))
goto pop_stack;
- } else {
+ else {
match_idx++;
goto proceed;
}
--
1.9.1
^ permalink raw reply related
* xen netback
From: Tomas Mozes @ 2014-10-03 8:00 UTC (permalink / raw)
To: netdev
On some of our xen-dom0 machines running 3.14.x we have a problem of
domU's freezing. This has been fixed in:
http://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/commit/drivers/net/xen-netback/netback.c?id=59ae9fc67007da8b5aea7b0a31c3607745cfbfee
and the patch has been included in 3.16.x, but I cannot find it in the
current longterm releases. We have an open gentoo bug report about it:
https://bugs.gentoo.org/show_bug.cgi?id=517852
This bug doesn't happen on all xen-dom0 machines, but I can confirm that
on the problematic machine after applying the aforemention patch, the
problem gone away and the system has been running for 60 days without
problems.
Please consider applying the patch to the longterm kernels.
Thank you
^ permalink raw reply
* Re: netlink NETLINK_ROUTE failure & Can the kernel really handle IPv6 properly
From: Ulf Samuelsson @ 2014-10-03 7:59 UTC (permalink / raw)
To: Dan Williams, Ulf samuelsson; +Cc: Hannes Frederic Sowa, Linux Netdev List
In-Reply-To: <1412264648.7227.9.camel@dcbw.local>
On 10/02/2014 05:44 PM, Dan Williams wrote:
> On Thu, 2014-10-02 at 14:38 +0200, Ulf samuelsson wrote:
>> This is the significant code, and it is wrong.
>>
>> static struct notifier_block my_ipv6_address_notifier =
>> {
>> my_ipv6_address_notifier_cb,
>> NULL,
>> 0
>> };
>>
>> register_inet6addr_notifier (&my_ipv6_address_notifier );
>>
>> int
>> my_ipv6_address_notifier_cb (struct notifier_block *self,
>> unsigned long event, void *val)
>> {
>> struct inet6_ifaddr *ifaddr = (struct inet6_ifaddr *)val;
>>
>>
>> /* We are only interested in address add/delete events */
>> /* IPv6 address add comes as NETDEV_UP and delete comes as
>> * NETDEV_DOWN
>> */
>> if ((event != NETDEV_UP) && (event != NETDEV_DOWN))
>> return ret;
>>
>> if (ifaddr == NULL)
>> return ret;
>> /* Now that we are sure that it is a IPv6 address being added deleted,
>> * verify that it is a link local address.
>> */
>> if (!IPV6_IS_ADDR_LINKLOCAL (&ifaddr->addr))
>> {
>> return ret;
>> }
>> ...
>> send_message_to_app(LINK_LOCAL_UP, ip);
>> ...
>> return ret;
>> }
>>
>>
>> Application tries to send message to "ip" and fails, because the link-local adress is still
>> in "tentative state"
> It seems to me that a better architecture would be to have the app
> itself listen for RTM_NEWADDR netlink event and look for lack of
> IFA_F_TENTATIVE in the IFA_FLAGS attribute. Using a kernel module to do
> the same thing seems pretty wrong.
>
> Dan
OK, got more information. This is part of a fairly large and complex system.
The kernel module is a control module which collects information
both from the kernel and from H/W, and talks to a userspace interface
manager.
There is a proprietary management application which is used to configure
the stack.
This talks to the interface manager to handle different operations for IPv6.
The kernel module needs to know when interfaces are ready to use,
I.E: know when it exits "tentative" mode to do its job properly,
so the kernel module has to listen for RTM_NEWADDR.
In a simpler system, your approach would be OK.
Best Regards,
Ulf Samuelsson
>> Best Regards
>> Ulf Samuelsson
>> ulf@emagii.com
>> +46 (722) 427 437
>>
>>
>>> 1 okt 2014 kl. 23:30 skrev Hannes Frederic Sowa <hannes@stressinduktion.org>:
>>>
>>> Hello,
>>>
>>>> On Wed, Oct 1, 2014, at 22:28, Ulf Samuelsson wrote:
>>>> BTW, the problem I am trying to solve is how to connect to an I/F with
>>>> an IPv6 link-local address.
>>>>
>>>> An existing kernel module waits for a NETDEV_UP event, and then tries to
>>>> communicate
>>>> with the link-local address.
>>>>
>>>> This will fail, because (according to a colleague) the I/F enters a
>>>> "tentative" state,
>>>> where it is trying to decide if it is unique or not.
>>>> It will remain in that state for 1-2 seconds, and only afterwards is the
>>>> link-local address
>>>> available for normal use.
>>>>
>>>> The guys writing the module, claim that the kernel is using NETDEV_UP.
>>>> There is very little code in the kernel using NETLINK_ROUTE, even in
>>>> latest stable.
>>>> It is using NETDEV_UP.
>>>>
>>>> If my colleague is right, the kernel really cannot handle IPv6
>>>> link-local addresses properly.
>>> Sorry, I cannot really follow you, can you send example code or be a bit
>>> more precise?
>>>
>>> Thanks,
>>> Hannes
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v1 5/5] driver-core: add driver asynchronous probe support
From: Tom Gundersen @ 2014-10-03 8:23 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: One Thousand Gnomes, Takashi Iwai, Kay Sievers, pmladek, LKML,
Michal Hocko, Praveen Krishnamoorthy, hare, Nagalakshmi Nandigama,
werner, Tetsuo Handa, mpt-fusionlinux.pdl, Tim Gardner,
Benjamin Poirier, Santosh Rastapur, Casey Leedom, Hariprasad S,
Pierre Fersing, dbueso, Sreekanth Reddy, Arjan van de Ven,
Abhijit Mahajan, systemd
In-Reply-To: <20141002200612.GQ14081@wotan.suse.de>
On Thu, Oct 2, 2014 at 10:06 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> On Thu, Oct 02, 2014 at 08:12:37AM +0200, Tom Gundersen wrote:
>> Making kmod a special case is of course possible. However, as long as
>> there is no fundamental reason why kmod should get this special
>> treatment, this just looks like a work-around to me.
>
> I've mentioned a series of five reasons why its a bad idea right now to
> sigkill modules [0], we're reviewed them each and still at least
> items 2-4 remain particularly valid fundamental reasons to avoid it
So items 2-4 basically say "there currently are drivers that cannot
deal with sigkill after a three minute timeout".
In the short-term we already have the solution: increase the timeout.
In the long-term, we have two choices, either permanently add some
heuristic to udev to deal with drivers taking a very long time to be
inserted, or fix the drivers not to take such a long time. A priori,
it makes no sense to me that drivers spend unbounded amounts of time
to get inserted, so fixing the drivers seems like the most reasonable
approach to me. That said, I'm of course open to be proven wrong if
there are some drivers that fundamentally _must_ take a long time to
insert (but we should then discuss why that is and how we can best
deal with the situation, rather than adding some hack up-front when we
don't even know if it is needed).
Your patch series should go a long way towards fixing the drivers (and
I imagine there being a lot of low-hanging fruit that can easily be
fixed once your series has landed), and the fact that we have now
increased the udev timeout from 30 to 180 seconds should also greatly
reduce the problem.
Cheers,
Tom
^ permalink raw reply
* Re: [PATCH v1 0/4] Enable FEC pps ouput
From: Richard Cochran @ 2014-10-03 8:23 UTC (permalink / raw)
To: Luwei Zhou
Cc: davem, netdev, shawn.guo, bhutchings, R49496, b38611, b20596,
stephen
In-Reply-To: <1411632621-17429-1-git-send-email-b45643@freescale.com>
On Thu, Sep 25, 2014 at 04:10:17PM +0800, Luwei Zhou wrote:
> This patch does:
> - Replace 32-bit free-running PTP timer with 31-bit.
> - Implement hardware PTP timestamp adjustment.
> - Enable PPS output based on hardware adjustment.
>
>
> Luwei Zhou (4):
> net: fec: ptp: Use the 31-bit ptp timer.
> net: fec: ptp: Use hardware algorithm to adjust PTP counter.
> net: fec: ptp: Enalbe PPS ouput based on ptp clock
^^^^^^ ^^^^^
Enable output
Also, it looks like you have implemented the wrong feature.
The "pps" capability means that the clock provides a PPS event
(interrupt) to the kernel.
IOW, if .pps==1, then you must call ptp_clock_event() with event type
PTP_CLOCK_PPS.
Your patch set seems to be creating a periodic output and not a PPS
kernel callback.
You should clarify what you are trying to do, and then implement the
appropriate interface in your driver.
Thanks,
Richard
^ permalink raw reply
* [PATCH v2 net-next] r8169:add support for RTL8168EP
From: Chun-Hao Lin @ 2014-10-03 9:20 UTC (permalink / raw)
To: netdev; +Cc: nic_swsd, linux-kernel, Chun-Hao Lin
RTL8168EP is Realtek PCIe Gigabit Ethernet controller.
It is a successor chip of RTL8168DP.
For RTL8168EP, the read/write ocp register is via eri channel type 2,
so I modify ocp_read() ocp_write() and move related functions under
rtl_eri_read() rtl_eri_write().
The way of checking if dash is enabled and setting driver start/stop
are also different with RTL8168DP.
Right now, RTL8168EP phy mcu did not need patch firmware code, so I
did not add firmware code for it.
Signed-off-by: Chun-Hao Lin <hau@realtek.com>
---
drivers/net/ethernet/realtek/r8169.c | 512 ++++++++++++++++++++++++++++++++---
1 file changed, 467 insertions(+), 45 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 54476ba..3efdf4d 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -155,6 +155,9 @@ enum mac_version {
RTL_GIGA_MAC_VER_46,
RTL_GIGA_MAC_VER_47,
RTL_GIGA_MAC_VER_48,
+ RTL_GIGA_MAC_VER_49,
+ RTL_GIGA_MAC_VER_50,
+ RTL_GIGA_MAC_VER_51,
RTL_GIGA_MAC_NONE = 0xff,
};
@@ -302,6 +305,15 @@ static const struct {
[RTL_GIGA_MAC_VER_48] =
_R("RTL8107e", RTL_TD_1, FIRMWARE_8107E_2,
JUMBO_1K, false),
+ [RTL_GIGA_MAC_VER_49] =
+ _R("RTL8168ep/8111ep", RTL_TD_1, NULL,
+ JUMBO_9K, false),
+ [RTL_GIGA_MAC_VER_50] =
+ _R("RTL8168ep/8111ep", RTL_TD_1, NULL,
+ JUMBO_9K, false),
+ [RTL_GIGA_MAC_VER_51] =
+ _R("RTL8168ep/8111ep", RTL_TD_1, NULL,
+ JUMBO_9K, false),
};
#undef _R
@@ -400,6 +412,10 @@ enum rtl_registers {
FuncEvent = 0xf0,
FuncEventMask = 0xf4,
FuncPresetState = 0xf8,
+ IBCR0 = 0xf8,
+ IBCR2 = 0xf9,
+ IBIMR0 = 0xfa,
+ IBISR0 = 0xfb,
FuncForceEvent = 0xfc,
};
@@ -467,6 +483,7 @@ enum rtl8168_registers {
#define ERIAR_EXGMAC (0x00 << ERIAR_TYPE_SHIFT)
#define ERIAR_MSIX (0x01 << ERIAR_TYPE_SHIFT)
#define ERIAR_ASF (0x02 << ERIAR_TYPE_SHIFT)
+#define ERIAR_OOB (0x02 << ERIAR_TYPE_SHIFT)
#define ERIAR_MASK_SHIFT 12
#define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT)
#define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT)
@@ -935,40 +952,6 @@ static const struct rtl_cond name = { \
\
static bool name ## _check(struct rtl8169_private *tp)
-DECLARE_RTL_COND(rtl_ocpar_cond)
-{
- void __iomem *ioaddr = tp->mmio_addr;
-
- return RTL_R32(OCPAR) & OCPAR_FLAG;
-}
-
-static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
-{
- void __iomem *ioaddr = tp->mmio_addr;
-
- RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
-
- return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 100, 20) ?
- RTL_R32(OCPDR) : ~0;
-}
-
-static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data)
-{
- void __iomem *ioaddr = tp->mmio_addr;
-
- RTL_W32(OCPDR, data);
- RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
-
- rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 100, 20);
-}
-
-DECLARE_RTL_COND(rtl_eriar_cond)
-{
- void __iomem *ioaddr = tp->mmio_addr;
-
- return RTL_R32(ERIAR) & ERIAR_FLAG;
-}
-
static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg)
{
if (reg & 0xffff0001) {
@@ -1110,6 +1093,13 @@ static int r8169_mdio_read(struct rtl8169_private *tp, int reg)
return value;
}
+DECLARE_RTL_COND(rtl_ocpar_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(OCPAR) & OCPAR_FLAG;
+}
+
static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data)
{
void __iomem *ioaddr = tp->mmio_addr;
@@ -1245,6 +1235,13 @@ static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr)
RTL_R32(EPHYAR) & EPHYAR_DATA_MASK : ~0;
}
+DECLARE_RTL_COND(rtl_eriar_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(ERIAR) & ERIAR_FLAG;
+}
+
static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask,
u32 val, int type)
{
@@ -1276,6 +1273,52 @@ static void rtl_w0w1_eri(struct rtl8169_private *tp, int addr, u32 mask, u32 p,
rtl_eri_write(tp, addr, mask, (val & ~m) | p, type);
}
+static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
+ return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 100, 20)
+ ? RTL_R32(OCPDR) : ~0;
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
+ return rtl_eri_read(tp, reg, ERIAR_OOB);
+ default:
+ BUG();
+ return ~0;
+ }
+}
+
+static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ RTL_W32(OCPDR, data);
+ RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 |
+ (reg & 0x0fff));
+ rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 100, 20);
+ break;
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
+ rtl_eri_write(tp, reg, ((u32)mask & 0x0f) << ERIAR_MASK_SHIFT,
+ data, ERIAR_OOB);
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd)
{
rtl_eri_write(tp, 0xe8, ERIAR_MASK_0001, cmd, ERIAR_EXGMAC);
@@ -1301,25 +1344,84 @@ DECLARE_RTL_COND(rtl_ocp_read_cond)
return ocp_read(tp, 0x0f, reg) & 0x00000800;
}
-static void rtl8168_driver_start(struct rtl8169_private *tp)
+DECLARE_RTL_COND(rtl_ep_ocp_read_cond)
{
- rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
+ return ocp_read(tp, 0x0f, 0x124) & 0x00000001;
+}
+
+DECLARE_RTL_COND(rtl_ocp_tx_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
- rtl_msleep_loop_wait_high(tp, &rtl_ocp_read_cond, 10, 10);
+ return RTL_R8(IBISR0) & 0x02;
+}
+
+static void rtl8168_driver_start(struct rtl8169_private *tp)
+{
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
+ rtl_msleep_loop_wait_high(tp, &rtl_ocp_read_cond, 10, 10);
+ break;
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
+ ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START);
+ ocp_write(tp, 0x01, 0x30, ocp_read(tp, 0x01, 0x30) | 0x01);
+ rtl_msleep_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10, 10);
+ break;
+ default:
+ BUG();
+ break;
+ }
}
static void rtl8168_driver_stop(struct rtl8169_private *tp)
{
- rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);
+ void __iomem *ioaddr = tp->mmio_addr;
- rtl_msleep_loop_wait_low(tp, &rtl_ocp_read_cond, 10, 10);
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);
+ rtl_msleep_loop_wait_low(tp, &rtl_ocp_read_cond, 10, 10);
+ break;
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
+ RTL_W8(IBCR2, RTL_R8(IBCR2) & ~0x01);
+ rtl_msleep_loop_wait_low(tp, &rtl_ocp_tx_cond, 50, 2000);
+ RTL_W8(IBISR0, RTL_R8(IBISR0) | 0x20);
+ RTL_W8(IBCR0, RTL_R8(IBCR0) & ~0x01);
+ ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP);
+ ocp_write(tp, 0x01, 0x30, ocp_read(tp, 0x01, 0x30) | 0x01);
+ rtl_msleep_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10, 10);
+ break;
+ default:
+ BUG();
+ break;
+ }
}
static int r8168_check_dash(struct rtl8169_private *tp)
{
u16 reg = rtl8168_get_ocp_reg(tp);
- return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0;
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0;
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
+ return (ocp_read(tp, 0x0f, 0x128) & 0x00000001) ? 1 : 0;
+ default:
+ return 0;
+ }
}
struct exgmac_reg {
@@ -1553,6 +1655,9 @@ static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
if (rtl_eri_read(tp, 0xdc, ERIAR_EXGMAC) & MagicPacket_v2)
wolopts |= WAKE_MAGIC;
break;
@@ -1620,6 +1725,9 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
tmp = ARRAY_SIZE(cfg) - 1;
if (wolopts & WAKE_MAGIC)
rtl_w0w1_eri(tp,
@@ -2126,6 +2234,11 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
u32 val;
int mac_version;
} mac_info[] = {
+ /* 8168EP family. */
+ { 0x7cf00000, 0x50200000, RTL_GIGA_MAC_VER_51 },
+ { 0x7cf00000, 0x50100000, RTL_GIGA_MAC_VER_50 },
+ { 0x7cf00000, 0x50000000, RTL_GIGA_MAC_VER_49 },
+
/* 8168H family. */
{ 0x7cf00000, 0x54100000, RTL_GIGA_MAC_VER_46 },
{ 0x7cf00000, 0x54000000, RTL_GIGA_MAC_VER_45 },
@@ -3741,6 +3854,139 @@ static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x1f, 0x0000);
}
+static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp)
+{
+ /* Enable PHY auto speed down */
+ rtl_writephy(tp, 0x1f, 0x0a44);
+ rtl_w0w1_phy(tp, 0x11, 0x000c, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ /* patch 10M & ALDPS */
+ rtl_writephy(tp, 0x1f, 0x0bcc);
+ rtl_w0w1_phy(tp, 0x14, 0x0000, 0x0100);
+ rtl_writephy(tp, 0x1f, 0x0a44);
+ rtl_w0w1_phy(tp, 0x11, 0x00c0, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0a43);
+ rtl_writephy(tp, 0x13, 0x8084);
+ rtl_w0w1_phy(tp, 0x14, 0x0000, 0x6000);
+ rtl_w0w1_phy(tp, 0x10, 0x1003, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ /* Enable EEE auto-fallback function */
+ rtl_writephy(tp, 0x1f, 0x0a4b);
+ rtl_w0w1_phy(tp, 0x11, 0x0004, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ /* Enable UC LPF tune function */
+ rtl_writephy(tp, 0x1f, 0x0a43);
+ rtl_writephy(tp, 0x13, 0x8012);
+ rtl_w0w1_phy(tp, 0x14, 0x8000, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ /* set rg_sel_sdm_rate */
+ rtl_writephy(tp, 0x1f, 0x0c42);
+ rtl_w0w1_phy(tp, 0x11, 0x4000, 0x2000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ /* Check ALDPS bit, disable it if enabled */
+ rtl_writephy(tp, 0x1f, 0x0a43);
+ if (rtl_readphy(tp, 0x10) & 0x0004)
+ rtl_w0w1_phy(tp, 0x10, 0x0000, 0x0004);
+
+ rtl_writephy(tp, 0x1f, 0x0000);
+}
+
+static void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp)
+{
+ /* patch 10M & ALDPS */
+ rtl_writephy(tp, 0x1f, 0x0bcc);
+ rtl_w0w1_phy(tp, 0x14, 0x0000, 0x0100);
+ rtl_writephy(tp, 0x1f, 0x0a44);
+ rtl_w0w1_phy(tp, 0x11, 0x00c0, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0a43);
+ rtl_writephy(tp, 0x13, 0x8084);
+ rtl_w0w1_phy(tp, 0x14, 0x0000, 0x6000);
+ rtl_w0w1_phy(tp, 0x10, 0x1003, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ /* Enable UC LPF tune function */
+ rtl_writephy(tp, 0x1f, 0x0a43);
+ rtl_writephy(tp, 0x13, 0x8012);
+ rtl_w0w1_phy(tp, 0x14, 0x8000, 0x0000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ /* Set rg_sel_sdm_rate */
+ rtl_writephy(tp, 0x1f, 0x0c42);
+ rtl_w0w1_phy(tp, 0x11, 0x4000, 0x2000);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ /* Channel estimation parameters */
+ rtl_writephy(tp, 0x1f, 0x0a43);
+ rtl_writephy(tp, 0x13, 0x80f3);
+ rtl_w0w1_phy(tp, 0x14, 0x8b00, ~0x8bff);
+ rtl_writephy(tp, 0x13, 0x80f0);
+ rtl_w0w1_phy(tp, 0x14, 0x3a00, ~0x3aff);
+ rtl_writephy(tp, 0x13, 0x80ef);
+ rtl_w0w1_phy(tp, 0x14, 0x0500, ~0x05ff);
+ rtl_writephy(tp, 0x13, 0x80f6);
+ rtl_w0w1_phy(tp, 0x14, 0x6e00, ~0x6eff);
+ rtl_writephy(tp, 0x13, 0x80ec);
+ rtl_w0w1_phy(tp, 0x14, 0x6800, ~0x68ff);
+ rtl_writephy(tp, 0x13, 0x80ed);
+ rtl_w0w1_phy(tp, 0x14, 0x7c00, ~0x7cff);
+ rtl_writephy(tp, 0x13, 0x80f2);
+ rtl_w0w1_phy(tp, 0x14, 0xf400, ~0xf4ff);
+ rtl_writephy(tp, 0x13, 0x80f4);
+ rtl_w0w1_phy(tp, 0x14, 0x8500, ~0x85ff);
+ rtl_writephy(tp, 0x1f, 0x0a43);
+ rtl_writephy(tp, 0x13, 0x8110);
+ rtl_w0w1_phy(tp, 0x14, 0xa800, ~0xa8ff);
+ rtl_writephy(tp, 0x13, 0x810f);
+ rtl_w0w1_phy(tp, 0x14, 0x1d00, ~0x1dff);
+ rtl_writephy(tp, 0x13, 0x8111);
+ rtl_w0w1_phy(tp, 0x14, 0xf500, ~0xf5ff);
+ rtl_writephy(tp, 0x13, 0x8113);
+ rtl_w0w1_phy(tp, 0x14, 0x6100, ~0x61ff);
+ rtl_writephy(tp, 0x13, 0x8115);
+ rtl_w0w1_phy(tp, 0x14, 0x9200, ~0x92ff);
+ rtl_writephy(tp, 0x13, 0x810e);
+ rtl_w0w1_phy(tp, 0x14, 0x0400, ~0x04ff);
+ rtl_writephy(tp, 0x13, 0x810c);
+ rtl_w0w1_phy(tp, 0x14, 0x7C00, ~0x7Cff);
+ rtl_writephy(tp, 0x13, 0x810b);
+ rtl_w0w1_phy(tp, 0x14, 0x5a00, ~0x5aff);
+ rtl_writephy(tp, 0x1f, 0x0a43);
+ rtl_writephy(tp, 0x13, 0x80d1);
+ rtl_w0w1_phy(tp, 0x14, 0xff00, ~0xffff);
+ rtl_writephy(tp, 0x13, 0x80cd);
+ rtl_w0w1_phy(tp, 0x14, 0x9e00, ~0x9eff);
+ rtl_writephy(tp, 0x13, 0x80d3);
+ rtl_w0w1_phy(tp, 0x14, 0x0e00, ~0x0eff);
+ rtl_writephy(tp, 0x13, 0x80d5);
+ rtl_w0w1_phy(tp, 0x14, 0xca00, ~0xcaff);
+ rtl_writephy(tp, 0x13, 0x80d7);
+ rtl_w0w1_phy(tp, 0x14, 0x8400, ~0x84ff);
+
+ /* Force PWM-mode */
+ rtl_writephy(tp, 0x1f, 0x0bcd);
+ rtl_writephy(tp, 0x14, 0x5065);
+ rtl_writephy(tp, 0x14, 0xd065);
+ rtl_writephy(tp, 0x1f, 0x0bC8);
+ rtl_writephy(tp, 0x12, 0x00ed);
+ rtl_writephy(tp, 0x1f, 0x0bcd);
+ rtl_writephy(tp, 0x14, 0x1065);
+ rtl_writephy(tp, 0x14, 0x9065);
+ rtl_writephy(tp, 0x14, 0x1065);
+ rtl_writephy(tp, 0x1f, 0x0000);
+
+ /* Check ALDPS bit, disable it if enabled */
+ rtl_writephy(tp, 0x1f, 0x0a43);
+ if (rtl_readphy(tp, 0x10) & 0x0004)
+ rtl_w0w1_phy(tp, 0x10, 0x0000, 0x0004);
+
+ rtl_writephy(tp, 0x1f, 0x0000);
+}
+
static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
@@ -3940,6 +4186,14 @@ static void rtl_hw_phy_config(struct net_device *dev)
rtl8168h_2_hw_phy_config(tp);
break;
+ case RTL_GIGA_MAC_VER_49:
+ rtl8168ep_1_hw_phy_config(tp);
+ break;
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
+ rtl8168ep_2_hw_phy_config(tp);
+ break;
+
case RTL_GIGA_MAC_VER_41:
default:
break;
@@ -4154,6 +4408,9 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
ops->write = r8168g_mdio_write;
ops->read = r8168g_mdio_read;
break;
@@ -4212,6 +4469,9 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
RTL_W32(RxConfig, RTL_R32(RxConfig) |
AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
break;
@@ -4356,7 +4616,10 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
if ((tp->mac_version == RTL_GIGA_MAC_VER_27 ||
tp->mac_version == RTL_GIGA_MAC_VER_28 ||
- tp->mac_version == RTL_GIGA_MAC_VER_31) &&
+ tp->mac_version == RTL_GIGA_MAC_VER_31 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_49 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_50 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_51) &&
r8168_check_dash(tp)) {
return;
}
@@ -4387,10 +4650,13 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_44:
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80);
break;
case RTL_GIGA_MAC_VER_40:
case RTL_GIGA_MAC_VER_41:
+ case RTL_GIGA_MAC_VER_49:
rtl_w0w1_eri(tp, 0x1a8, ERIAR_MASK_1111, 0x00000000,
0xfc000000, ERIAR_EXGMAC);
RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80);
@@ -4415,10 +4681,13 @@ static void r8168_pll_power_up(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_44:
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
RTL_W8(PMCH, RTL_R8(PMCH) | 0xc0);
break;
case RTL_GIGA_MAC_VER_40:
case RTL_GIGA_MAC_VER_41:
+ case RTL_GIGA_MAC_VER_49:
RTL_W8(PMCH, RTL_R8(PMCH) | 0xc0);
rtl_w0w1_eri(tp, 0x1a8, ERIAR_MASK_1111, 0xfc000000,
0x00000000, ERIAR_EXGMAC);
@@ -4493,6 +4762,9 @@ static void rtl_init_pll_power_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_44:
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
ops->down = r8168_pll_power_down;
ops->up = r8168_pll_power_up;
break;
@@ -4547,6 +4819,9 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF);
break;
default:
@@ -4712,6 +4987,9 @@ static void rtl_init_jumbo_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
default:
ops->disable = NULL;
ops->enable = NULL;
@@ -4828,7 +5106,10 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
tp->mac_version == RTL_GIGA_MAC_VER_45 ||
tp->mac_version == RTL_GIGA_MAC_VER_46 ||
tp->mac_version == RTL_GIGA_MAC_VER_47 ||
- tp->mac_version == RTL_GIGA_MAC_VER_48) {
+ tp->mac_version == RTL_GIGA_MAC_VER_48 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_49 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_50 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_51) {
RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq);
rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
} else {
@@ -5754,6 +6035,120 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
r8168_mac_ocp_write(tp, 0xc09e, 0x0000);
}
+static void rtl_hw_start_8168ep(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ struct pci_dev *pdev = tp->pci_dev;
+
+ RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);
+
+ rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x00080002, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, 0x2f, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xd0, ERIAR_MASK_0001, 0x5f, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
+
+ rtl_csi_access_enable_1(tp);
+
+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+
+ rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
+ rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
+
+ rtl_w0w1_eri(tp, 0xd4, ERIAR_MASK_1111, 0x1f80, 0x00, ERIAR_EXGMAC);
+
+ rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87, ERIAR_EXGMAC);
+
+ RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+ RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN);
+ RTL_W8(MaxTxPacketSize, EarlySize);
+
+ rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+
+ /* Adjust EEE LED frequency */
+ RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07);
+
+ rtl_w0w1_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06, ERIAR_EXGMAC);
+
+ RTL_W8(DLLPR, RTL_R8(DLLPR) & ~TX_10M_PS_EN);
+
+ rtl_pcie_state_l2l3_enable(tp, false);
+}
+
+static void rtl_hw_start_8168ep_1(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ static const struct ephy_info e_info_8168ep_1[] = {
+ { 0x00, 0xffff, 0x10ab },
+ { 0x06, 0xffff, 0xf030 },
+ { 0x08, 0xffff, 0x2006 },
+ { 0x0d, 0xffff, 0x1666 },
+ { 0x0c, 0x3ff0, 0x0000 }
+ };
+
+ /* disable aspm and clock request before access ephy */
+ RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
+ RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+ rtl_ephy_init(tp, e_info_8168ep_1, ARRAY_SIZE(e_info_8168ep_1));
+
+ rtl_hw_start_8168ep(tp);
+}
+
+static void rtl_hw_start_8168ep_2(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ static const struct ephy_info e_info_8168ep_2[] = {
+ { 0x00, 0xffff, 0x10a3 },
+ { 0x19, 0xffff, 0xfc00 },
+ { 0x1e, 0xffff, 0x20ea }
+ };
+
+ /* disable aspm and clock request before access ephy */
+ RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
+ RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+ rtl_ephy_init(tp, e_info_8168ep_2, ARRAY_SIZE(e_info_8168ep_2));
+
+ rtl_hw_start_8168ep(tp);
+
+ RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN);
+ RTL_W8(DLLPR, RTL_R8(MISC_1) & ~PFM_D3COLD_EN);
+}
+
+static void rtl_hw_start_8168ep_3(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ u32 data;
+ static const struct ephy_info e_info_8168ep_3[] = {
+ { 0x00, 0xffff, 0x10a3 },
+ { 0x19, 0xffff, 0x7c00 },
+ { 0x1e, 0xffff, 0x20eb },
+ { 0x0d, 0xffff, 0x1666 }
+ };
+
+ /* disable aspm and clock request before access ephy */
+ RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
+ RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+ rtl_ephy_init(tp, e_info_8168ep_3, ARRAY_SIZE(e_info_8168ep_3));
+
+ rtl_hw_start_8168ep(tp);
+
+ RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN);
+ RTL_W8(DLLPR, RTL_R8(MISC_1) & ~PFM_D3COLD_EN);
+
+ data = r8168_mac_ocp_read(tp, 0xd3e2);
+ data &= 0xf000;
+ data |= 0x0271;
+ r8168_mac_ocp_write(tp, 0xd3e2, data);
+
+ data = r8168_mac_ocp_read(tp, 0xd3e4);
+ data &= 0xff00;
+ r8168_mac_ocp_write(tp, 0xd3e4, data);
+
+ data = r8168_mac_ocp_read(tp, 0xe860);
+ data |= 0x0080;
+ r8168_mac_ocp_write(tp, 0xe860, data);
+}
+
static void rtl_hw_start_8168(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -5869,6 +6264,18 @@ static void rtl_hw_start_8168(struct net_device *dev)
rtl_hw_start_8168h_1(tp);
break;
+ case RTL_GIGA_MAC_VER_49:
+ rtl_hw_start_8168ep_1(tp);
+ break;
+
+ case RTL_GIGA_MAC_VER_50:
+ rtl_hw_start_8168ep_2(tp);
+ break;
+
+ case RTL_GIGA_MAC_VER_51:
+ rtl_hw_start_8168ep_3(tp);
+ break;
+
default:
printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n",
dev->name, tp->mac_version);
@@ -7399,7 +7806,10 @@ static void rtl_remove_one(struct pci_dev *pdev)
if ((tp->mac_version == RTL_GIGA_MAC_VER_27 ||
tp->mac_version == RTL_GIGA_MAC_VER_28 ||
- tp->mac_version == RTL_GIGA_MAC_VER_31) &&
+ tp->mac_version == RTL_GIGA_MAC_VER_31 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_49 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_50 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_51) &&
r8168_check_dash(tp)) {
rtl8168_driver_stop(tp);
}
@@ -7556,6 +7966,9 @@ static void rtl_hw_initialize(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
rtl_hw_init_8168g(tp);
break;
@@ -7708,6 +8121,9 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
+ case RTL_GIGA_MAC_VER_49:
+ case RTL_GIGA_MAC_VER_50:
+ case RTL_GIGA_MAC_VER_51:
if (rtl_eri_read(tp, 0xdc, ERIAR_EXGMAC) & MagicPacket_v2)
tp->features |= RTL_FEATURE_WOL;
if ((RTL_R8(Config3) & LinkUp) != 0)
@@ -7756,7 +8172,10 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->mac_version == RTL_GIGA_MAC_VER_45 ||
tp->mac_version == RTL_GIGA_MAC_VER_46 ||
tp->mac_version == RTL_GIGA_MAC_VER_47 ||
- tp->mac_version == RTL_GIGA_MAC_VER_48) {
+ tp->mac_version == RTL_GIGA_MAC_VER_48 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_49 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_50 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_51) {
u16 mac_addr[3];
*(u32 *)&mac_addr[0] = rtl_eri_read(tp, 0xe0, ERIAR_EXGMAC);
@@ -7835,7 +8254,10 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if ((tp->mac_version == RTL_GIGA_MAC_VER_27 ||
tp->mac_version == RTL_GIGA_MAC_VER_28 ||
- tp->mac_version == RTL_GIGA_MAC_VER_31) &&
+ tp->mac_version == RTL_GIGA_MAC_VER_31 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_49 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_50 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_51) &&
r8168_check_dash(tp)) {
rtl8168_driver_start(tp);
}
--
1.8.3.2
^ permalink raw reply related
* [patch] checkpatch: remove the ether_addr_copy warning
From: Dan Carpenter @ 2014-10-03 9:35 UTC (permalink / raw)
To: Andy Whitcroft, Andrew Morton
Cc: Joe Perches, netdev, kernel-janitors, gregkh
Most people sending checkpatch.pl fixes don't know how to verify the
alignment. This checkpatch warning just encourages newbies to try
introduce bugs. Patch submitters tell us that they just sed the code
and it's the job for the maintainer to check that it's correct.
If you want to work on these then you can get the same information by
typing `grep -nw memcpy drivers/net/ -R | grep ETH_ALEN`
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 52a223e..d540dd4 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -4698,16 +4698,6 @@ sub process {
}
}
-# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
- if ($^V && $^V ge 5.10.0 &&
- $line =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/s) {
- if (WARN("PREFER_ETHER_ADDR_COPY",
- "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . $herecurr) &&
- $fix) {
- $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
- }
- }
-
# typecasts on min/max could be min_t/max_t
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
^ permalink raw reply related
* [net-next PATCH] veth: don't assign a qdisc to veth
From: Jesper Dangaard Brouer @ 2014-10-03 10:48 UTC (permalink / raw)
To: Jesper Dangaard Brouer, netdev, David S. Miller; +Cc: Jiri Pirko, mpatel
The veth driver is a virtual device, and should not have assigned
the default qdisc. Verified (ndo_start_xmit) veth_xmit can only
return NETDEV_TX_OK, thus this should be safe to bypass qdisc.
Not assigning a qdisc is subtly done by setting tx_queue_len to zero.
Reported-by: Mrunal Patel <mpatel@redhat.com>
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
drivers/net/veth.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 8ad5965..3c32fcf 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -287,6 +287,7 @@ static const struct net_device_ops veth_netdev_ops = {
static void veth_setup(struct net_device *dev)
{
ether_setup(dev);
+ dev->tx_queue_len = 0;
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
^ permalink raw reply related
* Re: [RFC PATCH linux 2/2] fs/proc: use a hash table for the directory entries
From: Alexey Dobriyan @ 2014-10-03 10:55 UTC (permalink / raw)
To: Nicolas Dichtel
Cc: netdev, Linux Kernel, David Miller, Eric W. Biederman,
Andrew Morton, rui.xiang, Al Viro, Oleg Nesterov, Cyrill Gorcunov,
kirill.shutemov, Grant Likely, Theodore Ts'o,
Thierry Herbelot
In-Reply-To: <1412263501-6572-3-git-send-email-nicolas.dichtel@6wind.com>
On Thu, Oct 2, 2014 at 6:25 PM, Nicolas Dichtel
<nicolas.dichtel@6wind.com> wrote:
> --- a/fs/proc/generic.c
> +++ b/fs/proc/generic.c
> @@ -81,10 +81,13 @@ static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
> + if (!S_ISDIR(de->mode))
> + return -EINVAL;
There are way too many S_ISDIR checks.
In lookup and readdir, it is guaranteed that PDE is directory.
I'd say all of them aren't needed because non-directories have
->subdir = NULL and
directories have ->subdir != NULL which transforms into hashtable or
rbtree or whatever,
so you only need to guarantee only directories appear where they are
expected and
fearlessly use your new data structure traversing directories.
Alexey
^ permalink raw reply
* Re: [PATCH 1/1] bridge: Fix NAT66ed IPv6 packets not being bridged correctly
From: Pablo Neira Ayuso @ 2014-10-03 11:21 UTC (permalink / raw)
To: bernhard.thaler
Cc: David Miller, kuznet, jmorris, yoshfuji, kaber, stephen, netdev,
bridge, linux-kernel, netfilter-devel, sven
In-Reply-To: <20140915.174009.1151039353244879675.davem@davemloft.net>
Hi Bernhard,
Sorry for taking a bit to get back to you with feedback. We've been
discussing recently some changes in br_netfilter. Basically, to
modularize it [1] and this has taken a while.
Regarding your change. Sven Eckelmann (CC'ed in this email) sent a RFC
out of the merge window that have remain tagged in my patchwork, you
can find it here.
http://patchwork.ozlabs.org/patch/381027/
I would like to see a submission that covers all NAT66 scenarios that
we currenty support.
Thanks.
[1] http://comments.gmane.org/gmane.comp.security.firewalls.netfilter.devel/54234
On Mon, Sep 15, 2014 at 05:40:09PM -0400, David Miller wrote:
> From: Bernhard Thaler <bernhard.thaler@wvnet.at>
> Date: Mon, 15 Sep 2014 23:27:28 +0200
>
> CC:'ing netfilter-devel and the netfilter maintainer, which is
> probably the primary place this patch should have been submitted.
>
> > Ethernet frames are not bridged to correct interface when packets have
> > been NAT66ed; compared to IPv4 logic in code, IPv6 code does not store
> > original address (before NAT) on transmit to determine if packet was
> > NAT66ed on receive to swap addresses back.
> >
> > Changes added in br_netfilter.c to store original address, compare
> > against it and determine correct output interface. Changes needed in
> > netfilter_bridge.h to store IPv6 address in pre-existing union.
> > Export of ip6_route_input needed to use it in br_netfilter.c.
> >
> > Problem may only affect systems doing NAT66 and ethernet bridging at
> > the same time. Tested in NAT66 setup on base of an ethernet bridge.
> >
> > Signed-off-by: Bernhard Thaler <bernhard.thaler@wvnet.at>
> > ---
> > include/linux/netfilter_bridge.h | 2 +
> > net/bridge/br_netfilter.c | 136 ++++++++++++++++++++++++++++----------
> > net/ipv6/route.c | 1 +
> > 3 files changed, 105 insertions(+), 34 deletions(-)
> >
> > diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
> > index 8ab1c27..3a9cdcd 100644
> > --- a/include/linux/netfilter_bridge.h
> > +++ b/include/linux/netfilter_bridge.h
> > @@ -2,6 +2,7 @@
> > #define __LINUX_BRIDGE_NETFILTER_H
> >
> > #include <uapi/linux/netfilter_bridge.h>
> > +#include <uapi/linux/in6.h>
> >
> >
> > enum nf_br_hook_priorities {
> > @@ -79,6 +80,7 @@ static inline unsigned int nf_bridge_pad(const struct sk_buff *skb)
> > struct bridge_skb_cb {
> > union {
> > __be32 ipv4;
> > + struct in6_addr ipv6;
> > } daddr;
> > };
> >
> > diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
> > index a615264..2ae3888 100644
> > --- a/net/bridge/br_netfilter.c
> > +++ b/net/bridge/br_netfilter.c
> > @@ -35,6 +35,9 @@
> > #include <net/ip.h>
> > #include <net/ipv6.h>
> > #include <net/route.h>
> > +#include <net/ip6_route.h>
> > +#include <net/flow.h>
> > +#include <net/dst.h>
> >
> > #include <asm/uaccess.h>
> > #include "br_private.h"
> > @@ -42,10 +45,18 @@
> > #include <linux/sysctl.h>
> > #endif
> >
> > -#define skb_origaddr(skb) (((struct bridge_skb_cb *) \
> > - (skb->nf_bridge->data))->daddr.ipv4)
> > -#define store_orig_dstaddr(skb) (skb_origaddr(skb) = ip_hdr(skb)->daddr)
> > -#define dnat_took_place(skb) (skb_origaddr(skb) != ip_hdr(skb)->daddr)
> > +#define skb_origaddr(skb) (((struct bridge_skb_cb *)\
> > + (skb->nf_bridge->data))->daddr.ipv4)
> > +#define skb_origaddr_ipv6(skb) (((struct bridge_skb_cb *)\
> > + (skb->nf_bridge->data))->daddr.ipv6)
> > +#define store_orig_dstaddr(skb) (skb_origaddr(skb) = ip_hdr(skb)->daddr)
> > +#define store_orig_dstaddr_ipv6(skb) (skb_origaddr_ipv6(skb) = \
> > + ipv6_hdr(skb)->daddr)
> > +#define dnat_took_place(skb) (skb_origaddr(skb) != \
> > + ip_hdr(skb)->daddr)
> > +#define dnat_took_place_ipv6(skb) (memcmp(&skb_origaddr_ipv6(skb), \
> > + &(ipv6_hdr(skb)->daddr), \
> > + sizeof(struct in6_addr)) != 0)
> >
> > #ifdef CONFIG_SYSCTL
> > static struct ctl_table_header *brnf_sysctl_header;
> > @@ -340,36 +351,6 @@ int nf_bridge_copy_header(struct sk_buff *skb)
> > return 0;
> > }
> >
> > -/* PF_BRIDGE/PRE_ROUTING *********************************************/
> > -/* Undo the changes made for ip6tables PREROUTING and continue the
> > - * bridge PRE_ROUTING hook. */
> > -static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
> > -{
> > - struct nf_bridge_info *nf_bridge = skb->nf_bridge;
> > - struct rtable *rt;
> > -
> > - if (nf_bridge->mask & BRNF_PKT_TYPE) {
> > - skb->pkt_type = PACKET_OTHERHOST;
> > - nf_bridge->mask ^= BRNF_PKT_TYPE;
> > - }
> > - nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
> > -
> > - rt = bridge_parent_rtable(nf_bridge->physindev);
> > - if (!rt) {
> > - kfree_skb(skb);
> > - return 0;
> > - }
> > - skb_dst_set_noref(skb, &rt->dst);
> > -
> > - skb->dev = nf_bridge->physindev;
> > - nf_bridge_update_protocol(skb);
> > - nf_bridge_push_encap_header(skb);
> > - NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
> > - br_handle_frame_finish, 1);
> > -
> > - return 0;
> > -}
> > -
> > /* Obtain the correct destination MAC address, while preserving the original
> > * source MAC address. If we already know this address, we just copy it. If we
> > * don't, we use the neighbour framework to find out. In both cases, we make
> > @@ -527,6 +508,92 @@ bridged_dnat:
> > return 0;
> > }
> >
> > +/* PF_BRIDGE/PRE_ROUTING *********************************************
> > + * Undo the changes made for ip6tables PREROUTING and continue the
> > + * bridge PRE_ROUTING hook.
> > + */
> > +static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
> > +{
> > + struct net_device *dev = skb->dev;
> > + struct ipv6hdr *iph = ipv6_hdr(skb);
> > + struct nf_bridge_info *nf_bridge = skb->nf_bridge;
> > + struct rtable *rt;
> > + struct dst_entry *dst;
> > + struct flowi6 fl6 = {
> > + .flowi6_iif = skb->dev->ifindex,
> > + .daddr = iph->daddr,
> > + .saddr = iph->saddr,
> > + .flowlabel = ip6_flowinfo(iph),
> > + .flowi6_mark = skb->mark,
> > + .flowi6_proto = iph->nexthdr,
> > + };
> > +
> > + if (nf_bridge->mask & BRNF_PKT_TYPE) {
> > + skb->pkt_type = PACKET_OTHERHOST;
> > + nf_bridge->mask ^= BRNF_PKT_TYPE;
> > + }
> > + nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
> > +
> > + if (dnat_took_place_ipv6(skb)) {
> > + ip6_route_input(skb);
> > + /* ip6_route_input is void function,
> > + * no int returned as in ip4_route_input
> > + * changes value of skb->_skb_refdst) on success
> > + */
> > + if (skb->_skb_refdst == 0) {
> > + struct in_device *in_dev = __in_dev_get_rcu(dev);
> > +
> > + if (!in_dev || IN_DEV_FORWARD(in_dev))
> > + goto free_skb;
> > +
> > + dst = ip6_route_output(dev_net(dev), skb->sk, &fl6);
> > + if (!IS_ERR(dst)) {
> > + /* - Bridged-and-DNAT'ed traffic doesn't
> > + * require ip_forwarding.
> > + */
> > + if (dst->dev == dev) {
> > + skb_dst_set(skb, dst);
> > + goto bridged_dnat;
> > + }
> > + dst_release(dst);
> > + }
> > +free_skb:
> > + kfree_skb(skb);
> > + return 0;
> > + } else {
> > + if (skb_dst(skb)->dev == dev) {
> > +bridged_dnat:
> > + skb->dev = nf_bridge->physindev;
> > + nf_bridge_update_protocol(skb);
> > + nf_bridge_push_encap_header(skb);
> > + NF_HOOK_THRESH(NFPROTO_BRIDGE,
> > + NF_BR_PRE_ROUTING,
> > + skb, skb->dev, NULL,
> > + br_nf_pre_routing_finish_bridge,
> > + 1);
> > + return 0;
> > + }
> > + memcpy(eth_hdr(skb)->h_dest, dev->dev_addr, ETH_ALEN);
> > + skb->pkt_type = PACKET_HOST;
> > + }
> > + } else {
> > + rt = bridge_parent_rtable(nf_bridge->physindev);
> > + if (!rt) {
> > + kfree_skb(skb);
> > + return 0;
> > + }
> > + skb_dst_set_noref(skb, &rt->dst);
> > + }
> > +
> > + skb->dev = nf_bridge->physindev;
> > + nf_bridge_update_protocol(skb);
> > + nf_bridge_push_encap_header(skb);
> > + NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
> > + br_handle_frame_finish, 1);
> > +
> > + return 0;
> > +}
> > +
> > static struct net_device *brnf_get_logical_dev(struct sk_buff *skb, const struct net_device *dev)
> > {
> > struct net_device *vlan, *br;
> > @@ -658,6 +725,7 @@ static unsigned int br_nf_pre_routing_ipv6(const struct nf_hook_ops *ops,
> > if (!setup_pre_routing(skb))
> > return NF_DROP;
> >
> > + store_orig_dstaddr_ipv6(skb);
> > skb->protocol = htons(ETH_P_IPV6);
> > NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
> > br_nf_pre_routing_finish_ipv6);
> > diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> > index f23fbd2..e328905 100644
> > --- a/net/ipv6/route.c
> > +++ b/net/ipv6/route.c
> > @@ -1017,6 +1017,7 @@ void ip6_route_input(struct sk_buff *skb)
> >
> > skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags));
> > }
> > +EXPORT_SYMBOL(ip6_route_input);
> >
> > static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
> > struct flowi6 *fl6, int flags)
> > --
> > 1.7.10.4
> >
^ permalink raw reply
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Nicolas Dichtel @ 2014-10-03 12:22 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Andy Lutomirski, Network Development, Linux Containers,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux API,
David S. Miller, Stephen Hemminger, Andrew Morton, Cong Wang
In-Reply-To: <8761g2nurx.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
Le 02/10/2014 21:20, Eric W. Biederman a écrit :
> Nicolas Dichtel <nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org> writes:
>
>> Le 29/09/2014 20:43, Eric W. Biederman a écrit :
>>> Nicolas Dichtel <nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org> writes:
>>>
>>>> Le 26/09/2014 20:57, Eric W. Biederman a écrit :
>>>>> Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org> writes:
>>>>>
>>>>>> On Fri, Sep 26, 2014 at 11:10 AM, Eric W. Biederman
>>>>>> <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> wrote:
>>>>>>> I see two ways to go with this.
>>>>>>>
>>>>>>> - A per network namespace table to that you can store ids for ``peer''
>>>>>>> network namespaces. The table would need to be populated manually by
>>>>>>> the likes of ip netns add.
>>>>>>>
>>>>>>> That flips the order of assignment and makes this idea solid.
>>>> I have a preference for this solution, because it allows to have a full
>>>> broadcast messages. When you have a lot of network interfaces (> 10k),
>>>> it saves a lot of time to avoid another request to get all informations.
>>>
>>> My practical question is how often does it happen that we care?
>> In fact, I don't think that scenarii with a lot of netns have a full mesh of
>> x-netns interfaces. It will be more one "link" netns with the physical
>> interface and all other with one interface with the link part in this "link"
>> netns. Hence, only one nsid is needing in each netns.
>
> I will buy that a full mesh is unlikely.
>
> For people doing simulations anything physical has a limited number of
> links.
>
> For people wanting all to all connectivity setting up an internal
> macvlan (or the equivalent) is likely much simpler and more efficient
> that a full mesh.
>
> So the question in my mind is how do we create these identifiers at need
> (when we create the cross network namespace links) instead of at network
> namespace creation time. I don't see an answer to that in your patches,
> and perhaps it obvious.
For me, it is the responsability of the user who creates the netns. He should
know what will be done with this new netns, hence he may or may not define an
id. It's also possible to delegate this to the user who will create the tunnel.
In other words, it's part of the configuration.
^ permalink raw reply
* Re: [RFC PATCH net-next v3 1/4] netns: add genl cmd to add and get peer netns ids
From: Nicolas Dichtel @ 2014-10-03 12:22 UTC (permalink / raw)
To: Eric W. Biederman
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
luto-kltTT9wpgjJwATOyAt5JVQ, cwang-xCSkyg8dI+0RB7SZvlqPiA
In-Reply-To: <87tx3mmflp.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
Le 02/10/2014 21:33, Eric W. Biederman a écrit :
> Nicolas Dichtel <nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org> writes:
>
>> With this patch, a user can define an id for a peer netns by providing a FD or a
>> PID. These ids are local to netns (ie valid only into one netns).
>>
>> This will be useful for netlink messages when a x-netns interface is
>> dumped.
>
> You have a "id -> struct net *" table but you don't have a
> "struct net * -> id" table which looks like it will impact the
> performance of peernet2id at scale.
It is indirectly stores in 'struct idr'. It can be optimized later, with a
proper algorithm to find quickly this 'struct net *' (hash table? something
else?). A basic algorithm will not be more scalable than the current
idr_for_each().
^ permalink raw reply
* Re: [PATCH net] ematch: Fix the matching of inverted containers (again).
From: Sergei Shtylyov @ 2014-10-03 12:22 UTC (permalink / raw)
To: Ignacy Gawędzki, netdev
In-Reply-To: <20141003080600.GA13146@zenon.in.qult.net>
Hello.
On 10/3/2014 12:06 PM, Ignacy Gawędzki wrote:
> The result of a negated container has to be inverted before checking for
> early ending.
> Signed-off-by: Ignacy Gawędzki <ignacy.gawedzki@green-communications.fr>
> ---
> net/sched/ematch.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
> diff --git a/net/sched/ematch.c b/net/sched/ematch.c
> index ad57f44..300ecf6 100644
> --- a/net/sched/ematch.c
> +++ b/net/sched/ematch.c
> @@ -526,11 +526,12 @@ pop_stack:
> match_idx = stack[--stackp];
> cur_match = tcf_em_get_match(tree, match_idx);
>
> - if (tcf_em_early_end(cur_match, res)) {
> - if (tcf_em_is_inverted(cur_match))
> - res = !res;
> + if (tcf_em_is_inverted(cur_match))
> + res = !res;
> +
> + if (tcf_em_early_end(cur_match, res))
> goto pop_stack;
> - } else {
> + else {
> match_idx++;
> goto proceed;
> }
The kernel style dictates that an *if* statement should have {} in all its
arms, if it has {} in at least one of the arms.
WBR, Sergei
^ permalink raw reply
* Re: [PATCH v2 3/6] dtb: Add 10GbE node to APM X-Gene SoC device tree
From: Mark Rutland @ 2014-10-03 12:49 UTC (permalink / raw)
To: Iyappan Subramanian
Cc: davem@davemloft.net, netdev@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
patches@apm.com, kchudgar@apm.com
In-Reply-To: <1412294568-26747-4-git-send-email-isubramanian@apm.com>
Hi,
[...]
> + xgenet: ethernet@1f610000 {
> + compatible = "apm,xgene-enet";
> + status = "disabled";
> + reg = <0x0 0x1f610000 0x0 0xd100>,
> + <0x0 0x1f600000 0x0 0X400>,
> + <0x0 0x18000000 0x0 0X200>;
> + reg-names = "enet_csr", "ring_csr", "ring_cmd";
> + interrupts = <0x0 0x60 0x4>;
> + dma-coherent;
> + clocks = <&xge0clk 0>;
> + local-mac-address = [00 01 73 00 00 04];
Apolgoies, I'd missed your reply on this last time. Please use
all-zeroes for the mac address, and have a comment that this will be
overwritten by the bootloader.
Thanks,
Mark.
^ permalink raw reply
* Re: [RFC PATCH linux 2/2] fs/proc: use a hash table for the directory entries
From: Nicolas Dichtel @ 2014-10-03 13:07 UTC (permalink / raw)
To: Alexey Dobriyan
Cc: netdev, linux-kernel, davem, ebiederm, akpm, rui.xiang, viro,
oleg, gorcunov, kirill.shutemov, grant.likely, tytso,
Thierry Herbelot
In-Reply-To: <20141002172814.GA2435@p183.telecom.by>
Le 02/10/2014 19:28, Alexey Dobriyan a écrit :
> On Thu, Oct 02, 2014 at 05:25:01PM +0200, Nicolas Dichtel wrote:
>> +static inline unsigned int proc_pde_name_hash(const unsigned char *name,
>> + const unsigned int len)
>> +{
>> + return full_name_hash(name, len) & PROC_PDE_HASH_MASK;
>> +}
>
> PDE already stands for "proc dir entry" :^)
>
> Alexey
>
Oops, will fix it in v2.
Thank you,
Nicolas
^ permalink raw reply
* Re: [RFC PATCH linux 2/2] fs/proc: use a hash table for the directory entries
From: Nicolas Dichtel @ 2014-10-03 13:07 UTC (permalink / raw)
To: Alexey Dobriyan
Cc: netdev, Linux Kernel, David Miller, Eric W. Biederman,
Andrew Morton, rui.xiang, Al Viro, Oleg Nesterov, Cyrill Gorcunov,
kirill.shutemov, Grant Likely, Theodore Ts'o,
Thierry Herbelot
In-Reply-To: <CACVxJT98EJvw1E+o6mpu8ugMz3Ztqz7pJOwZeZW9A41P0AhB_g@mail.gmail.com>
Le 03/10/2014 12:55, Alexey Dobriyan a écrit :
> On Thu, Oct 2, 2014 at 6:25 PM, Nicolas Dichtel
> <nicolas.dichtel@6wind.com> wrote:
>> --- a/fs/proc/generic.c
>> +++ b/fs/proc/generic.c
>> @@ -81,10 +81,13 @@ static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
>
>> + if (!S_ISDIR(de->mode))
>> + return -EINVAL;
>
> There are way too many S_ISDIR checks.
> In lookup and readdir, it is guaranteed that PDE is directory.
>
> I'd say all of them aren't needed because non-directories have
> ->subdir = NULL and
> directories have ->subdir != NULL which transforms into hashtable or
> rbtree or whatever,
> so you only need to guarantee only directories appear where they are
> expected and
> fearlessly use your new data structure traversing directories.
To be honest, they was put during the debug stage and I hesitated to remove
them at the end.
I will remove them!
Thank you,
Nicolas
^ permalink raw reply
* Re: [RFC PATCH linux 2/2] fs/proc: use a hash table for the directory entries
From: Nicolas Dichtel @ 2014-10-03 13:09 UTC (permalink / raw)
To: Eric W. Biederman
Cc: netdev, linux-kernel, davem, akpm, adobriyan, rui.xiang, viro,
oleg, gorcunov, kirill.shutemov, grant.likely, tytso,
Thierry Herbelot
In-Reply-To: <87h9zmpcz5.fsf@x220.int.ebiederm.org>
Le 02/10/2014 20:01, Eric W. Biederman a écrit :
> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>
>> From: Thierry Herbelot <thierry.herbelot@6wind.com>
>>
>> The current implementation for the directories in /proc is using a single
>> linked list. This is slow when handling directories with large numbers of
>> entries (eg netdevice-related entries when lots of tunnels are opened).
>>
>> This patch enables multiple linked lists. A hash based on the entry name is
>> used to select the linked list for one given entry.
>>
>> The speed creation of netdevices is faster as shorter linked lists must be
>> scanned when adding a new netdevice.
>
> Is the directory of primary concern /proc/net/dev/snmp6 ?
Yes.
>
> Unless I have configured my networking stack weird by mistake that
> is the only directory under /proc/net that grows when we add an
> interface.
>
> I just want to make certain I am seeing the same things that you are
> seeing.
>
> I feel silly for overlooking this directory when the rest of the
> scalability work was done.
>
>> Here are some numbers:
>>
>> dummy30000.batch contains 30 000 times 'link add type dummy'.
>>
>> Before the patch:
>> time ip -b dummy30000.batch
>> real 2m32.221s
>> user 0m0.380s
>> sys 2m30.610s
>>
>> After the patch:
>> time ip -b dummy30000.batch
>> real 1m57.190s
>> user 0m0.350s
>> sys 1m56.120s
>>
>> The single 'subdir' list head is replaced by a subdir hash table. The subdir
>> hash buckets are only allocated for directories. The number of hash buckets
>> is a compile-time parameter.
>
> That looks like a nice speed up. A couple of things.
>
> With sysfs and sysctl when faced this class of challenge we used an
> rbtree instead of a hash table. That should use less memory and scale
> better.
>
> I am concerned about a fixed sized hash table moving the location where
> we fall off a cliff but not removing the cliff itself.
>
> I suppose it would be possible to use the new fancy resizable hash
> tables but previous work on sysctl and sysfs suggests that we don't look
> up these entries sufficiently to require a hash table. We just need a
> data structure that doesn't fall over at scale, and the rbtrees seem to
> do that very nicely.
Ok, I will have a look at it.
Thank you,
Nicolas
^ permalink raw reply
* Re: [RFC PATCH linux 2/2] fs/proc: use a hash table for the directory entries
From: Nicolas Dichtel @ 2014-10-03 13:10 UTC (permalink / raw)
To: Stephen Hemminger
Cc: netdev, linux-kernel, davem, ebiederm, akpm, adobriyan, rui.xiang,
viro, oleg, gorcunov, kirill.shutemov, grant.likely, tytso,
Thierry Herbelot
In-Reply-To: <20141002094657.1e28e027@urahara>
Le 02/10/2014 18:46, Stephen Hemminger a écrit :
> On Thu, 2 Oct 2014 17:25:01 +0200
> Nicolas Dichtel <nicolas.dichtel@6wind.com> wrote:
>
>> From: Thierry Herbelot <thierry.herbelot@6wind.com>
>>
>> The current implementation for the directories in /proc is using a single
>> linked list. This is slow when handling directories with large numbers of
>> entries (eg netdevice-related entries when lots of tunnels are opened).
>>
>> This patch enables multiple linked lists. A hash based on the entry name is
>> used to select the linked list for one given entry.
>>
>> The speed creation of netdevices is faster as shorter linked lists must be
>> scanned when adding a new netdevice.
>>
>> Here are some numbers:
>>
>> dummy30000.batch contains 30 000 times 'link add type dummy'.
>>
>> Before the patch:
>> time ip -b dummy30000.batch
>> real 2m32.221s
>> user 0m0.380s
>> sys 2m30.610s
>>
>> After the patch:
>> time ip -b dummy30000.batch
>> real 1m57.190s
>> user 0m0.350s
>> sys 1m56.120s
>>
>> The single 'subdir' list head is replaced by a subdir hash table. The subdir
>> hash buckets are only allocated for directories. The number of hash buckets
>> is a compile-time parameter.
>>
>> For all functions which handle directory entries, an additional check on the
>> directory nature of the dir entry ensures that pde_hash_buckets was allocated.
>> This check was not needed as subdir was present for all dir entries, whether
>> actual directories or simple files.
>>
>> Signed-off-by: Thierry Herbelot <thierry.herbelot@6wind.com>
>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
>
> I think the speed up is a good idea and makes sense.
> It would be better to use exist hlist macros for hash table rather than
> open coding it.
>
Right, I will rework this after looking at rbtree.
^ permalink raw reply
* [PATCH iproute2] ip address: print stats with -s
From: Jiri Benc @ 2014-10-03 13:25 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Pavel Simerda
Make ip address show accept the -s option similarly to ip link. This creates
an one command replacement for "ifconfig -a" useful for people who still
stay with ifconfig because of this feature.
Print the stats as the last thing for the interface. This requires some code
shuffling.
Signed-off-by: Jiri Benc <jbenc@redhat.com>
---
ip/ipaddress.c | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 245df39179a9..45729d890abd 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -322,7 +322,6 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s,
const struct rtattr *carrier_changes)
{
- fprintf(fp, "%s", _SL_);
fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
s->rx_compressed ? "compressed" : "", _SL_);
fprintf(fp, " %-10"PRIu64" %-8"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64"",
@@ -375,10 +374,9 @@ static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s,
}
}
-static void print_link_stats(FILE *fp, const struct rtnl_link_stats *s,
- const struct rtattr *carrier_changes)
+static void print_link_stats32(FILE *fp, const struct rtnl_link_stats *s,
+ const struct rtattr *carrier_changes)
{
- fprintf(fp, "%s", _SL_);
fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
s->rx_compressed ? "compressed" : "", _SL_);
fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u",
@@ -425,6 +423,27 @@ static void print_link_stats(FILE *fp, const struct rtnl_link_stats *s,
}
}
+static void __print_link_stats(FILE *fp, struct rtattr **tb)
+{
+ if (tb[IFLA_STATS64])
+ print_link_stats64(fp, RTA_DATA(tb[IFLA_STATS64]),
+ tb[IFLA_CARRIER_CHANGES]);
+ else if (tb[IFLA_STATS])
+ print_link_stats32(fp, RTA_DATA(tb[IFLA_STATS]),
+ tb[IFLA_CARRIER_CHANGES]);
+}
+
+static void print_link_stats(FILE *fp, struct nlmsghdr *n)
+{
+ struct ifinfomsg *ifi = NLMSG_DATA(n);
+ struct rtattr * tb[IFLA_MAX+1];
+
+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi),
+ n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)));
+ __print_link_stats(fp, tb);
+ fprintf(fp, "%s", _SL_);
+}
+
int print_linkinfo(const struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
{
@@ -550,12 +569,8 @@ int print_linkinfo(const struct sockaddr_nl *who,
}
if (do_link && show_stats) {
- if (tb[IFLA_STATS64])
- print_link_stats64(fp, RTA_DATA(tb[IFLA_STATS64]),
- tb[IFLA_CARRIER_CHANGES]);
- else if (tb[IFLA_STATS])
- print_link_stats(fp, RTA_DATA(tb[IFLA_STATS]),
- tb[IFLA_CARRIER_CHANGES]);
+ fprintf(fp, "%s", _SL_);
+ __print_link_stats(fp, tb);
}
if (do_link && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
@@ -567,7 +582,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
fprintf(fp, "\n");
fflush(fp);
- return 0;
+ return 1;
}
static int flush_update(void)
@@ -1282,11 +1297,15 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
}
for (l = linfo.head; l; l = l->next) {
- if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) {
+ int res = 0;
+
+ if (no_link || (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
if (filter.family != AF_PACKET)
print_selected_addrinfo(ifi->ifi_index,
ainfo.head, stdout);
+ if (res > 0 && !do_link && show_stats)
+ print_link_stats(stdout, &l->h);
}
}
fflush(stdout);
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH v3 net-next 3/3] bridge: Add filtering support for default_pvid
From: Vlad Yasevich @ 2014-10-03 13:37 UTC (permalink / raw)
To: Cong Wang, Vladislav Yasevich
Cc: Stephen Hemminger, netdev, bridge@lists.linux-foundation.org
In-Reply-To: <CAHA+R7OycteYron5K3YJ3qtsEE-5uUxhPkictJDWosXCihR5hA@mail.gmail.com>
On 10/03/2014 12:41 AM, Cong Wang wrote:
> On Thu, Oct 2, 2014 at 4:54 PM, Vladislav Yasevich <vyasevich@gmail.com> wrote:
>> +static void br_vlan_disable_default_pvid(struct net_bridge *br)
>> +{
>> + struct net_bridge_port *p;
>> + u16 pvid = br->default_pvid;
>> +
>> + /* Disable default_pvid on all ports where it is still
>> + * configured.
>> + */
>> +
>
> This empty line is not necessary.
>
>> + if (vlan_default_pvid(br_get_vlan_info(br), pvid))
>> + br_vlan_delete(br, pvid);
>> +
>> + list_for_each_entry(p, &br->port_list, list) {
>> + if (vlan_default_pvid(nbp_get_vlan_info(p), pvid))
>> + nbp_vlan_delete(p, pvid);
>> + }
>> +
>> + br->default_pvid = 0;
>> +}
>> +
>> +static int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
>> +{
>> + struct net_bridge_port *p;
>> + u16 old_pvid;
>> + int err;
>> + DECLARE_BITMAP(changed, BR_MAX_PORTS);
>
>
> This bitmap will use 128 bytes on stack, why not using heap?
>
I suppose I wanted to avoid yet another memory allocation failure condition.
Is this really going to cause issues?
Thanks
-vlad
>> +
>> + bitmap_zero(changed, BR_MAX_PORTS);
>> +
>> + /* This function runs with filtering turned off so we can
>> + * remove the old pvid configuration and add the new one after
>> + * without impacting traffic.
>> + */
>> +
>> + old_pvid = br->default_pvid;
>
>
> Remove the empty line.
>
> [...]
>
>> +int nbp_vlan_init(struct net_bridge_port *p)
>> +{
>> + int rc = 0;
>> +
>> + if (p->br->default_pvid) {
>> + rc = nbp_vlan_add(p, p->br->default_pvid,
>> + BRIDGE_VLAN_INFO_PVID |
>> + BRIDGE_VLAN_INFO_UNTAGGED);
>> + }
>> +
>> + return rc;
>> +}
>
> 'rc' can be removed.
>
^ 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