* [PATCH] dev: use name hash for dev_seq_ops
From: Mihai Maruseac @ 2011-10-21 6:45 UTC (permalink / raw)
To: davem, shemminger, eric.dumazet
Cc: mirq-linux, therbert, jpirko, netdev, linux-kernel, dbaluta,
Mihai Maruseac
In-Reply-To: <1319097717-14910-1-git-send-email-mmaruseac@ixiacom.com>
Instead of using the dev->next chain and trying to resync at each call to
dev_seq_start, use the name hash, keeping the bucket and the offset in
seq->private field.
Tests revealed the following results for ifconfig > /dev/null
* 1000 interfaces:
* 0.114s without patch
* 0.089s with patch
* 3000 interfaces:
* 0.489s without patch
* 0.110s with patch
* 5000 interfaces:
* 1.363s without patch
* 0.250s with patch
* 128000 interfaces (other setup):
* ~100s without patch
* ~30s with patch
Signed-off-by: Mihai Maruseac <mmaruseac@ixiacom.com>
---
net/core/dev.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 69 insertions(+), 15 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 70ecb86..6edbcc5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4041,6 +4041,60 @@ static int dev_ifconf(struct net *net, char __user *arg)
}
#ifdef CONFIG_PROC_FS
+
+#define BUCKET_SPACE (32 - NETDEV_HASHBITS)
+
+struct dev_iter_state {
+ struct seq_net_private p;
+ unsigned int pos; /* bucket << BUCKET_SPACE + offset */
+};
+
+#define get_bucket(x) ((x) >> BUCKET_SPACE)
+#define get_offset(x) ((x) & ((1 << BUCKET_SPACE) - 1))
+#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
+
+static inline struct net_device *dev_from_same_bucket(struct seq_file *seq)
+{
+ struct dev_iter_state *state = seq->private;
+ struct net *net = seq_file_net(seq);
+ struct net_device *dev;
+ struct hlist_node *p;
+ struct hlist_head *h;
+ unsigned int count, bucket, offset;
+
+ bucket = get_bucket(state->pos);
+ offset = get_offset(state->pos);
+ h = &net->dev_name_head[bucket];
+ count = 0;
+ hlist_for_each_entry_rcu(dev, p, h, name_hlist) {
+ if (count++ == offset) {
+ state->pos = set_bucket_offset(bucket, count);
+ return dev;
+ }
+ }
+
+ return NULL;
+}
+
+static inline struct net_device *dev_from_new_bucket(struct seq_file *seq)
+{
+ struct dev_iter_state *state = seq->private;
+ struct net_device *dev;
+ unsigned int bucket;
+
+ bucket = get_bucket(state->pos);
+ do {
+ dev = dev_from_same_bucket(seq);
+ if (dev)
+ return dev;
+
+ bucket++;
+ state->pos = set_bucket_offset(bucket, 0);
+ } while (bucket < NETDEV_HASHENTRIES);
+
+ return NULL;
+}
+
/*
* This is invoked by the /proc filesystem handler to display a device
* in detail.
@@ -4048,33 +4102,33 @@ static int dev_ifconf(struct net *net, char __user *arg)
void *dev_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(RCU)
{
- struct net *net = seq_file_net(seq);
- loff_t off;
- struct net_device *dev;
+ struct dev_iter_state *state = seq->private;
rcu_read_lock();
if (!*pos)
return SEQ_START_TOKEN;
- off = 1;
- for_each_netdev_rcu(net, dev)
- if (off++ == *pos)
- return dev;
+ /* check for end of the hash */
+ if (state->pos == 0 && *pos > 1)
+ return NULL;
- return NULL;
+ return dev_from_new_bucket(seq);
}
void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct net_device *dev = v;
+ struct net_device *dev;
+
+ ++*pos;
if (v == SEQ_START_TOKEN)
- dev = first_net_device_rcu(seq_file_net(seq));
- else
- dev = next_net_device_rcu(dev);
+ return dev_from_new_bucket(seq);
- ++*pos;
- return dev;
+ dev = dev_from_same_bucket(seq);
+ if (dev)
+ return dev;
+
+ return dev_from_new_bucket(seq);
}
void dev_seq_stop(struct seq_file *seq, void *v)
@@ -4173,7 +4227,7 @@ static const struct seq_operations dev_seq_ops = {
static int dev_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &dev_seq_ops,
- sizeof(struct seq_net_private));
+ sizeof(struct dev_iter_state));
}
static const struct file_operations dev_seq_fops = {
--
1.7.4.1
^ permalink raw reply related
* Re: [PATCH net -v2] [BUGFIX] bonding: use flush_delayed_work_sync in bond_close
From: Jay Vosburgh @ 2011-10-21 6:26 UTC (permalink / raw)
To: =?UTF-8?Q?Am=C3=A9rico_Wang?=
Cc: Stephen Hemminger, Mitsuo Hayasaka, Andy Gospodarek, netdev,
linux-kernel, yrl.pp-manager.tt
In-Reply-To: <CAM_iQpV8089aU8gfeo8KotTNXQbx4ficMeBX69Nin_yXzqcEKg@mail.gmail.com>
Américo Wang <xiyou.wangcong@gmail.com> wrote:
>On Thu, Oct 20, 2011 at 3:09 AM, Jay Vosburgh <fubar@us.ibm.com> wrote:
>> Stephen Hemminger <shemminger@vyatta.com> wrote:
>>
>>>On Wed, 19 Oct 2011 11:01:02 -0700
>>>Jay Vosburgh <fubar@us.ibm.com> wrote:
>>>
>>>> Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com> wrote:
>>>>
>>>> >The bond_close() calls cancel_delayed_work() to cancel delayed works.
>>>> >It, however, cannot cancel works that were already queued in workqueue.
>>>> >The bond_open() initializes work->data, and proccess_one_work() refers
>>>> >get_work_cwq(work)->wq->flags. The get_work_cwq() returns NULL when
>>>> >work->data has been initialized. Thus, a panic occurs.
>>>> >
>>>> >This patch uses flush_delayed_work_sync() instead of cancel_delayed_work()
>>>> >in bond_close(). It cancels delayed timer and waits for work to finish
>>>> >execution. So, it can avoid the null pointer dereference due to the
>>>> >parallel executions of proccess_one_work() and initializing proccess
>>>> >of bond_open().
>>>>
>>>> I'm setting up to test this. I have a dim recollection that we
>>>> tried this some years ago, and there was a different deadlock that
>>>> manifested through the flush path. Perhaps changes since then have
>>>> removed that problem.
>>>>
>>>> -J
>>>
>>>Won't this deadlock on RTNL. The problem is that:
>>>
>>> CPU0 CPU1
>>> rtnl_lock
>>> bond_close
>>> delayed_work
>>> mii_work
>>> read_lock(bond->lock);
>>> read_unlock(bond->lock);
>>> rtnl_lock... waiting for CPU0
>>> flush_delayed_work_sync
>>> waiting for delayed_work to finish...
>>
>> Yah, that was it. We discussed this a couple of years ago in
>> regards to a similar patch:
>>
>> http://lists.openwall.net/netdev/2009/12/17/3
>>
>> The short version is that we could rework the rtnl_lock inside
>> the montiors to be conditional and retry on failure (where "retry" means
>> "reschedule the work and try again later," not "spin retrying on rtnl").
>> That should permit the use of flush or cancel to terminate the work
>> items.
>
>Yes? Even if we use rtnl_trylock(), doesn't flush_delayed_work_sync()
>still queue the pending delayed work and wait for it to be finished?
Yes, it does. The original patch wants to use flush instead of
cancel to wait for the work to finish, because there's evidently a
possibility of getting back into bond_open before the work item
executes, and bond_open would reinitialize the work queue and corrupt
the queued work item.
The original patch series, and recipe for destruction, is here:
http://www.spinics.net/lists/netdev/msg176382.html
I've been unable to reproduce the work queue panic locally,
although it sounds plausible.
Mitsuo: can you provide the precise bonding configuration you're
using to induce the problem? Driver options, number and type of slaves,
etc.
>Maybe I am too blind, why do we need rtnl_lock for cancel_delayed_work()
>inside bond_close()?
We don't need RTNL for cancel/flush. However, bond_close is an
ndo_stop operation, and is called in the dev_close path, which always
occurs under RTNL. The mii / arp monitor work functions separately
acquire RTNL if they need to perform various failover related
operations.
I'm working on a patch that should resolve the mii / arp monitor
RTNL problem as I described above (if rtnl_trylock fails, punt and
reschedule the work). I need to rearrange the netdev_bonding_change
stuff a bit as well, since it acquires RTNL separately.
Once these changes are made to mii / arp monitor, then
bond_close can call flush instead of cancel, which should eliminate the
original problem described at the top.
-J
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
^ permalink raw reply
* Re: [PATCH net -v2] [BUGFIX] bonding: use flush_delayed_work_sync in bond_close
From: Américo Wang @ 2011-10-21 5:45 UTC (permalink / raw)
To: Jay Vosburgh
Cc: Stephen Hemminger, Mitsuo Hayasaka, Andy Gospodarek, netdev,
linux-kernel, yrl.pp-manager.tt
In-Reply-To: <29731.1319051397@death>
On Thu, Oct 20, 2011 at 3:09 AM, Jay Vosburgh <fubar@us.ibm.com> wrote:
> Stephen Hemminger <shemminger@vyatta.com> wrote:
>
>>On Wed, 19 Oct 2011 11:01:02 -0700
>>Jay Vosburgh <fubar@us.ibm.com> wrote:
>>
>>> Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com> wrote:
>>>
>>> >The bond_close() calls cancel_delayed_work() to cancel delayed works.
>>> >It, however, cannot cancel works that were already queued in workqueue.
>>> >The bond_open() initializes work->data, and proccess_one_work() refers
>>> >get_work_cwq(work)->wq->flags. The get_work_cwq() returns NULL when
>>> >work->data has been initialized. Thus, a panic occurs.
>>> >
>>> >This patch uses flush_delayed_work_sync() instead of cancel_delayed_work()
>>> >in bond_close(). It cancels delayed timer and waits for work to finish
>>> >execution. So, it can avoid the null pointer dereference due to the
>>> >parallel executions of proccess_one_work() and initializing proccess
>>> >of bond_open().
>>>
>>> I'm setting up to test this. I have a dim recollection that we
>>> tried this some years ago, and there was a different deadlock that
>>> manifested through the flush path. Perhaps changes since then have
>>> removed that problem.
>>>
>>> -J
>>
>>Won't this deadlock on RTNL. The problem is that:
>>
>> CPU0 CPU1
>> rtnl_lock
>> bond_close
>> delayed_work
>> mii_work
>> read_lock(bond->lock);
>> read_unlock(bond->lock);
>> rtnl_lock... waiting for CPU0
>> flush_delayed_work_sync
>> waiting for delayed_work to finish...
>
> Yah, that was it. We discussed this a couple of years ago in
> regards to a similar patch:
>
> http://lists.openwall.net/netdev/2009/12/17/3
>
> The short version is that we could rework the rtnl_lock inside
> the montiors to be conditional and retry on failure (where "retry" means
> "reschedule the work and try again later," not "spin retrying on rtnl").
> That should permit the use of flush or cancel to terminate the work
> items.
Yes? Even if we use rtnl_trylock(), doesn't flush_delayed_work_sync()
still queue the pending delayed work and wait for it to be finished?
Maybe I am too blind, why do we need rtnl_lock for cancel_delayed_work()
inside bond_close()?
Thanks.
^ permalink raw reply
* Re: [RFC PATCH 05/17] phy_driver: Make .read_status()/.config_aneg() optional
From: Kyle Moffett @ 2011-10-21 5:13 UTC (permalink / raw)
To: Mike Frysinger
Cc: Kyle Moffett, linux-kernel, netdev, Randy Dunlap,
Stephen Hemminger, David S. Miller, Greg Dietsche,
Giuseppe Cavallaro, David Daney, Arnaud Patard, Grant Likely,
Baruch Siach, Thorsten Schubert, David Decotigny, Andrew Morton,
Lucas De Marchi, Marc Kleine-Budde, linux-doc
In-Reply-To: <201110201714.36533.vapier@gentoo.org>
Oops, I just realized that I may have misused
scripts/get_maintainer.pl... it seems to have added about 20 CCs to
this email, sorry!
On Thu, Oct 20, 2011 at 17:14, Mike Frysinger <vapier@gentoo.org> wrote:
> On Thursday 20 October 2011 17:10:12 Mike Frysinger wrote:
>> On Thursday 20 October 2011 17:00:12 Kyle Moffett wrote:
>> > Approximately 90% of the PHY drivers follow the PHY layer docs and
>> > simply use &genphy_read_status and &genphy_config_aneg. There would
>> > seem to be little point in requiring them all to manually specify those
>> > functions.
>>
>> well, it does make sense if you think about the compile vs build time
>> overhead. yes, your patch does make things much nicer to read, and a
>> little easier to maintain the source. however, it adds runtime overhead
>> (checking the func pointers) while the func pointer storage is unchanged
>> (it's now a NULL pointer instead of pointing to the genphy funcs).
>> personally, i think the savings in runtime and smaller compiled code is
>> more important. so i'm going to NAK this. sorry.
>
> ah, sorry, i was thinking this was u-boot since we were just having
> conversations there.
>
> since this is Linux, and i don't have real standing in the general netdev
> community, i can't really NAK here. but i think my comment still stands in
> that this patch makes things much worse than the minor code style improvement.
I would argue that the PHY layer itself is not remotely a hot-path,
especially not to the level of caring about an extra if statement. A
single phy_read() is a sleeping call which goes over a slow serial
bus, so code maintainability is much more important.
At the higher level, the reason for this change is that currently
genphy_config_aneg() is currently responsible both for configuring
auto-negotiation *AND* counterintuitively for configuring forced-mode
links. A lot of PHY drivers need to override just one or the other,
which results in either a lot of copy-pasted code in individual PHY
drivers or in a duplicate test for autoneg-vs-fixed-mode before
calling the primary genphy_config_aneg() function.
In order to split that up and refactor it, I would like to minimize
the number of callers and references to config_aneg() to minimize the
number of places that have to be changed to match. Since all the rest
of the PHY functions are already conditionals, making these two also
conditional didn't seem to be a big deal.
Cheers,
Kyle Moffett
--
Curious about my work on the Debian powerpcspe port?
I'm keeping a blog here: http://pureperl.blogspot.com/
^ permalink raw reply
* Re: [PATCH] net: ipv6: Allow netlink to set IPv6 address scope
From: Maciej Żenczykowski @ 2011-10-21 4:25 UTC (permalink / raw)
To: Brian Haley; +Cc: Lorenzo Colitti, yoshfuji, netdev
In-Reply-To: <4E9C9ED6.9080601@hp.com>
>> RFC 3879 deprecated site-local addresses because the were non-unique and thus
>> ambiguous, and if they leak, they cause problems. This is not an issue
>> in the use
>> case I presented, because the addresses are syntactically global
>> addresses - they
>> just don't have global reachability.
>
> Not very global then :(
They're globally unique.
Global does not imply being able to reach the internet, or being able
to be reached from the internet.
Whatever the RFC's say, that's just a sad fact of life.
>> I don't think it's a good idea. Waiting for an IETF working group to
>> produce a standard
>> when it doesn't even have a problem statement finalized could take years.
>
> It would be useful to give some input there, even if the Linux-specific
> implementation of any standard plays with bits in the ifaddr.
I'm afraid this is a real problem _right_ now, a solution is required
and we can't really afford to wait a year while working groups work
out a bugfix.
> In my opinion it just feels like a hack, because things won't work when your
> wifi attaches to a walled garden, or there's a third interface - who wins the
> tiebreaker?
I would tend to agree that this is a little hacky... but, ultimately,
I always claim that policy should belong in userspace - not in the
kernel.
If userspace administrator wants to shoot himself, he can do that in
plenty of ways already.
> I do see your point that it will help with the problem you're trying to solve,
> hopefully someone else will offer their opinion.
I'm a little biased here, but I'd prefer my cellphone to just work ;-)
- Maciej
^ permalink raw reply
* Questions about CHECKSUM_COMPLETE
From: fengcheng lu @ 2011-10-21 3:05 UTC (permalink / raw)
To: netdev
Hello everyone
I have one question about the CHECKSUM_COMPLETE. When
CHECK_SUM_COMPLETE is set, which data does the skb->csum computed by
hardware cover?
I thought skb->csum only covers the Transport header (e.g. TCP/UDP) +
Transport payload + pseudo header. However, after I read the vlan
codes (vlan_skb_recv in the vlan_dev.c of linux kernel 2.6.27.19), I
become confuse.
The vlan_skb_recv calls skb_pull_rcsum which updates the skb->csum if
CHECKSUM_COMPLETE is set. It implies the vlan header is also covered
by the skb->csum. so I wonder if the skb->csum cover the whole data
besides the eth header (14 bytes).
Thanks
Steven Lu
^ permalink raw reply
* Re: [patch net-next]alx: Atheros AR8131/AR8151/AR8152/AR8161 Ethernet driver
From: Luis R. Rodriguez @ 2011-10-21 2:36 UTC (permalink / raw)
To: Ren, Cloud, Xiong Huang
Cc: David Miller, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <6349D7A510622448B1BA0967850A8438011CC7CA@nasanexd02d.na.qualcomm.com>
On Thu, Oct 20, 2011 at 7:21 PM, Ren, Cloud <cjren@qca.qualcomm.com> wrote:
>>On Thu, Oct 20, 2011 at 2:48 AM, Ren, Cloud <cjren@qca.qualcomm.com>
>>wrote:
>>>
>>>>From: "Ren, Cloud" <cjren@qca.qualcomm.com>
>>>>Date: Thu, 20 Oct 2011 09:23:07 +0000
>>>>
>>>>> As you saw, should I do the two following steps?
>>>>> 1. I firstly try to submit code to linux-staging.git.
>>>>> 2. After the driver have been accepted by linux-staging.git, I
>>>>> submit to net-
>>>>next.git again.
>>>>
>>>>You submit and get it into staging so that it can sit there for some
>>>>time and get reviewed and improved by others.
>>>>
>>>>One doesn't submit directly to net-next right after it gets into
>>>>staging, staging is a place where your driver lives while it still
>>>>smelly funky and needs more work.
>>>
>>> The driver will support the next generation NICs of Atheros.
>>> Meanwhile, the driver can also have better optimization for AR8131 and
>>> AR8151 than atl1c. For some reason, we don't plan to patch atl1c
>>> driver to support our new NIC, such as AR8161. So I hope the driver
>>> can stay in net-next in the end. Of course, I will be responsible for modify
>>source code and let it match kernel requirements.
>>
>>Cloud,
>>
>>If you want to skip staging (which I recommend) then you need to address all
>>upstream concerns expressed. Given that you indicate that you will be
>>working on following up with the driver until its acceptable upstream my
>>recommendation is either to clean up the driver very well and review it
>>internally at Atheros prior to a public submission *or* just dump into staging
>>and get the benefit of community cleanup and eventually wait until it is ready
>>for proper upstream. If you want internal private review at Atheros you can
>>use the internal private ath9k-devel list.
>>
>>Also are you going to maintain the older atlx drivers? While at it can you clear
>>up who maintains what as far as Atheros is concerned for Ethernet?
>>
>> Luis
>
> Dear Luis
>
> Thanks for your suggestions. I would rather do an internal review than only submit to staging.
> Alx driver is one of the most important drivers for Atheros Ethernet. It's easier to maintain.
> Because it shares many codes with other drivers on different OSs, it can be convenient to patch
> some issues which are found on different OSs.
>
> I'm going to maintain alx linux driver. alx linux driver can support all NICs which atl1c linux driver supports.
> So we don't plan to maintain atl1c driver. atl1e and atlx driver are also maintained by me. But maybe I can
> not response requests for those drivers on time, because sometimes I am busy at alx driver.
Are there issues with the atl1x driver that are fixed in the alx
driver? How many ? Do we expect to find many more ? If there isn't
much churn then why not let atl1x rot to death while atx can move
without atl1x support at all upstream?
A driver replacement for atl1x seems fair only if you can ensure there
will be no regressions Vs the atx driver code. I'd much prefer an atx
driver that *is* actively maintained by Atheros than only Gigabit
support for atx, and an orphaned atl1x driver but if we don't expect
much changes to go for atl1x what is the point?
Luis
^ permalink raw reply
* RE: [patch net-next]alx: Atheros AR8131/AR8151/AR8152/AR8161 Ethernet driver
From: Ren, Cloud @ 2011-10-21 2:21 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: David Miller, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <CAB=NE6W6Gc+dN3SzX00VwO9iheemNzhRQ34KuvMtZsBqVJQhJQ@mail.gmail.com>
>On Thu, Oct 20, 2011 at 2:48 AM, Ren, Cloud <cjren@qca.qualcomm.com>
>wrote:
>>
>>>From: "Ren, Cloud" <cjren@qca.qualcomm.com>
>>>Date: Thu, 20 Oct 2011 09:23:07 +0000
>>>
>>>> As you saw, should I do the two following steps?
>>>> 1. I firstly try to submit code to linux-staging.git.
>>>> 2. After the driver have been accepted by linux-staging.git, I
>>>> submit to net-
>>>next.git again.
>>>
>>>You submit and get it into staging so that it can sit there for some
>>>time and get reviewed and improved by others.
>>>
>>>One doesn't submit directly to net-next right after it gets into
>>>staging, staging is a place where your driver lives while it still
>>>smelly funky and needs more work.
>>
>> The driver will support the next generation NICs of Atheros.
>> Meanwhile, the driver can also have better optimization for AR8131 and
>> AR8151 than atl1c. For some reason, we don't plan to patch atl1c
>> driver to support our new NIC, such as AR8161. So I hope the driver
>> can stay in net-next in the end. Of course, I will be responsible for modify
>source code and let it match kernel requirements.
>
>Cloud,
>
>If you want to skip staging (which I recommend) then you need to address all
>upstream concerns expressed. Given that you indicate that you will be
>working on following up with the driver until its acceptable upstream my
>recommendation is either to clean up the driver very well and review it
>internally at Atheros prior to a public submission *or* just dump into staging
>and get the benefit of community cleanup and eventually wait until it is ready
>for proper upstream. If you want internal private review at Atheros you can
>use the internal private ath9k-devel list.
>
>Also are you going to maintain the older atlx drivers? While at it can you clear
>up who maintains what as far as Atheros is concerned for Ethernet?
>
> Luis
Dear Luis
Thanks for your suggestions. I would rather do an internal review than only submit to staging.
Alx driver is one of the most important drivers for Atheros Ethernet. It's easier to maintain.
Because it shares many codes with other drivers on different OSs, it can be convenient to patch
some issues which are found on different OSs.
I'm going to maintain alx linux driver. alx linux driver can support all NICs which atl1c linux driver supports.
So we don't plan to maintain atl1c driver. atl1e and atlx driver are also maintained by me. But maybe I can
not response requests for those drivers on time, because sometimes I am busy at alx driver.
cloud
^ permalink raw reply
* [PATCH 2/2] ipvs: Fix compilation error in ip_vs.h for ip_vs_confirm_conntrack function.
From: Simon Horman @ 2011-10-21 1:33 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: lvs-devel, netdev, netfilter-devel, Wensong Zhang,
Julian Anastasov, Krzysztof Wilczynski, Simon Horman
In-Reply-To: <1319160783-28422-1-git-send-email-horms@verge.net.au>
From: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>
This is to address the following error during the compilation:
In file included from kernel/sysctl_binary.c:6:
include/net/ip_vs.h:1406: error: expected identifier or ‘(’ before ‘{’ token
make[1]: *** [kernel/sysctl_binary.o] Error 1
make[1]: *** Waiting for unfinished jobs....
That manifests itself when CONFIG_IP_VS_NFCT is undefined in .config file.
Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
include/net/ip_vs.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 139784e..de527d1 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -1395,7 +1395,7 @@ static inline void ip_vs_update_conntrack(struct sk_buff *skb,
{
}
-static inline int ip_vs_confirm_conntrack(struct sk_buff *skb);
+static inline int ip_vs_confirm_conntrack(struct sk_buff *skb)
{
return NF_ACCEPT;
}
--
1.7.6.3
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" 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 related
* [PATCH 1/2] ipvs: Remove unused variable "cs" from ip_vs_leave function.
From: Simon Horman @ 2011-10-21 1:33 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: lvs-devel, netdev, netfilter-devel, Wensong Zhang,
Julian Anastasov, Krzysztof Wilczynski, Simon Horman
In-Reply-To: <1319160783-28422-1-git-send-email-horms@verge.net.au>
From: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>
This is to address the following warning during compilation time:
net/netfilter/ipvs/ip_vs_core.c: In function ‘ip_vs_leave’:
net/netfilter/ipvs/ip_vs_core.c:532: warning: unused variable ‘cs’
This variable is indeed no longer in use.
Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
net/netfilter/ipvs/ip_vs_core.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 46a8130..093cc32 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -529,7 +529,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
a cache_bypass connection entry */
ipvs = net_ipvs(net);
if (ipvs->sysctl_cache_bypass && svc->fwmark && unicast) {
- int ret, cs;
+ int ret;
struct ip_vs_conn *cp;
unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET &&
iph.protocol == IPPROTO_UDP)?
--
1.7.6.3
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" 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 related
* [GIT PULL nf-next] IPVS
From: Simon Horman @ 2011-10-21 1:33 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: lvs-devel, netdev, netfilter-devel, Wensong Zhang,
Julian Anastasov, Krzysztof Wilczynski
Hi Pablo,
please consider pulling the following to get compile fix
and cleanup patches from Krzysztof Wilczynski.
The following changes since commit 2ca5b853f1dd81c605ddc8a55e06bdad85636597:
netfilter: export NAT definitions through linux/netfilter_ipv4/nf_nat.h (2011-10-11 03:32:34 +0200)
are available in the git repository at:
git://github.com/horms/ipvs-next.git master
Krzysztof Wilczynski (2):
ipvs: Remove unused variable "cs" from ip_vs_leave function.
ipvs: Fix compilation error in ip_vs.h for ip_vs_confirm_conntrack function.
include/net/ip_vs.h | 2 +-
net/netfilter/ipvs/ip_vs_core.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
^ permalink raw reply
* Re: [PATCH] ipvs: Fix compilation error in ip_vs.h for ip_vs_confirm_conntrack function.
From: Simon Horman @ 2011-10-21 1:25 UTC (permalink / raw)
To: Krzysztof Wilczynski; +Cc: Patrick McHardy, netdev
In-Reply-To: <1319113084-7498-1-git-send-email-krzysztof.wilczynski@linux.com>
On Thu, Oct 20, 2011 at 01:18:04PM +0100, Krzysztof Wilczynski wrote:
> This is to address the following error during the compilation:
>
> In file included from kernel/sysctl_binary.c:6:
> include/net/ip_vs.h:1406: error: expected identifier or ‘(’ before ‘{’ token
> make[1]: *** [kernel/sysctl_binary.o] Error 1
> make[1]: *** Waiting for unfinished jobs....
>
> That manifests itself when CONFIG_IP_VS_NFCT is undefined in .config file.
>
> Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>
> ---
> include/net/ip_vs.h | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
> index 139784e..de527d1 100644
> --- a/include/net/ip_vs.h
> +++ b/include/net/ip_vs.h
> @@ -1395,7 +1395,7 @@ static inline void ip_vs_update_conntrack(struct sk_buff *skb,
> {
> }
>
> -static inline int ip_vs_confirm_conntrack(struct sk_buff *skb);
> +static inline int ip_vs_confirm_conntrack(struct sk_buff *skb)
> {
> return NF_ACCEPT;
> }
Thanks Krzysztof,
that fixes a brown paper bag effort from me.
^ permalink raw reply
* Re: [RFC PATCH 15/17] phy_device: Add "port" and "transciever" fields
From: Ben Hutchings @ 2011-10-20 23:27 UTC (permalink / raw)
To: Kyle Moffett
Cc: linux-kernel, netdev, David S. Miller, David Decotigny,
Stephen Hemminger, Andrew Morton, Lucas De Marchi,
Marc Kleine-Budde, Mike Frysinger
In-Reply-To: <1319144425-15547-16-git-send-email-Kyle.D.Moffett@boeing.com>
On Thu, 2011-10-20 at 17:00 -0400, Kyle Moffett wrote:
> Some PHYs have multiple software-selectable inputs and outputs,
> including RGMII, SGMII, SerDes, etc. New fields are added to the
> "struct phy_device" for "port" and "transciever" to allow "ethtool" to
> switch outputs at runtime. The defaults for the new fields are
> identical to the hardcoded values used previously.
>
> This should make no functional changes to the PHY layer behavior, but
> it will allow later PHY/ethernet drivers to override those fields.
>
> Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
> ---
> drivers/net/phy/phy.c | 4 ++--
> drivers/net/phy/phy_device.c | 2 ++
> include/linux/phy.h | 4 ++++
> 3 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index c378f91..5f72055 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -290,9 +290,9 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
>
> ethtool_cmd_speed_set(cmd, phydev->speed);
> cmd->duplex = phydev->duplex;
> - cmd->port = PORT_MII;
> + cmd->port = phydev->port;
> cmd->phy_address = phydev->addr;
> - cmd->transceiver = XCVR_EXTERNAL;
> + cmd->transceiver = phydev->transciever;
'transceiver' is spelt thus.
[...]
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -308,6 +308,10 @@ struct phy_device {
> u32 supported;
> u32 advertising;
>
> + /* The current port/xcvr info (Copper, Fibre, MII, Direct-Attach) */
> + u8 port;
> + u8 transceiver;
> +
And yet you got it right here.
Ben.
> int autoneg;
>
> int link_timeout;
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH] net: allow CAP_NET_RAW to set socket options IP{,V6}_TRANSPARENT
From: David Miller @ 2011-10-20 22:22 UTC (permalink / raw)
To: zenczykowski; +Cc: maze, netdev
In-Reply-To: <1319148614-6739-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <zenczykowski@gmail.com>
Date: Thu, 20 Oct 2011 15:10:14 -0700
> From: Maciej Żenczykowski <maze@google.com>
>
> Up till now the IP{,V6}_TRANSPARENT socket options (which actually set
> the same bit in the socket struct) have required CAP_NET_ADMIN
> privileges to set or clear the option.
>
> - we make clearing the bit not require any privileges.
> - we allow CAP_NET_ADMIN to set the bit (as before this change)
> - we allow CAP_NET_RAW to set this bit, because raw
> sockets already pretty much effectively allow you
> to emulate socket transparency.
>
> Signed-off-by: Maciej Żenczykowski <maze@google.com>
Applied, thanks.
^ permalink raw reply
* [PATCH] net: allow CAP_NET_RAW to set socket options IP{,V6}_TRANSPARENT
From: Maciej Żenczykowski @ 2011-10-20 22:10 UTC (permalink / raw)
To: Maciej Żenczykowski; +Cc: David Miller, netdev, Maciej Żenczykowski
In-Reply-To: <20111020.003458.1034042223691970343.davem@davemloft.net>
From: Maciej Żenczykowski <maze@google.com>
Up till now the IP{,V6}_TRANSPARENT socket options (which actually set
the same bit in the socket struct) have required CAP_NET_ADMIN
privileges to set or clear the option.
- we make clearing the bit not require any privileges.
- we allow CAP_NET_ADMIN to set the bit (as before this change)
- we allow CAP_NET_RAW to set this bit, because raw
sockets already pretty much effectively allow you
to emulate socket transparency.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
include/linux/capability.h | 3 ++-
net/ipv4/ip_sockglue.c | 2 +-
net/ipv6/ipv6_sockglue.c | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/include/linux/capability.h b/include/linux/capability.h
index c421123..a63d13d 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -198,7 +198,7 @@ struct cpu_vfs_cap_data {
/* Allow modification of routing tables */
/* Allow setting arbitrary process / process group ownership on
sockets */
-/* Allow binding to any address for transparent proxying */
+/* Allow binding to any address for transparent proxying (also via NET_RAW) */
/* Allow setting TOS (type of service) */
/* Allow setting promiscuous mode */
/* Allow clearing driver statistics */
@@ -210,6 +210,7 @@ struct cpu_vfs_cap_data {
/* Allow use of RAW sockets */
/* Allow use of PACKET sockets */
+/* Allow binding to any address for transparent proxying (also via NET_ADMIN) */
#define CAP_NET_RAW 13
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 8905e92..f0dc3ad 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -961,7 +961,7 @@ mc_msf_out:
break;
case IP_TRANSPARENT:
- if (!capable(CAP_NET_ADMIN)) {
+ if (!!val && !capable(CAP_NET_RAW) && !capable(CAP_NET_ADMIN)) {
err = -EPERM;
break;
}
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 2fbda5f..c99e3ee 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -343,7 +343,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
break;
case IPV6_TRANSPARENT:
- if (!capable(CAP_NET_ADMIN)) {
+ if (valbool && !capable(CAP_NET_ADMIN) && !capable(CAP_NET_RAW)) {
retv = -EPERM;
break;
}
--
1.7.3.1
^ permalink raw reply related
* Re: [PATCH] net: Fix driver name for mdio-gpio.c
From: David Miller @ 2011-10-20 21:48 UTC (permalink / raw)
To: eibach; +Cc: linux-kernel, netdev, grant.likely
In-Reply-To: <1318943051-22432-1-git-send-email-eibach@gdsys.de>
From: Dirk Eibach <eibach@gdsys.de>
Date: Tue, 18 Oct 2011 15:04:11 +0200
> Since commit
> "7488876... dt/net: Eliminate users of of_platform_{,un}register_driver"
> there are two platform drivers named "mdio-gpio" registered.
> I renamed the of variant to "mdio-ofgpio".
>
> Signed-off-by: Dirk Eibach <eibach@gdsys.de>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next] net: constify skbuff and Qdisc elements
From: David Miller @ 2011-10-20 21:46 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1319146917.2854.46.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 20 Oct 2011 23:41:57 +0200
> Preliminary patch before tcp constification
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied, thanks Eric.
^ permalink raw reply
* Re: [PATCH net-next] tcp: remove unused tcp_fin() parameters
From: David Miller @ 2011-10-20 21:44 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1319145084.2854.42.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 20 Oct 2011 23:11:24 +0200
> tcp_fin() only needs socket pointer, we can remove skb and th params.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied, thanks Eric.
^ permalink raw reply
* Re: [PATCH net-next] myri10ge: fix truesize underestimation
From: David Miller @ 2011-10-20 21:42 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, mason
In-Reply-To: <1319141403.2854.17.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 20 Oct 2011 22:10:03 +0200
> skb->truesize must account for allocated memory, not the used part of
> it. Doing this work is important to avoid unexpected OOM situations.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] igbvf: fix truesize underestimation
From: David Miller @ 2011-10-20 21:42 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, jeffrey.t.kirsher
In-Reply-To: <1319138538.2854.9.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 20 Oct 2011 21:22:18 +0200
> igbvf allocates half a page per skb fragment. We must account
> PAGE_SIZE/2 increments on skb->truesize, not the actual frag length.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Applied.
^ permalink raw reply
* Re: pull request: batman-adv 2011-10-18 (more regression fixes)
From: David Miller @ 2011-10-20 21:42 UTC (permalink / raw)
To: lindner_marek-LWAfsSFWpa4
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
In-Reply-To: <1318971669-941-1-git-send-email-lindner_marek-LWAfsSFWpa4@public.gmane.org>
From: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
Date: Tue, 18 Oct 2011 23:01:07 +0200
> we have identified and fixed 2 more critical bugs in the linux-3.1
> code base. We are somewhat late in the 3.1 release cycle but hoped
> to take advantage of the delayed release to get these patches
> included before the final version is out.
Pulled, thanks Marek.
^ permalink raw reply
* [PATCH net-next] net: constify skbuff and Qdisc elements
From: Eric Dumazet @ 2011-10-20 21:41 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Preliminary patch before tcp constification
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
include/linux/skbuff.h | 17 +++++++++--------
include/net/sch_generic.h | 24 ++++++++++++------------
2 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 1ebf1ea..3411f22 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -853,9 +853,9 @@ static inline struct sk_buff *skb_unshare(struct sk_buff *skb,
* The reference count is not incremented and the reference is therefore
* volatile. Use with caution.
*/
-static inline struct sk_buff *skb_peek(struct sk_buff_head *list_)
+static inline struct sk_buff *skb_peek(const struct sk_buff_head *list_)
{
- struct sk_buff *list = ((struct sk_buff *)list_)->next;
+ struct sk_buff *list = ((const struct sk_buff *)list_)->next;
if (list == (struct sk_buff *)list_)
list = NULL;
return list;
@@ -874,9 +874,9 @@ static inline struct sk_buff *skb_peek(struct sk_buff_head *list_)
* The reference count is not incremented and the reference is therefore
* volatile. Use with caution.
*/
-static inline struct sk_buff *skb_peek_tail(struct sk_buff_head *list_)
+static inline struct sk_buff *skb_peek_tail(const struct sk_buff_head *list_)
{
- struct sk_buff *list = ((struct sk_buff *)list_)->prev;
+ struct sk_buff *list = ((const struct sk_buff *)list_)->prev;
if (list == (struct sk_buff *)list_)
list = NULL;
return list;
@@ -1830,7 +1830,7 @@ static inline dma_addr_t skb_frag_dma_map(struct device *dev,
* Returns true if modifying the header part of the cloned buffer
* does not requires the data to be copied.
*/
-static inline int skb_clone_writable(struct sk_buff *skb, unsigned int len)
+static inline int skb_clone_writable(const struct sk_buff *skb, unsigned int len)
{
return !skb_header_cloned(skb) &&
skb_headroom(skb) + len <= skb->hdr_len;
@@ -2451,7 +2451,8 @@ static inline bool skb_warn_if_lro(const struct sk_buff *skb)
{
/* LRO sets gso_size but not gso_type, whereas if GSO is really
* wanted then gso_type will be set. */
- struct skb_shared_info *shinfo = skb_shinfo(skb);
+ const struct skb_shared_info *shinfo = skb_shinfo(skb);
+
if (skb_is_nonlinear(skb) && shinfo->gso_size != 0 &&
unlikely(shinfo->gso_type == 0)) {
__skb_warn_lro_forwarding(skb);
@@ -2475,7 +2476,7 @@ static inline void skb_forward_csum(struct sk_buff *skb)
* Instead of forcing ip_summed to CHECKSUM_NONE, we can
* use this helper, to document places where we make this assertion.
*/
-static inline void skb_checksum_none_assert(struct sk_buff *skb)
+static inline void skb_checksum_none_assert(const struct sk_buff *skb)
{
#ifdef DEBUG
BUG_ON(skb->ip_summed != CHECKSUM_NONE);
@@ -2484,7 +2485,7 @@ static inline void skb_checksum_none_assert(struct sk_buff *skb)
bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off);
-static inline bool skb_is_recycleable(struct sk_buff *skb, int skb_size)
+static inline bool skb_is_recycleable(const struct sk_buff *skb, int skb_size)
{
if (irqs_disabled())
return false;
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 4fc88f3..2eb207e 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -46,14 +46,14 @@ struct qdisc_size_table {
struct Qdisc {
int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
struct sk_buff * (*dequeue)(struct Qdisc *dev);
- unsigned flags;
+ unsigned int flags;
#define TCQ_F_BUILTIN 1
#define TCQ_F_INGRESS 2
#define TCQ_F_CAN_BYPASS 4
#define TCQ_F_MQROOT 8
#define TCQ_F_WARN_NONWC (1 << 16)
int padded;
- struct Qdisc_ops *ops;
+ const struct Qdisc_ops *ops;
struct qdisc_size_table __rcu *stab;
struct list_head list;
u32 handle;
@@ -224,7 +224,7 @@ struct qdisc_skb_cb {
long data[];
};
-static inline int qdisc_qlen(struct Qdisc *q)
+static inline int qdisc_qlen(const struct Qdisc *q)
{
return q->q.qlen;
}
@@ -239,12 +239,12 @@ static inline spinlock_t *qdisc_lock(struct Qdisc *qdisc)
return &qdisc->q.lock;
}
-static inline struct Qdisc *qdisc_root(struct Qdisc *qdisc)
+static inline struct Qdisc *qdisc_root(const struct Qdisc *qdisc)
{
return qdisc->dev_queue->qdisc;
}
-static inline struct Qdisc *qdisc_root_sleeping(struct Qdisc *qdisc)
+static inline struct Qdisc *qdisc_root_sleeping(const struct Qdisc *qdisc)
{
return qdisc->dev_queue->qdisc_sleeping;
}
@@ -260,7 +260,7 @@ static inline struct Qdisc *qdisc_root_sleeping(struct Qdisc *qdisc)
* root. This is enforced by holding the RTNL semaphore, which
* all users of this lock accessor must do.
*/
-static inline spinlock_t *qdisc_root_lock(struct Qdisc *qdisc)
+static inline spinlock_t *qdisc_root_lock(const struct Qdisc *qdisc)
{
struct Qdisc *root = qdisc_root(qdisc);
@@ -268,7 +268,7 @@ static inline spinlock_t *qdisc_root_lock(struct Qdisc *qdisc)
return qdisc_lock(root);
}
-static inline spinlock_t *qdisc_root_sleeping_lock(struct Qdisc *qdisc)
+static inline spinlock_t *qdisc_root_sleeping_lock(const struct Qdisc *qdisc)
{
struct Qdisc *root = qdisc_root_sleeping(qdisc);
@@ -276,17 +276,17 @@ static inline spinlock_t *qdisc_root_sleeping_lock(struct Qdisc *qdisc)
return qdisc_lock(root);
}
-static inline struct net_device *qdisc_dev(struct Qdisc *qdisc)
+static inline struct net_device *qdisc_dev(const struct Qdisc *qdisc)
{
return qdisc->dev_queue->dev;
}
-static inline void sch_tree_lock(struct Qdisc *q)
+static inline void sch_tree_lock(const struct Qdisc *q)
{
spin_lock_bh(qdisc_root_sleeping_lock(q));
}
-static inline void sch_tree_unlock(struct Qdisc *q)
+static inline void sch_tree_unlock(const struct Qdisc *q)
{
spin_unlock_bh(qdisc_root_sleeping_lock(q));
}
@@ -319,7 +319,7 @@ static inline unsigned int qdisc_class_hash(u32 id, u32 mask)
}
static inline struct Qdisc_class_common *
-qdisc_class_find(struct Qdisc_class_hash *hash, u32 id)
+qdisc_class_find(const struct Qdisc_class_hash *hash, u32 id)
{
struct Qdisc_class_common *cl;
struct hlist_node *n;
@@ -393,7 +393,7 @@ static inline bool qdisc_all_tx_empty(const struct net_device *dev)
}
/* Are any of the TX qdiscs changing? */
-static inline bool qdisc_tx_changing(struct net_device *dev)
+static inline bool qdisc_tx_changing(const struct net_device *dev)
{
unsigned int i;
for (i = 0; i < dev->num_tx_queues; i++) {
^ permalink raw reply related
* Re: [RFC PATCH 06/17] phy_driver: Add and use phy_driver_[un]register_multiple()
From: Mike Frysinger @ 2011-10-20 21:15 UTC (permalink / raw)
To: Kyle Moffett
Cc: linux-kernel, netdev, David S. Miller, Greg Dietsche,
Giuseppe Cavallaro, David Daney, Arnaud Patard, Grant Likely,
Baruch Siach, Stephen Hemminger, Lucas De Marchi,
Marc Kleine-Budde, Andrew Morton
In-Reply-To: <1319144425-15547-7-git-send-email-Kyle.D.Moffett@boeing.com>
[-- Attachment #1: Type: Text/Plain, Size: 390 bytes --]
On Thursday 20 October 2011 17:00:13 Kyle Moffett wrote:
> + return phy_driver_register_multiple(bcm63xx_drivers,
> + ARRAY_SIZE(bcm63xx_drivers));
if only the arm ARRAY_AND_SIZE() macro could gain traction in the wider tree:
return phy_driver_register_multiple(ARRAY_AND_SIZE(bcm63xx_drivers));
ignoring that, this patch looks cool
Acked-by: Mike Frysinger <vapier@gentoo.org>
-mike
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [RFC PATCH 05/17] phy_driver: Make .read_status()/.config_aneg() optional
From: Mike Frysinger @ 2011-10-20 21:14 UTC (permalink / raw)
To: Kyle Moffett
Cc: linux-kernel, netdev, Randy Dunlap, Stephen Hemminger,
David S. Miller, Greg Dietsche, Giuseppe Cavallaro, David Daney,
Arnaud Patard, Grant Likely, Baruch Siach, Thorsten Schubert,
David Decotigny, Andrew Morton, Lucas De Marchi,
Marc Kleine-Budde, linux-doc
In-Reply-To: <201110201710.17519.vapier@gentoo.org>
[-- Attachment #1: Type: Text/Plain, Size: 1601 bytes --]
On Thursday 20 October 2011 17:10:12 Mike Frysinger wrote:
> On Thursday 20 October 2011 17:00:12 Kyle Moffett wrote:
> > Approximately 90% of the PHY drivers follow the PHY layer docs and
> > simply use &genphy_read_status and &genphy_config_aneg. There would
> > seem to be little point in requiring them all to manually specify those
> > functions.
>
> well, it does make sense if you think about the compile vs build time
> overhead. yes, your patch does make things much nicer to read, and a
> little easier to maintain the source. however, it adds runtime overhead
> (checking the func pointers) while the func pointer storage is unchanged
> (it's now a NULL pointer instead of pointing to the genphy funcs).
> personally, i think the savings in runtime and smaller compiled code is
> more important. so i'm going to NAK this. sorry.
>
> > This patch makes it much easier for subsequent patches to split and
> > refactor the functionality of the .config_aneg() method.
> >
> > Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
> > ---
> >
> > Documentation/networking/phy.txt | 13 +++++--------
> > drivers/net/phy/bcm63xx.c | 4 ----
>
> hrm, what tree are you using ? this driver is not in mainline.
ah, sorry, i was thinking this was u-boot since we were just having
conversations there.
since this is Linux, and i don't have real standing in the general netdev
community, i can't really NAK here. but i think my comment still stands in
that this patch makes things much worse than the minor code style improvement.
-mike
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [RFC PATCH 06/17] phy_driver: Add and use phy_driver_[un]register_multiple()
From: Kyle Moffett @ 2011-10-20 21:00 UTC (permalink / raw)
To: linux-kernel, netdev
Cc: Kyle Moffett, David S. Miller, Greg Dietsche, Giuseppe Cavallaro,
David Daney, Arnaud Patard, Grant Likely, Baruch Siach,
Stephen Hemminger, Lucas De Marchi, Marc Kleine-Budde,
Andrew Morton, Mike Frysinger
In-Reply-To: <1319144425-15547-1-git-send-email-Kyle.D.Moffett@boeing.com>
Several of the PHY drivers are registering dozens of "phy_driver"
structures at load-time, with different IDs and variations on methods.
As a result, the error handling is exceptionally ugly.
The "marvell" driver already uses an array of "struct phy_driver" and
iterates over that to add the drivers, but even then its error handling
contains a bug (it will not unregister array item 0 on failure).
To resolve these problems, new functions phy_driver_register_multiple()
and phy_driver_unregister_multiple() are added which take an array and a
number of drivers and iterate over them internally.
All of the PHY driver files which register more than one "phy_driver"
are modified to use the new helpers. This is a sizable net removal of
about 260 lines of code.
Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
---
drivers/net/phy/bcm63xx.c | 30 +++--------
drivers/net/phy/broadcom.c | 118 ++++++------------------------------------
drivers/net/phy/cicada.c | 32 +++---------
drivers/net/phy/davicom.c | 40 +++-----------
drivers/net/phy/icplus.c | 21 +++-----
drivers/net/phy/lxt.c | 40 +++-----------
drivers/net/phy/marvell.c | 22 ++------
drivers/net/phy/micrel.c | 61 ++++------------------
drivers/net/phy/phy_device.c | 32 +++++++++++
drivers/net/phy/realtek.c | 6 +--
drivers/net/phy/smsc.c | 63 ++++-------------------
drivers/net/phy/ste10Xp.c | 20 +++-----
drivers/net/phy/vitesse.c | 45 ++++++----------
include/linux/phy.h | 2 +
14 files changed, 138 insertions(+), 394 deletions(-)
diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c
index c455f02..3b4258d 100644
--- a/drivers/net/phy/bcm63xx.c
+++ b/drivers/net/phy/bcm63xx.c
@@ -74,7 +74,7 @@ static int bcm63xx_config_intr(struct phy_device *phydev)
return err;
}
-static struct phy_driver bcm63xx_1_driver = {
+static struct phy_driver bcm63xx_drivers[] = { {
.phy_id = 0x00406000,
.phy_id_mask = 0xfffffc00,
.name = "Broadcom BCM63XX (1)",
@@ -85,10 +85,8 @@ static struct phy_driver bcm63xx_1_driver = {
.ack_interrupt = bcm63xx_ack_interrupt,
.config_intr = bcm63xx_config_intr,
.driver = { .owner = THIS_MODULE },
-};
-
-/* same phy as above, with just a different OUI */
-static struct phy_driver bcm63xx_2_driver = {
+}, {
+ /* same phy as above, with just a different OUI */
.phy_id = 0x002bdc00,
.phy_id_mask = 0xfffffc00,
.name = "Broadcom BCM63XX (2)",
@@ -98,30 +96,18 @@ static struct phy_driver bcm63xx_2_driver = {
.ack_interrupt = bcm63xx_ack_interrupt,
.config_intr = bcm63xx_config_intr,
.driver = { .owner = THIS_MODULE },
-};
+} };
static int __init bcm63xx_phy_init(void)
{
- int ret;
-
- ret = phy_driver_register(&bcm63xx_1_driver);
- if (ret)
- goto out_63xx_1;
- ret = phy_driver_register(&bcm63xx_2_driver);
- if (ret)
- goto out_63xx_2;
- return ret;
-
-out_63xx_2:
- phy_driver_unregister(&bcm63xx_1_driver);
-out_63xx_1:
- return ret;
+ return phy_driver_register_multiple(bcm63xx_drivers,
+ ARRAY_SIZE(bcm63xx_drivers));
}
static void __exit bcm63xx_phy_exit(void)
{
- phy_driver_unregister(&bcm63xx_1_driver);
- phy_driver_unregister(&bcm63xx_2_driver);
+ phy_driver_unregister_multiple(bcm63xx_drivers,
+ ARRAY_SIZE(bcm63xx_drivers));
}
module_init(bcm63xx_phy_init);
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index f220264..1b83f75 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -684,7 +684,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
return err;
}
-static struct phy_driver bcm5411_driver = {
+static struct phy_driver broadcom_drivers[] = { {
.phy_id = PHY_ID_BCM5411,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5411",
@@ -695,9 +695,7 @@ static struct phy_driver bcm5411_driver = {
.ack_interrupt = bcm54xx_ack_interrupt,
.config_intr = bcm54xx_config_intr,
.driver = { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5421_driver = {
+}, {
.phy_id = PHY_ID_BCM5421,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5421",
@@ -708,9 +706,7 @@ static struct phy_driver bcm5421_driver = {
.ack_interrupt = bcm54xx_ack_interrupt,
.config_intr = bcm54xx_config_intr,
.driver = { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5461_driver = {
+}, {
.phy_id = PHY_ID_BCM5461,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5461",
@@ -721,9 +717,7 @@ static struct phy_driver bcm5461_driver = {
.ack_interrupt = bcm54xx_ack_interrupt,
.config_intr = bcm54xx_config_intr,
.driver = { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5464_driver = {
+}, {
.phy_id = PHY_ID_BCM5464,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5464",
@@ -734,9 +728,7 @@ static struct phy_driver bcm5464_driver = {
.ack_interrupt = bcm54xx_ack_interrupt,
.config_intr = bcm54xx_config_intr,
.driver = { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5481_driver = {
+}, {
.phy_id = PHY_ID_BCM5481,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5481",
@@ -748,9 +740,7 @@ static struct phy_driver bcm5481_driver = {
.ack_interrupt = bcm54xx_ack_interrupt,
.config_intr = bcm54xx_config_intr,
.driver = { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5482_driver = {
+}, {
.phy_id = PHY_ID_BCM5482,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5482",
@@ -762,9 +752,7 @@ static struct phy_driver bcm5482_driver = {
.ack_interrupt = bcm54xx_ack_interrupt,
.config_intr = bcm54xx_config_intr,
.driver = { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm50610_driver = {
+}, {
.phy_id = PHY_ID_BCM50610,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM50610",
@@ -775,9 +763,7 @@ static struct phy_driver bcm50610_driver = {
.ack_interrupt = bcm54xx_ack_interrupt,
.config_intr = bcm54xx_config_intr,
.driver = { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm50610m_driver = {
+}, {
.phy_id = PHY_ID_BCM50610M,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM50610M",
@@ -788,9 +774,7 @@ static struct phy_driver bcm50610m_driver = {
.ack_interrupt = bcm54xx_ack_interrupt,
.config_intr = bcm54xx_config_intr,
.driver = { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm57780_driver = {
+}, {
.phy_id = PHY_ID_BCM57780,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM57780",
@@ -801,9 +785,7 @@ static struct phy_driver bcm57780_driver = {
.ack_interrupt = bcm54xx_ack_interrupt,
.config_intr = bcm54xx_config_intr,
.driver = { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcmac131_driver = {
+}, {
.phy_id = PHY_ID_BCMAC131,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCMAC131",
@@ -814,9 +796,7 @@ static struct phy_driver bcmac131_driver = {
.ack_interrupt = brcm_fet_ack_interrupt,
.config_intr = brcm_fet_config_intr,
.driver = { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5241_driver = {
+}, {
.phy_id = PHY_ID_BCM5241,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5241",
@@ -827,84 +807,18 @@ static struct phy_driver bcm5241_driver = {
.ack_interrupt = brcm_fet_ack_interrupt,
.config_intr = brcm_fet_config_intr,
.driver = { .owner = THIS_MODULE },
-};
+} };
static int __init broadcom_init(void)
{
- int ret;
-
- ret = phy_driver_register(&bcm5411_driver);
- if (ret)
- goto out_5411;
- ret = phy_driver_register(&bcm5421_driver);
- if (ret)
- goto out_5421;
- ret = phy_driver_register(&bcm5461_driver);
- if (ret)
- goto out_5461;
- ret = phy_driver_register(&bcm5464_driver);
- if (ret)
- goto out_5464;
- ret = phy_driver_register(&bcm5481_driver);
- if (ret)
- goto out_5481;
- ret = phy_driver_register(&bcm5482_driver);
- if (ret)
- goto out_5482;
- ret = phy_driver_register(&bcm50610_driver);
- if (ret)
- goto out_50610;
- ret = phy_driver_register(&bcm50610m_driver);
- if (ret)
- goto out_50610m;
- ret = phy_driver_register(&bcm57780_driver);
- if (ret)
- goto out_57780;
- ret = phy_driver_register(&bcmac131_driver);
- if (ret)
- goto out_ac131;
- ret = phy_driver_register(&bcm5241_driver);
- if (ret)
- goto out_5241;
- return ret;
-
-out_5241:
- phy_driver_unregister(&bcmac131_driver);
-out_ac131:
- phy_driver_unregister(&bcm57780_driver);
-out_57780:
- phy_driver_unregister(&bcm50610m_driver);
-out_50610m:
- phy_driver_unregister(&bcm50610_driver);
-out_50610:
- phy_driver_unregister(&bcm5482_driver);
-out_5482:
- phy_driver_unregister(&bcm5481_driver);
-out_5481:
- phy_driver_unregister(&bcm5464_driver);
-out_5464:
- phy_driver_unregister(&bcm5461_driver);
-out_5461:
- phy_driver_unregister(&bcm5421_driver);
-out_5421:
- phy_driver_unregister(&bcm5411_driver);
-out_5411:
- return ret;
+ return phy_driver_register_multiple(broadcom_drivers,
+ ARRAY_SIZE(broadcom_drivers));
}
static void __exit broadcom_exit(void)
{
- phy_driver_unregister(&bcm5241_driver);
- phy_driver_unregister(&bcmac131_driver);
- phy_driver_unregister(&bcm57780_driver);
- phy_driver_unregister(&bcm50610m_driver);
- phy_driver_unregister(&bcm50610_driver);
- phy_driver_unregister(&bcm5482_driver);
- phy_driver_unregister(&bcm5481_driver);
- phy_driver_unregister(&bcm5464_driver);
- phy_driver_unregister(&bcm5461_driver);
- phy_driver_unregister(&bcm5421_driver);
- phy_driver_unregister(&bcm5411_driver);
+ phy_driver_unregister_multiple(broadcom_drivers,
+ ARRAY_SIZE(broadcom_drivers));
}
module_init(broadcom_init);
diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c
index c409ca2..9c805cd 100644
--- a/drivers/net/phy/cicada.c
+++ b/drivers/net/phy/cicada.c
@@ -101,8 +101,8 @@ static int cis820x_config_intr(struct phy_device *phydev)
return err;
}
-/* Cicada 8201, a.k.a Vitesse VSC8201 */
-static struct phy_driver cis8201_driver = {
+static struct phy_driver cicada_drivers[] = { {
+ /* Cicada 8201, a.k.a Vitesse VSC8201 */
.phy_id = 0x000fc410,
.name = "Cicada Cis8201",
.phy_id_mask = 0x000ffff0,
@@ -112,10 +112,7 @@ static struct phy_driver cis8201_driver = {
.ack_interrupt = &cis820x_ack_interrupt,
.config_intr = &cis820x_config_intr,
.driver = { .owner = THIS_MODULE,},
-};
-
-/* Cicada 8204 */
-static struct phy_driver cis8204_driver = {
+}, {
.phy_id = 0x000fc440,
.name = "Cicada Cis8204",
.phy_id_mask = 0x000fffc0,
@@ -125,31 +122,18 @@ static struct phy_driver cis8204_driver = {
.ack_interrupt = &cis820x_ack_interrupt,
.config_intr = &cis820x_config_intr,
.driver = { .owner = THIS_MODULE,},
-};
+} };
static int __init cicada_init(void)
{
- int ret;
-
- ret = phy_driver_register(&cis8204_driver);
- if (ret)
- goto err1;
-
- ret = phy_driver_register(&cis8201_driver);
- if (ret)
- goto err2;
- return 0;
-
-err2:
- phy_driver_unregister(&cis8204_driver);
-err1:
- return ret;
+ return phy_driver_register_multiple(cicada_drivers,
+ ARRAY_SIZE(cicada_drivers));
}
static void __exit cicada_exit(void)
{
- phy_driver_unregister(&cis8204_driver);
- phy_driver_unregister(&cis8201_driver);
+ phy_driver_unregister_multiple(cicada_drivers,
+ ARRAY_SIZE(cicada_drivers));
}
module_init(cicada_init);
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index 5249e1e..435be46 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -149,7 +149,7 @@ static int dm9161_ack_interrupt(struct phy_device *phydev)
return (err < 0) ? err : 0;
}
-static struct phy_driver dm9161e_driver = {
+static struct phy_driver davicom_drivers[] = { {
.phy_id = 0x0181b880,
.name = "Davicom DM9161E",
.phy_id_mask = 0x0ffffff0,
@@ -157,9 +157,7 @@ static struct phy_driver dm9161e_driver = {
.config_init = dm9161_config_init,
.config_aneg = dm9161_config_aneg,
.driver = { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver dm9161a_driver = {
+}, {
.phy_id = 0x0181b8a0,
.name = "Davicom DM9161A",
.phy_id_mask = 0x0ffffff0,
@@ -167,9 +165,7 @@ static struct phy_driver dm9161a_driver = {
.config_init = dm9161_config_init,
.config_aneg = dm9161_config_aneg,
.driver = { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver dm9131_driver = {
+}, {
.phy_id = 0x00181b80,
.name = "Davicom DM9131",
.phy_id_mask = 0x0ffffff0,
@@ -178,38 +174,18 @@ static struct phy_driver dm9131_driver = {
.ack_interrupt = dm9161_ack_interrupt,
.config_intr = dm9161_config_intr,
.driver = { .owner = THIS_MODULE,},
-};
+} };
static int __init davicom_init(void)
{
- int ret;
-
- ret = phy_driver_register(&dm9161e_driver);
- if (ret)
- goto err1;
-
- ret = phy_driver_register(&dm9161a_driver);
- if (ret)
- goto err2;
-
- ret = phy_driver_register(&dm9131_driver);
- if (ret)
- goto err3;
- return 0;
-
- err3:
- phy_driver_unregister(&dm9161a_driver);
- err2:
- phy_driver_unregister(&dm9161e_driver);
- err1:
- return ret;
+ return phy_driver_register_multiple(davicom_drivers,
+ ARRAY_SIZE(davicom_drivers));
}
static void __exit davicom_exit(void)
{
- phy_driver_unregister(&dm9161e_driver);
- phy_driver_unregister(&dm9161a_driver);
- phy_driver_unregister(&dm9131_driver);
+ phy_driver_unregister_multiple(davicom_drivers,
+ ARRAY_SIZE(davicom_drivers));
}
module_init(davicom_init);
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index 28a190e..b23c78f 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -131,7 +131,7 @@ static int ip175c_config_aneg(struct phy_device *phydev)
return 0;
}
-static struct phy_driver ip175c_driver = {
+static struct phy_driver icplus_drivers[] = { {
.phy_id = 0x02430d80,
.name = "ICPlus IP175C",
.phy_id_mask = 0x0ffffff0,
@@ -142,9 +142,7 @@ static struct phy_driver ip175c_driver = {
.suspend = genphy_suspend,
.resume = genphy_resume,
.driver = { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver ip1001_driver = {
+}, {
.phy_id = 0x02430d90,
.name = "ICPlus IP1001",
.phy_id_mask = 0x0ffffff0,
@@ -154,23 +152,18 @@ static struct phy_driver ip1001_driver = {
.suspend = genphy_suspend,
.resume = genphy_resume,
.driver = { .owner = THIS_MODULE,},
-};
+} };
static int __init icplus_init(void)
{
- int ret = 0;
-
- ret = phy_driver_register(&ip1001_driver);
- if (ret < 0)
- return -ENODEV;
-
- return phy_driver_register(&ip175c_driver);
+ return phy_driver_register_multiple(icplus_drivers,
+ ARRAY_SIZE(icplus_drivers));
}
static void __exit icplus_exit(void)
{
- phy_driver_unregister(&ip1001_driver);
- phy_driver_unregister(&ip175c_driver);
+ phy_driver_unregister_multiple(icplus_drivers,
+ ARRAY_SIZE(icplus_drivers));
}
module_init(icplus_init);
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
index 0ed7e51..902d2d1 100644
--- a/drivers/net/phy/lxt.c
+++ b/drivers/net/phy/lxt.c
@@ -149,7 +149,7 @@ static int lxt973_config_aneg(struct phy_device *phydev)
return phydev->priv ? 0 : genphy_config_aneg(phydev);
}
-static struct phy_driver lxt970_driver = {
+static struct phy_driver lxt_drivers[] = { {
.phy_id = 0x78100000,
.name = "LXT970",
.phy_id_mask = 0xfffffff0,
@@ -159,9 +159,7 @@ static struct phy_driver lxt970_driver = {
.ack_interrupt = lxt970_ack_interrupt,
.config_intr = lxt970_config_intr,
.driver = { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver lxt971_driver = {
+}, {
.phy_id = 0x001378e0,
.name = "LXT971",
.phy_id_mask = 0xfffffff0,
@@ -170,9 +168,7 @@ static struct phy_driver lxt971_driver = {
.ack_interrupt = lxt971_ack_interrupt,
.config_intr = lxt971_config_intr,
.driver = { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver lxt973_driver = {
+}, {
.phy_id = 0x00137a10,
.name = "LXT973",
.phy_id_mask = 0xfffffff0,
@@ -181,38 +177,18 @@ static struct phy_driver lxt973_driver = {
.probe = lxt973_probe,
.config_aneg = lxt973_config_aneg,
.driver = { .owner = THIS_MODULE,},
-};
+} };
static int __init lxt_init(void)
{
- int ret;
-
- ret = phy_driver_register(&lxt970_driver);
- if (ret)
- goto err1;
-
- ret = phy_driver_register(&lxt971_driver);
- if (ret)
- goto err2;
-
- ret = phy_driver_register(&lxt973_driver);
- if (ret)
- goto err3;
- return 0;
-
- err3:
- phy_driver_unregister(&lxt971_driver);
- err2:
- phy_driver_unregister(&lxt970_driver);
- err1:
- return ret;
+ return phy_driver_register_multiple(lxt_drivers,
+ ARRAY_SIZE(lxt_drivers));
}
static void __exit lxt_exit(void)
{
- phy_driver_unregister(&lxt970_driver);
- phy_driver_unregister(&lxt971_driver);
- phy_driver_unregister(&lxt973_driver);
+ phy_driver_unregister_multiple(lxt_drivers,
+ ARRAY_SIZE(lxt_drivers));
}
module_init(lxt_init);
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index e4beb96..9aaae96 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -832,28 +832,14 @@ static struct phy_driver marvell_drivers[] = {
static int __init marvell_init(void)
{
- int ret;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) {
- ret = phy_driver_register(&marvell_drivers[i]);
-
- if (ret) {
- while (i-- > 0)
- phy_driver_unregister(&marvell_drivers[i]);
- return ret;
- }
- }
-
- return 0;
+ return phy_driver_register_multiple(marvell_drivers,
+ ARRAY_SIZE(marvell_drivers));
}
static void __exit marvell_exit(void)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++)
- phy_driver_unregister(&marvell_drivers[i]);
+ phy_driver_unregister_multiple(marvell_drivers,
+ ARRAY_SIZE(marvell_drivers));
}
module_init(marvell_init);
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 1404b3c..1359a2e 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -114,7 +114,7 @@ static int ks8051_config_init(struct phy_device *phydev)
return 0;
}
-static struct phy_driver ks8737_driver = {
+static struct phy_driver ksphy_drivers[] = { {
.phy_id = PHY_ID_KS8737,
.phy_id_mask = 0x00fffff0,
.name = "Micrel KS8737",
@@ -124,9 +124,7 @@ static struct phy_driver ks8737_driver = {
.ack_interrupt = kszphy_ack_interrupt,
.config_intr = ks8737_config_intr,
.driver = { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver ks8041_driver = {
+}, {
.phy_id = PHY_ID_KS8041,
.phy_id_mask = 0x00fffff0,
.name = "Micrel KS8041",
@@ -137,9 +135,7 @@ static struct phy_driver ks8041_driver = {
.ack_interrupt = kszphy_ack_interrupt,
.config_intr = kszphy_config_intr,
.driver = { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver ks8051_driver = {
+}, {
.phy_id = PHY_ID_KS8051,
.phy_id_mask = 0x00fffff0,
.name = "Micrel KS8051",
@@ -150,9 +146,7 @@ static struct phy_driver ks8051_driver = {
.ack_interrupt = kszphy_ack_interrupt,
.config_intr = kszphy_config_intr,
.driver = { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver ks8001_driver = {
+}, {
.phy_id = PHY_ID_KS8001,
.name = "Micrel KS8001 or KS8721",
.phy_id_mask = 0x00fffff0,
@@ -162,9 +156,7 @@ static struct phy_driver ks8001_driver = {
.ack_interrupt = kszphy_ack_interrupt,
.config_intr = kszphy_config_intr,
.driver = { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver ksz9021_driver = {
+}, {
.phy_id = PHY_ID_KSZ9021,
.phy_id_mask = 0x000fff10,
.name = "Micrel KSZ9021 Gigabit PHY",
@@ -175,51 +167,18 @@ static struct phy_driver ksz9021_driver = {
.ack_interrupt = kszphy_ack_interrupt,
.config_intr = ksz9021_config_intr,
.driver = { .owner = THIS_MODULE, },
-};
+} };
static int __init ksphy_init(void)
{
- int ret;
-
- ret = phy_driver_register(&ks8001_driver);
- if (ret)
- goto err1;
-
- ret = phy_driver_register(&ksz9021_driver);
- if (ret)
- goto err2;
-
- ret = phy_driver_register(&ks8737_driver);
- if (ret)
- goto err3;
- ret = phy_driver_register(&ks8041_driver);
- if (ret)
- goto err4;
- ret = phy_driver_register(&ks8051_driver);
- if (ret)
- goto err5;
-
- return 0;
-
-err5:
- phy_driver_unregister(&ks8041_driver);
-err4:
- phy_driver_unregister(&ks8737_driver);
-err3:
- phy_driver_unregister(&ksz9021_driver);
-err2:
- phy_driver_unregister(&ks8001_driver);
-err1:
- return ret;
+ return phy_driver_register_multiple(ksphy_drivers,
+ ARRAY_SIZE(ksphy_drivers));
}
static void __exit ksphy_exit(void)
{
- phy_driver_unregister(&ks8001_driver);
- phy_driver_unregister(&ks8737_driver);
- phy_driver_unregister(&ksz9021_driver);
- phy_driver_unregister(&ks8041_driver);
- phy_driver_unregister(&ks8051_driver);
+ phy_driver_unregister_multiple(ksphy_drivers,
+ ARRAY_SIZE(ksphy_drivers));
}
module_init(ksphy_init);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index f1d8352..8990e87 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1012,6 +1012,38 @@ void phy_driver_unregister(struct phy_driver *drv)
}
EXPORT_SYMBOL(phy_driver_unregister);
+/**
+ * phy_driver_register_multiple - register an array of phy_drivers
+ * @drivers: array of phy_drivers to register
+ */
+int phy_driver_register_multiple(struct phy_driver *drivers,
+ unsigned long nr_drivers)
+{
+ unsigned long i;
+ for (i = 0; i < nr_drivers; i++) {
+ int retval = phy_driver_register(&drivers[i]);
+ if (retval) {
+ /*
+ * A failure occurred, so unregister everything that
+ * was already successfully registered.
+ */
+ phy_driver_unregister_multiple__(drivers, i);
+ return retval;
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL(phy_driver_register_multiple);
+
+void phy_driver_unregister_multiple(struct phy_driver *drivers,
+ unsigned long nr_drivers)
+{
+ unsigned long i;
+ for (i = nr_drivers; i > 0; i++)
+ phy_driver_unregister(drvs[i-1]);
+}
+EXPORT_SYMBOL(phy_driver_unregister_multiple);
+
static struct phy_driver genphy_driver = {
.phy_id = 0xffffffff,
.phy_id_mask = 0xffffffff,
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 1a00deb..0172248 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -62,11 +62,7 @@ static struct phy_driver rtl821x_driver = {
static int __init realtek_init(void)
{
- int ret;
-
- ret = phy_driver_register(&rtl821x_driver);
-
- return ret;
+ return phy_driver_register(&rtl821x_driver);
}
static void __exit realtek_exit(void)
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index a8aa088..eb05b0f 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -80,7 +80,7 @@ static int lan911x_config_init(struct phy_device *phydev)
return smsc_phy_ack_interrupt(phydev);
}
-static struct phy_driver lan83c185_driver = {
+static struct phy_driver smsc_drivers[] = { {
.phy_id = 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */
.phy_id_mask = 0xfffffff0,
.name = "SMSC LAN83C185",
@@ -100,9 +100,7 @@ static struct phy_driver lan83c185_driver = {
.resume = genphy_resume,
.driver = { .owner = THIS_MODULE, }
-};
-
-static struct phy_driver lan8187_driver = {
+}, {
.phy_id = 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */
.phy_id_mask = 0xfffffff0,
.name = "SMSC LAN8187",
@@ -122,9 +120,7 @@ static struct phy_driver lan8187_driver = {
.resume = genphy_resume,
.driver = { .owner = THIS_MODULE, }
-};
-
-static struct phy_driver lan8700_driver = {
+}, {
.phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */
.phy_id_mask = 0xfffffff0,
.name = "SMSC LAN8700",
@@ -144,9 +140,7 @@ static struct phy_driver lan8700_driver = {
.resume = genphy_resume,
.driver = { .owner = THIS_MODULE, }
-};
-
-static struct phy_driver lan911x_int_driver = {
+}, {
.phy_id = 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */
.phy_id_mask = 0xfffffff0,
.name = "SMSC LAN911x Internal PHY",
@@ -166,9 +160,7 @@ static struct phy_driver lan911x_int_driver = {
.resume = genphy_resume,
.driver = { .owner = THIS_MODULE, }
-};
-
-static struct phy_driver lan8710_driver = {
+}, {
.phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
.phy_id_mask = 0xfffffff0,
.name = "SMSC LAN8710/LAN8720",
@@ -188,53 +180,18 @@ static struct phy_driver lan8710_driver = {
.resume = genphy_resume,
.driver = { .owner = THIS_MODULE, }
-};
+} };
static int __init smsc_init(void)
{
- int ret;
-
- ret = phy_driver_register (&lan83c185_driver);
- if (ret)
- goto err1;
-
- ret = phy_driver_register (&lan8187_driver);
- if (ret)
- goto err2;
-
- ret = phy_driver_register (&lan8700_driver);
- if (ret)
- goto err3;
-
- ret = phy_driver_register (&lan911x_int_driver);
- if (ret)
- goto err4;
-
- ret = phy_driver_register (&lan8710_driver);
- if (ret)
- goto err5;
-
- return 0;
-
-err5:
- phy_driver_unregister (&lan911x_int_driver);
-err4:
- phy_driver_unregister (&lan8700_driver);
-err3:
- phy_driver_unregister (&lan8187_driver);
-err2:
- phy_driver_unregister (&lan83c185_driver);
-err1:
- return ret;
+ return phy_driver_register_multiple(smsc_drivers,
+ ARRAY_SIZE(smsc_drivers));
}
static void __exit smsc_exit(void)
{
- phy_driver_unregister (&lan8710_driver);
- phy_driver_unregister (&lan911x_int_driver);
- phy_driver_unregister (&lan8700_driver);
- phy_driver_unregister (&lan8187_driver);
- phy_driver_unregister (&lan83c185_driver);
+ phy_driver_unregister_multiple(smsc_drivers,
+ ARRAY_SIZE(smsc_drivers));
}
MODULE_DESCRIPTION("SMSC PHY driver");
diff --git a/drivers/net/phy/ste10Xp.c b/drivers/net/phy/ste10Xp.c
index 45cde8f..855589c 100644
--- a/drivers/net/phy/ste10Xp.c
+++ b/drivers/net/phy/ste10Xp.c
@@ -81,7 +81,7 @@ static int ste10Xp_ack_interrupt(struct phy_device *phydev)
return 0;
}
-static struct phy_driver ste101p_pdriver = {
+static struct phy_driver ste10Xp_drivers[] = { {
.phy_id = STE101P_PHY_ID,
.phy_id_mask = 0xfffffff0,
.name = "STe101p",
@@ -93,9 +93,7 @@ static struct phy_driver ste101p_pdriver = {
.suspend = genphy_suspend,
.resume = genphy_resume,
.driver = {.owner = THIS_MODULE,}
-};
-
-static struct phy_driver ste100p_pdriver = {
+}, {
.phy_id = STE100P_PHY_ID,
.phy_id_mask = 0xffffffff,
.name = "STe100p",
@@ -107,22 +105,18 @@ static struct phy_driver ste100p_pdriver = {
.suspend = genphy_suspend,
.resume = genphy_resume,
.driver = {.owner = THIS_MODULE,}
-};
+} };
static int __init ste10Xp_init(void)
{
- int retval;
-
- retval = phy_driver_register(&ste100p_pdriver);
- if (retval < 0)
- return retval;
- return phy_driver_register(&ste101p_pdriver);
+ return phy_driver_register_multiple(ste10Xp_drivers,
+ ARRAY_SIZE(ste10Xp_drivers));
}
static void __exit ste10Xp_exit(void)
{
- phy_driver_unregister(&ste100p_pdriver);
- phy_driver_unregister(&ste101p_pdriver);
+ phy_driver_unregister_multiple(ste10Xp_drivers,
+ ARRAY_SIZE(ste10Xp_drivers));
}
module_init(ste10Xp_init);
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 20ea438..82f808e 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -128,19 +128,6 @@ static int vsc82xx_config_intr(struct phy_device *phydev)
return err;
}
-/* Vitesse 824x */
-static struct phy_driver vsc8244_driver = {
- .phy_id = PHY_ID_VSC8244,
- .name = "Vitesse VSC8244",
- .phy_id_mask = 0x000fffc0,
- .features = PHY_GBIT_FEATURES,
- .flags = PHY_HAS_INTERRUPT,
- .config_init = &vsc824x_config_init,
- .ack_interrupt = &vsc824x_ack_interrupt,
- .config_intr = &vsc82xx_config_intr,
- .driver = { .owner = THIS_MODULE,},
-};
-
static int vsc8221_config_init(struct phy_device *phydev)
{
int err;
@@ -153,8 +140,17 @@ static int vsc8221_config_init(struct phy_device *phydev)
Options are 802.3Z SerDes or SGMII */
}
-/* Vitesse 8221 */
-static struct phy_driver vsc8221_driver = {
+static struct phy_driver vitesse_drivers[] = { {
+ .phy_id = PHY_ID_VSC8244,
+ .name = "Vitesse VSC8244",
+ .phy_id_mask = 0x000fffc0,
+ .features = PHY_GBIT_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = &vsc824x_config_init,
+ .ack_interrupt = &vsc824x_ack_interrupt,
+ .config_intr = &vsc82xx_config_intr,
+ .driver = { .owner = THIS_MODULE, },
+}, {
.phy_id = PHY_ID_VSC8221,
.phy_id_mask = 0x000ffff0,
.name = "Vitesse VSC8221",
@@ -163,26 +159,19 @@ static struct phy_driver vsc8221_driver = {
.config_init = &vsc8221_config_init,
.ack_interrupt = &vsc824x_ack_interrupt,
.config_intr = &vsc82xx_config_intr,
- .driver = { .owner = THIS_MODULE,},
-};
+ .driver = { .owner = THIS_MODULE, },
+} };
static int __init vsc82xx_init(void)
{
- int err;
-
- err = phy_driver_register(&vsc8244_driver);
- if (err < 0)
- return err;
- err = phy_driver_register(&vsc8221_driver);
- if (err < 0)
- phy_driver_unregister(&vsc8244_driver);
- return err;
+ return phy_driver_register_multiple(vitesse_drivers,
+ ARRAY_SIZE(vitesse_drivers));
}
static void __exit vsc82xx_exit(void)
{
- phy_driver_unregister(&vsc8244_driver);
- phy_driver_unregister(&vsc8221_driver);
+ phy_driver_unregister_multiple(vitesse_drivers,
+ ARRAY_SIZE(vitesse_drivers));
}
module_init(vsc82xx_init);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index a55a6c4..c6bbb38 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -505,7 +505,9 @@ int genphy_read_status(struct phy_device *phydev);
int genphy_suspend(struct phy_device *phydev);
int genphy_resume(struct phy_device *phydev);
void phy_driver_unregister(struct phy_driver *drv);
+void phy_driver_unregister_multiple(struct phy_driver *drvs, unsigned long nr);
int phy_driver_register(struct phy_driver *new_driver);
+int phy_driver_register_multiple(struct phy_driver *drvs, unsigned long nr);
void phy_state_machine(struct work_struct *work);
void phy_start_machine(struct phy_device *phydev,
void (*handler)(struct net_device *));
--
1.7.2.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox