* Re: [PATCH] Revert "ipw2200: select CFG80211_WEXT"
From: Marcel Holtmann @ 2015-01-03 18:02 UTC (permalink / raw)
To: Paul Bolle
Cc: Stanislav Yakovlev, Kalle Valo, Jiri Kosina, Linus Torvalds,
linux-wireless, Network Development, linux-kernel
In-Reply-To: <1420297188.2397.3.camel@tiscali.nl>
Hi Paul,
> This reverts commit dddd60220f41775e634258efd1b54c6fa81ce706.
>
> The raison d'être of commit dddd60220f41 ("ipw2200: select
> CFG80211_WEXT") was reverted in commit 2d36e008739e ("Revert "cfg80211:
> make WEXT compatibility unselectable""). So revert this commit too.
>
> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
> ---
> drivers/net/wireless/ipw2x00/Kconfig | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig
> index 21de4fe6cf2d..91c0cb3c368e 100644
> --- a/drivers/net/wireless/ipw2x00/Kconfig
> +++ b/drivers/net/wireless/ipw2x00/Kconfig
> @@ -65,8 +65,7 @@ config IPW2100_DEBUG
>
> config IPW2200
> tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
> - depends on PCI && CFG80211
> - select CFG80211_WEXT
> + depends on PCI && CFG80211 && CFG80211_WEXT
> select WIRELESS_EXT
> select WEXT_SPY
> select WEXT_PRIV
why would you revert this? It is obviously the correct change to actually select CFG80211_WEXT.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] Revert "ipw2200: select CFG80211_WEXT"
From: Linus Torvalds @ 2015-01-03 18:07 UTC (permalink / raw)
To: Marcel Holtmann
Cc: Paul Bolle, Stanislav Yakovlev, Kalle Valo, Jiri Kosina,
linux-wireless, Network Development, Linux Kernel Mailing List
In-Reply-To: <CD467A59-F563-439B-BA82-954AB27AD9CC@holtmann.org>
On Sat, Jan 3, 2015 at 10:02 AM, Marcel Holtmann <marcel@holtmann.org> wrote:
>
> why would you revert this? It is obviously the correct change to actually select CFG80211_WEXT.
I don't know about obvious, but yeah, I think the select in this case
is actually the better idea anyway.
We could make the CFG80211_WEXT help message be very negative so that
people aren't encouraged to select it even if they can, but then if
they need the ipw driver it gets selected because of that. Because the
ipw driver is probably the more important of the two if you just
happen to have old hardware but are upgrading yout software (and
anybody who recompiles their own kernel is obviously doing the
latter).
Linus
^ permalink raw reply
* [RFC] netlink: get rid of nl_table_lock
From: Stephen Hemminger @ 2015-01-03 19:02 UTC (permalink / raw)
To: Thomas Graf
Cc: davem, netdev, linux-kernel, herbert, paulmck, edumazet,
john.r.fastabend, josh
In-Reply-To: <daae84cd33bfde8518b849176e25dcf3eea8014b.1420230585.git.tgraf@suug.ch>
As a follow on to Thomas's patch I think this would complete the
transistion to RCU for netlink.
Compile tested only.
This patch gets rid of the reader/writer nl_table_lock and replaces it
with exclusively using RCU for reading, and a mutex for writing.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
--- a/include/net/sock.h 2015-01-01 10:05:35.805253771 -0800
+++ b/include/net/sock.h 2015-01-03 10:45:29.661737618 -0800
@@ -666,6 +666,8 @@ static inline void sk_add_bind_node(stru
hlist_for_each_entry_safe(__sk, tmp, list, sk_node)
#define sk_for_each_bound(__sk, list) \
hlist_for_each_entry(__sk, list, sk_bind_node)
+#define sk_for_each_bound_rcu(__sk, list) \
+ hlist_for_each_entry_rcu(__sk, list, sk_bind_node)
/**
* sk_nulls_for_each_entry_offset - iterate over a list at a given struct offset
--- a/net/netlink/af_netlink.c 2015-01-03 10:04:37.738319202 -0800
+++ b/net/netlink/af_netlink.c 2015-01-03 10:53:29.568387253 -0800
@@ -100,15 +100,14 @@ static void netlink_skb_destructor(struc
* Lookup and traversal are protected with an RCU read-side lock. Insertion
* and removal are protected with nl_sk_hash_lock while using RCU list
* modification primitives and may run in parallel to RCU protected lookups.
- * Destruction of the Netlink socket may only occur *after* nl_table_lock has
+ * Destruction of the Netlink socket may only occur *after* nl_table_mutex has
* been acquired * either during or after the socket has been removed from
* the list and after an RCU grace period.
*/
-DEFINE_RWLOCK(nl_table_lock);
-EXPORT_SYMBOL_GPL(nl_table_lock);
-static atomic_t nl_table_users = ATOMIC_INIT(0);
+static DEFINE_MUTEX(nl_table_mutex);
-#define nl_deref_protected(X) rcu_dereference_protected(X, lockdep_is_held(&nl_table_lock));
+#define nl_deref_protected(X) \
+ rcu_dereference_protected(X, lockdep_is_held(&nl_table_mutex))
/* Protects netlink socket hash table mutations */
DEFINE_MUTEX(nl_sk_hash_lock);
@@ -118,7 +117,8 @@ EXPORT_SYMBOL_GPL(nl_sk_hash_lock);
static int lockdep_nl_sk_hash_is_held(void *parent)
{
if (debug_locks)
- return lockdep_is_held(&nl_sk_hash_lock) || lockdep_is_held(&nl_table_lock);
+ return lockdep_is_held(&nl_sk_hash_lock) ||
+ lockdep_is_held(&nl_table_mutex);
return 1;
}
#endif
@@ -925,59 +925,14 @@ static void netlink_sock_destruct(struct
WARN_ON(nlk_sk(sk)->groups);
}
-/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on
- * SMP. Look, when several writers sleep and reader wakes them up, all but one
- * immediately hit write lock and grab all the cpus. Exclusive sleep solves
- * this, _but_ remember, it adds useless work on UP machines.
- */
-
void netlink_table_grab(void)
- __acquires(nl_table_lock)
{
- might_sleep();
-
- write_lock_irq(&nl_table_lock);
-
- if (atomic_read(&nl_table_users)) {
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue_exclusive(&nl_table_wait, &wait);
- for (;;) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- if (atomic_read(&nl_table_users) == 0)
- break;
- write_unlock_irq(&nl_table_lock);
- schedule();
- write_lock_irq(&nl_table_lock);
- }
-
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(&nl_table_wait, &wait);
- }
+ mutex_lock(&nl_table_mutex);
}
void netlink_table_ungrab(void)
- __releases(nl_table_lock)
-{
- write_unlock_irq(&nl_table_lock);
- wake_up(&nl_table_wait);
-}
-
-static inline void
-netlink_lock_table(void)
{
- /* read_lock() synchronizes us to netlink_table_grab */
-
- read_lock(&nl_table_lock);
- atomic_inc(&nl_table_users);
- read_unlock(&nl_table_lock);
-}
-
-static inline void
-netlink_unlock_table(void)
-{
- if (atomic_dec_and_test(&nl_table_users))
- wake_up(&nl_table_wait);
+ mutex_unlock(&nl_table_mutex);
}
struct netlink_compare_arg
@@ -1151,12 +1106,12 @@ static int netlink_create(struct net *ne
if (protocol < 0 || protocol >= MAX_LINKS)
return -EPROTONOSUPPORT;
- netlink_lock_table();
+ mutex_lock(&nl_table_mutex);
#ifdef CONFIG_MODULES
if (!nl_table[protocol].registered) {
- netlink_unlock_table();
+ mutex_unlock(&nl_table_mutex);
request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol);
- netlink_lock_table();
+ mutex_lock(&nl_table_mutex);
}
#endif
if (nl_table[protocol].registered &&
@@ -1167,7 +1122,7 @@ static int netlink_create(struct net *ne
cb_mutex = nl_table[protocol].cb_mutex;
bind = nl_table[protocol].bind;
unbind = nl_table[protocol].unbind;
- netlink_unlock_table();
+ mutex_unlock(&nl_table_mutex);
if (err < 0)
goto out;
@@ -1982,17 +1937,13 @@ int netlink_broadcast_filtered(struct so
info.tx_filter = filter;
info.tx_data = filter_data;
- /* While we sleep in clone, do not allow to change socket list */
-
- netlink_lock_table();
-
- sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list)
+ rcu_read_lock();
+ sk_for_each_bound_rcu(sk, &nl_table[ssk->sk_protocol].mc_list)
do_one_broadcast(sk, &info);
+ rcu_read_unlock();
consume_skb(skb);
- netlink_unlock_table();
-
if (info.delivery_failure) {
kfree_skb(info.skb2);
return -ENOBUFS;
@@ -2071,12 +2022,11 @@ int netlink_set_err(struct sock *ssk, u3
/* sk->sk_err wants a positive error value */
info.code = -code;
- read_lock(&nl_table_lock);
-
- sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list)
+ rcu_read_lock();
+ sk_for_each_bound_rcu(sk, &nl_table[ssk->sk_protocol].mc_list)
ret += do_one_set_err(sk, &info);
+ rcu_read_unlock();
- read_unlock(&nl_table_lock);
return ret;
}
EXPORT_SYMBOL(netlink_set_err);
--- a/net/netlink/diag.c 2014-08-09 08:39:57.756179454 -0700
+++ b/net/netlink/diag.c 2015-01-03 10:57:31.113791535 -0800
@@ -136,7 +136,7 @@ static int __netlink_diag_dump(struct sk
}
}
- sk_for_each_bound(sk, &tbl->mc_list) {
+ sk_for_each_bound_rcu(sk, &tbl->mc_list) {
if (sk_hashed(sk))
continue;
if (!net_eq(sock_net(sk), net))
@@ -171,7 +171,7 @@ static int netlink_diag_dump(struct sk_b
req = nlmsg_data(cb->nlh);
mutex_lock(&nl_sk_hash_lock);
- read_lock(&nl_table_lock);
+ rcu_read_lock();
if (req->sdiag_protocol == NDIAG_PROTO_ALL) {
int i;
@@ -183,7 +183,7 @@ static int netlink_diag_dump(struct sk_b
}
} else {
if (req->sdiag_protocol >= MAX_LINKS) {
- read_unlock(&nl_table_lock);
+ rcu_read_unlock();
mutex_unlock(&nl_sk_hash_lock);
return -ENOENT;
}
@@ -191,7 +191,7 @@ static int netlink_diag_dump(struct sk_b
__netlink_diag_dump(skb, cb, req->sdiag_protocol, s_num);
}
- read_unlock(&nl_table_lock);
+ rcu_read_unlock();
mutex_unlock(&nl_sk_hash_lock);
return skb->len;
^ permalink raw reply
* Re: [PATCH 0/9 net-next v2] rhashtable: Per bucket locks & deferred table resizing
From: David Miller @ 2015-01-03 19:44 UTC (permalink / raw)
To: tgraf
Cc: netdev, linux-kernel, herbert, paulmck, edumazet,
john.r.fastabend, josh
In-Reply-To: <cover.1420230585.git.tgraf@suug.ch>
From: Thomas Graf <tgraf@suug.ch>
Date: Fri, 2 Jan 2015 23:00:13 +0100
> Prepares for and introduces per bucket spinlocks and deferred table
> resizing. This allows for parallel table mutations in different hash
> buckets from atomic context. The resizing occurs in the background
> in a separate worker thread while lookups, inserts, and removals can
> continue.
>
> Also modified the chain linked list to be terminated with a special
> nulls marker to allow entries to move between multiple lists.
>
> Last but not least, reintroduces lockless netlink_lookup() with
> deferred Netlink socket destruction to avoid the side effect of
> increased netlink_release() runtime.
I'm sure that this might need a minor tweak or two still, but I really
like how you implemented this so I'll apply this series now.
Thanks!
^ permalink raw reply
* Re: linux-next: build failure after merge of the net-next tree
From: David Miller @ 2015-01-03 19:45 UTC (permalink / raw)
To: sfr; +Cc: netdev, linux-next, linux-kernel, richardcochran,
jeffrey.t.kirsher
In-Reply-To: <20150103091101.04b2c11e@canb.auug.org.au>
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Sat, 3 Jan 2015 09:11:01 +1100
> After merging the net-next tree, today's linux-next build (powerpc
> ppc64_defconfig) failed like this:
>
> drivers/net/ethernet/mellanox/mlx4/en_clock.c: In function 'mlx4_en_init_timestamp':
> drivers/net/ethernet/mellanox/mlx4/en_clock.c:249:2: error: implicit declaration of function 'CLOCKSOURCE_MASK' [-Werror=implicit-function-declaration]
> mdev->cycles.mask = CLOCKSOURCE_MASK(48);
Stephen please let me know if this failure is persisting.
^ permalink raw reply
* Re: [PATCH v3 0/6] support GMAC driver for RK3288
From: Heiko Stübner @ 2015-01-03 22:27 UTC (permalink / raw)
To: David Miller
Cc: roger.chen, peppe.cavallaro, netdev, linux-kernel, linux-rockchip,
kever.yang, eddie.cai
In-Reply-To: <20150101.210122.660970681208198668.davem@davemloft.net>
Am Donnerstag, 1. Januar 2015, 21:01:22 schrieb David Miller:
> From: Heiko Stübner <heiko@sntech.de>
> Date: Thu, 01 Jan 2015 03:06:31 +0100
>
> > Hi David,
> >
> > Am Mittwoch, 31. Dezember 2014, 19:15:38 schrieb David Miller:
> >> From: Roger Chen <roger.chen@rock-chips.com>
> >> Date: Mon, 29 Dec 2014 17:42:32 +0800
> >>
> >> > Roger Chen (6):
> >> > patch1: add driver for Rockchip RK3288 SoCs integrated GMAC
> >> > patch2: define clock ID used for GMAC
> >> > patch3: modify CRU config for Rockchip RK3288 SoCs integrated GMAC
> >> > patch4: dts: rockchip: add gmac info for rk3288
> >> > patch5: dts: rockchip: enable gmac on RK3288 evb board
> >> > patch6: add document for Rockchip RK3288 GMAC
> >> >
> >> > Tested on rk3288 evb board:
> >> > Execute the following command to enable ethernet,
> >> > set local IP and ping a remote host.
> >> >
> >> > busybox ifconfig eth0 up
> >> > busybox ifconfig eth0 192.168.1.111
> >> > ping 192.168.1.1
> >>
> >> Series applied to net-next, thanks.
> >
> > could we split this up a bit instead?
>
> Too late, what's in my tree is in the permanent commit history
> and cannot be deleted.
ok no problem ... I'll work around it then so that any possible conflicts are
easily solvable.
Heiko
^ permalink raw reply
* Re: [PATCH] Revert "ipw2200: select CFG80211_WEXT"
From: Paul Bolle @ 2015-01-03 22:28 UTC (permalink / raw)
To: Linus Torvalds
Cc: Marcel Holtmann, Stanislav Yakovlev, Kalle Valo, Jiri Kosina,
linux-wireless, Network Development, Linux Kernel Mailing List
In-Reply-To: <CA+55aFzYSiUkntraMrHEhMzkt35Ft2p9E3cT7ejwQOBDwKvcOg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Sat, 2015-01-03 at 10:07 -0800, Linus Torvalds wrote:
> On Sat, Jan 3, 2015 at 10:02 AM, Marcel Holtmann <marcel-kz+m5ild9QBg9hUCZPvPmw@public.gmane.org> wrote:
> >
> > why would you revert this? It is obviously the correct change to actually select CFG80211_WEXT.
>
> I don't know about obvious, but yeah, I think the select in this case
> is actually the better idea anyway.
Obviously it wasn't obvious to me!
My reasoning was that the "ipw2200: select CFG80211_WEXT" commit was
_solely_ a workaround for the breakage introduced by that other patch.
And since that one is now reverted the workaround wasn't needed anymore.
Besied, I thought we try to avoid select-ing symbols that can also be
set manually. As that makes it more likely to trigger circular
dependency problems in the kconfig tools, doesn't it?
> We could make the CFG80211_WEXT help message be very negative so that
> people aren't encouraged to select it even if they can, but then if
> they need the ipw driver it gets selected because of that. Because the
> ipw driver is probably the more important of the two if you just
> happen to have old hardware but are upgrading yout software (and
> anybody who recompiles their own kernel is obviously doing the
> latter).
Side note: am I correct in thinking that there's some successor to
CFG80211_WEXT and that the ipw2200 driver could, at least in theory, be
ported to that successor? (ipw2200 hardware appears to be a bit old, so
probably no one would care enough to actually do that.)
net/wireless/kconfig doesn't mention anything like that, so probably I'm
just confused.
Paul Bolle
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH iproute2 3/3] ss: Filtering logic changing, with fixes
From: Vadim Kochan @ 2015-01-03 22:58 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Vadim Kochan, netdev
In-Reply-To: <20150103095707.37e69147@urahara>
On Sat, Jan 03, 2015 at 09:57:07AM -0800, Stephen Hemminger wrote:
> On Sat, 3 Jan 2015 02:44:37 +0200
> Vadim Kochan <vadim4j@gmail.com> wrote:
>
> > +struct filter default_dbs[MAX_DB] = {
> > + [TCP_DB] = {
> > + .states = SS_CONN,
> > + .families = (1 << AF_INET) | (1 << AF_INET6),
> > + },
>
> I like table driven code, so this is good. But please make
> mark the table as const.
I did re-test, and I still don't like very much my results (some cases
are not logically) even if they (IMHO) better than the 'master' version,
so I will try to change filer options applying in the following way:
0) default filter should have only default states & all dbs
1) apply all selected families with their default dbs & states from table
2) logical AND selected dbs with dbs of the selected families and their default
states from table, also select families by db from table if there no
already selected families
3) logical AND selected states with selected dbs and their default states from table,
also select families and dbs from table by states if there no
already selected dbs & families
So with such approach the options should affect each other in the strict
predictable way:
families -> dbs (socket tables) -> socket states
I hope I will success with this ...
I appreciate any feedback.
Regards,
Vadim Kochan
^ permalink raw reply
* [PATCH] brcm80211: brcmsmac: dma: Remove some unused functions
From: Rickard Strandqvist @ 2015-01-04 0:47 UTC (permalink / raw)
To: Brett Rudley, Arend van Spriel
Cc: Rickard Strandqvist, Hante Meuleman, Kalle Valo, Fabian Frederick,
linux-wireless, brcm80211-dev-list, netdev, linux-kernel
Removes some functions that are not used anywhere:
dma_txflush() dma_txsuspended()
This was partially found by using a static code analysis program called cppcheck.
Signed-off-by: Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se>
---
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 19 -------------------
drivers/net/wireless/brcm80211/brcmsmac/dma.h | 2 --
2 files changed, 21 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index 796f5f9..bca233a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -1192,16 +1192,6 @@ void dma_txresume(struct dma_pub *pub)
bcma_mask32(di->core, DMA64TXREGOFFS(di, control), ~D64_XC_SE);
}
-bool dma_txsuspended(struct dma_pub *pub)
-{
- struct dma_info *di = container_of(pub, struct dma_info, dma);
-
- return (di->ntxd == 0) ||
- ((bcma_read32(di->core,
- DMA64TXREGOFFS(di, control)) & D64_XC_SE) ==
- D64_XC_SE);
-}
-
void dma_txreclaim(struct dma_pub *pub, enum txd_range range)
{
struct dma_info *di = container_of(pub, struct dma_info, dma);
@@ -1425,15 +1415,6 @@ int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
return -ENOSPC;
}
-void dma_txflush(struct dma_pub *pub)
-{
- struct dma_info *di = container_of(pub, struct dma_info, dma);
- struct brcms_ampdu_session *session = &di->ampdu_session;
-
- if (!skb_queue_empty(&session->skb_list))
- ampdu_finalize(di);
-}
-
int dma_txpending(struct dma_pub *pub)
{
struct dma_info *di = container_of(pub, struct dma_info, dma);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
index ff5b80b..210ec72 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
@@ -88,11 +88,9 @@ bool dma_txreset(struct dma_pub *pub);
void dma_txinit(struct dma_pub *pub);
int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
struct sk_buff *p0);
-void dma_txflush(struct dma_pub *pub);
int dma_txpending(struct dma_pub *pub);
void dma_kick_tx(struct dma_pub *pub);
void dma_txsuspend(struct dma_pub *pub);
-bool dma_txsuspended(struct dma_pub *pub);
void dma_txresume(struct dma_pub *pub);
void dma_txreclaim(struct dma_pub *pub, enum txd_range range);
void dma_rxreclaim(struct dma_pub *pub);
--
1.7.10.4
^ permalink raw reply related
* Fw: [Bug 89831] New: timeout of TCP-sockets is *infinite* by default .. even if TCP-connection is already *broken*
From: Stephen Hemminger @ 2015-01-04 1:33 UTC (permalink / raw)
To: netdev
Begin forwarded message:
Date: Tue, 16 Dec 2014 22:33:50 -0800
From: "bugzilla-daemon@bugzilla.kernel.org" <bugzilla-daemon@bugzilla.kernel.org>
To: "stephen@networkplumber.org" <stephen@networkplumber.org>
Subject: [Bug 89831] New: timeout of TCP-sockets is *infinite* by default .. even if TCP-connection is already *broken*
https://bugzilla.kernel.org/show_bug.cgi?id=89831
Bug ID: 89831
Summary: timeout of TCP-sockets is *infinite* by default ..
even if TCP-connection is already *broken*
Product: Networking
Version: 2.5
Kernel Version: all
Hardware: All
OS: Linux
Tree: Mainline
Status: NEW
Severity: normal
Priority: P1
Component: IPV4
Assignee: shemminger@linux-foundation.org
Reporter: polymorphm@gmail.com
Regression: No
Created attachment 160881
--> https://bugzilla.kernel.org/attachment.cgi?id=160881&action=edit
test for catch infinite freezing (on TCP-sockets by default) on GNU/Linux
good day!
please, very sorry me for your time. :-) [and sorry for my bad english].
big problem in that fact: *most* application-programmers think that if
TCP-connection is already *broken* -- that timeout of TCP-socket will *NOT* be
*infinite*. (default system timeout).
I prepared example code:
https://gist.github.com/polymorphm/0e057402c9fa82547d72 (and this file
"to-test.c" -- in attachment).
this example code ("to-test.c") -- shows that if TCP-connection *broken* --
that timeout will *never* be reached (for broken TCP-connection. EVEN AFTER
SOME DAYS).
program "to-test.c" -- becomes to infinite freezing -- after "[step 8]":
$ gcc -Wall -Werror -o to-test to-test.c && sudo ./to-test
***** begin of test *****
[step 1] creating socket...
***** INFO: is used SO_KEEPALIVE by default for TCP-sockets? answer: 0
*****
[step 2] connecting socket...
[step 3] time waiting (1s)...
[step 4] breaking down network... [wlp1s0]
# ip link set down dev wlp1s0
[step 5] time waiting (15s)...
[step 6] reestablishing up network... [wlp1s0]
# ip link set up dev wlp1s0
[step 7] time waiting (1s)...
[step 8] waiting of socket timeout (or we are freezed *infinity*?)...
(infinite freeze -- at this point)
probably, this issue-ticket will be marked as WONTFIX (and again: very sorry me
for your time!). but this issue-ticket -- need at least for official canonical
URL-link for answer to problem of default timeout of *broken* TCP-connection on
GNU/Linux.
when I speek with some application-programmers -- they say me: if GNU/Linux
freeze at broken-TCP-connections (with default settings of socket) than is
*bug* of GNU/Linux. and I maked this issue-ticket. sorry.
--
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* RE: [PATCH net-next v1 0/3] net: fec: add Wake-on-LAN support
From: fugang.duan @ 2015-01-04 1:39 UTC (permalink / raw)
To: Fabio Estevam, David Miller
Cc: Shawn Guo, netdev@vger.kernel.org, Ben Hutchings,
Stephen Hemminger
In-Reply-To: <CAOMZO5De+v_LAOdxGR=OHV3iMXwe8O-Z1dK0uv8ezMU90sMnMA@mail.gmail.com>
From: Fabio Estevam <festevam@gmail.com> Sent: Thursday, January 01, 2015 3:22 AM
> To: David Miller
> Cc: Duan Fugang-B38611; Shawn Guo; netdev@vger.kernel.org; Ben Hutchings;
> Stephen Hemminger
> Subject: Re: [PATCH net-next v1 0/3] net: fec: add Wake-on-LAN support
>
> On Wed, Dec 31, 2014 at 5:20 PM, David Miller <davem@davemloft.net> wrote:
> > From: Fabio Estevam <festevam@gmail.com>
> > Date: Wed, 31 Dec 2014 17:03:28 -0200
> >
> >> ,but when we see your patches applied they appear with Nimrod Andy as
> >> the author instead:
> >> https://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/commi
> >> t/?id=de40ed31b3c577cefd7b54972365a272ecbe9dd6
> >>
> >> It would be nice if you could use the From field to match the name in
> >> the Signed-off tag.
> >
> > It's his business to setup things properly so they match, not mine. I
> > just take what is in the patch as-is.
>
> Exactly. This was what I suggested him to do.
Thanks for your suggestion.
I have these two English name. Sorry I will sync one name in later patch.
Regards,
Andy
^ permalink raw reply
* [PATCH net-next] qlcnic: Fix dump_skb output
From: Joe Perches @ 2015-01-04 1:50 UTC (permalink / raw)
To: Shahed Shaikh; +Cc: netdev, LKML
Use normal facilities to avoid printing each byte
on a separate line.
Now emits at KERN_DEBUG instead of KERN_INFO.
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 18e5de7..d166e53 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -10,6 +10,7 @@
#include <net/ip.h>
#include <linux/ipv6.h>
#include <net/checksum.h>
+#include <linux/printk.h>
#include "qlcnic.h"
@@ -1465,14 +1466,14 @@ void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter,
static void dump_skb(struct sk_buff *skb, struct qlcnic_adapter *adapter)
{
- int i;
- unsigned char *data = skb->data;
-
- pr_info(KERN_INFO "\n");
- for (i = 0; i < skb->len; i++) {
- QLCDB(adapter, DRV, "%02x ", data[i]);
- if ((i & 0x0f) == 8)
- pr_info(KERN_INFO "\n");
+ if (adapter->ahw->msg_enable & NETIF_MSG_DRV) {
+ char prefix[30];
+
+ scnprintf(prefix, sizeof(prefix), "%s: %s: ",
+ dev_name(&adapter->pdev->dev), __func__);
+
+ print_hex_dump_debug(prefix, DUMP_PREFIX_NONE, 16, 1,
+ skb->data, skb->len, true);
}
}
^ permalink raw reply related
* Re: Re: [PATCH v3 05/20] selftests/ftrace: add install target to enable test install
From: Masami Hiramatsu @ 2015-01-04 5:18 UTC (permalink / raw)
To: Steven Rostedt
Cc: Shuah Khan, mmarek-AlSwsSmVLrQ,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
mingo-H+wXaHxf7aLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
keescook-F7+t8E8rja9g9hUCZPvPmw,
tranmanphong-Re5JQEeQqe8AvxtiuMwx3w, mpe-Gsx/Oe8HsFggBc27wqDAHg,
cov-sgV2jX0FEOL9JmXXK+q4OQ, dh.herrmann-Re5JQEeQqe8AvxtiuMwx3w,
hughd-hpIqsD4AKlfQT0dZR+AlfA, bobby.prani-Re5JQEeQqe8AvxtiuMwx3w,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, tim.bird-/MT0OVThwyLZJqsBc5GL+g,
josh-iaAMLnmF4UmaiuxdJuQwMA, koct9i-Re5JQEeQqe8AvxtiuMwx3w,
linux-kbuild-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20150102104526.29df5641-f9ZlEuEWxVcJvu8Pb33WZ0EMvNT87kid@public.gmane.org>
(2015/01/03 0:45), Steven Rostedt wrote:
> On Wed, 24 Dec 2014 09:27:41 -0700
> Shuah Khan <shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org> wrote:
>
>> Add a new make target to enable installing test. This target
>> installs test in the kselftest install location and add to the
>> kselftest script to run the test. Install target can be run
>> only from top level kernel source directory.
>>
>> Signed-off-by: Shuah Khan <shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
>> ---
>> tools/testing/selftests/ftrace/Makefile | 11 ++++++++++-
>> 1 file changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/testing/selftests/ftrace/Makefile b/tools/testing/selftests/ftrace/Makefile
>> index 76cc9f1..7c7cf42 100644
>> --- a/tools/testing/selftests/ftrace/Makefile
>> +++ b/tools/testing/selftests/ftrace/Makefile
>> @@ -1,7 +1,16 @@
>> +TEST_STR = /bin/sh ./ftracetest || echo ftrace selftests: [FAIL]
>
> Is it ok that this removes the quotes around the echo string? I don't
> see anything wrong about it, but I don't know if there's a shell out
> there that will fail due to it.
Agreed, if possible, we'd better add quotes around the echo string
as you did in 2/20 in this series.
Anyway, you can also add my ack to this patch.
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt-FCd8Q96Dh0JBDgjK7y7TUQ@public.gmane.org>
Thank you!
>
> Other than than,
>
> Acked-by: Steven Rostedt <rostedt-nx8X9YLhiw1AfugRpC6u6w@public.gmane.org>
>
> -- Steve
>
>
>> +
>> all:
>>
>> +install:
>> +ifdef INSTALL_KSFT_PATH
>> + install ./ftracetest $(INSTALL_KSFT_PATH)
>> + @cp -r test.d $(INSTALL_KSFT_PATH)
>> + echo "$(TEST_STR)" >> $(KSELFTEST)
>> +endif
>> +
>> run_tests:
>> - @/bin/sh ./ftracetest || echo "ftrace selftests: [FAIL]"
>> + @$(TEST_STR)
>>
>> clean:
>> rm -rf logs/*
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt-FCd8Q96Dh0JBDgjK7y7TUQ@public.gmane.org
^ permalink raw reply
* Re: Re: [PATCH v3 05/20] selftests/ftrace: add install target to enable test install
From: Masami Hiramatsu @ 2015-01-04 5:29 UTC (permalink / raw)
To: Steven Rostedt
Cc: Shuah Khan, mmarek, gregkh, akpm, mingo, davem, keescook,
tranmanphong, mpe, cov, dh.herrmann, hughd, bobby.prani,
serge.hallyn, ebiederm, tim.bird, josh, koct9i, linux-kbuild,
linux-kernel, linux-api, netdev, yrl.pp-manager.tt@hitachi.com
In-Reply-To: <20150102104526.29df5641@gandalf.local.home>
(2015/01/03 0:45), Steven Rostedt wrote:
> On Wed, 24 Dec 2014 09:27:41 -0700
> Shuah Khan <shuahkh@osg.samsung.com> wrote:
>
>> Add a new make target to enable installing test. This target
>> installs test in the kselftest install location and add to the
>> kselftest script to run the test. Install target can be run
>> only from top level kernel source directory.
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>> tools/testing/selftests/ftrace/Makefile | 11 ++++++++++-
>> 1 file changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/testing/selftests/ftrace/Makefile b/tools/testing/selftests/ftrace/Makefile
>> index 76cc9f1..7c7cf42 100644
>> --- a/tools/testing/selftests/ftrace/Makefile
>> +++ b/tools/testing/selftests/ftrace/Makefile
>> @@ -1,7 +1,16 @@
>> +TEST_STR = /bin/sh ./ftracetest || echo ftrace selftests: [FAIL]
>
> Is it ok that this removes the quotes around the echo string? I don't
> see anything wrong about it, but I don't know if there's a shell out
> there that will fail due to it.
Agreed, if possible, we'd better add quotes around the echo string
as you did in 2/20 in this series.
Anyway, you can also add my ack to this patch.
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Thank you!
>
> Other than than,
>
> Acked-by: Steven Rostedt <rostedt@goodmis.org>
>
> -- Steve
>
>
>> +
>> all:
>>
>> +install:
>> +ifdef INSTALL_KSFT_PATH
>> + install ./ftracetest $(INSTALL_KSFT_PATH)
>> + @cp -r test.d $(INSTALL_KSFT_PATH)
>> + echo "$(TEST_STR)" >> $(KSELFTEST)
>> +endif
>> +
>> run_tests:
>> - @/bin/sh ./ftracetest || echo "ftrace selftests: [FAIL]"
>> + @$(TEST_STR)
>>
>> clean:
>> rm -rf logs/*
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com
^ permalink raw reply
* Re: [PATCH] brcm80211: brcmsmac: dma: Remove some unused functions
From: Larry Finger @ 2015-01-04 6:21 UTC (permalink / raw)
To: Rickard Strandqvist, Brett Rudley, Arend van Spriel
Cc: Hante Meuleman, Kalle Valo, Fabian Frederick,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
brcm80211-dev-list-dY08KVG/lbpWk0Htik3J/w,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1420332469-5907-1-git-send-email-rickard_strandqvist-IW2WV5XWFqGZkjO+N0TKoMugMpMbD5Xr@public.gmane.org>
On 01/03/2015 06:47 PM, Rickard Strandqvist wrote:
> Removes some functions that are not used anywhere:
> dma_txflush() dma_txsuspended()
>
> This was partially found by using a static code analysis program called cppcheck.
>
> Signed-off-by: Rickard Strandqvist <rickard_strandqvist-IW2WV5XWFqGZkjO+N0TKoMugMpMbD5Xr@public.gmane.org>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/dma.c | 19 -------------------
> drivers/net/wireless/brcm80211/brcmsmac/dma.h | 2 --
> 2 files changed, 21 deletions(-)
Just because file dma.c is involved, it does not need to be, nor should it be in
the subject line. You could specify the driver names in the file tree after
wireless. In this instance, one possible subject would be "brcm80211: brcmsmac:
Remove some unused functions". On the other hand, if you look at "git log" to
see past patches, the driver maintainers even leave off the brcm80211 part, thus
to match them, the subject should be "brcmsmac: Remove some unused functions".
As was suggested earlier, you need to look at the precedents. Keeping a uniform
method of patch naming helps when looking for patches in the git log.
Larry
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: [PATCH net-next] net: More vlan tests before registering netdevice
From: Yuval Mintz @ 2015-01-04 6:32 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20150102.155743.1836127158044264148.davem@davemloft.net>
> > I guess this is fine as a defensive test, so I'll apply this.
> > But do you actually know of any devices which have violated this rule either
> > now or in the past?
> > I quickly tried to audit the entire tree for this right now and found no problems.
>
> Actually, reverted.
>
> Nothing makes me more angry than a patch that wasn't even build tested:
>
> net/core/dev.c: In function ‘register_netdevice’:
> net/core/dev.c:6285:57: error: expected ‘)’ before ‘{’ token
> net/core/dev.c:6378:1: error: expected expression before ‘}’ token
> net/core/dev.c:6277:4: error: label ‘out’ used but not defined
> net/core/dev.c:6378:1: warning: control reaches end of non-void function [-
> Wreturn-type]
Sorry about that.
Don't know how that happened, but obviously I can't make any excuses.
Regarding your previous question - I hit it while implementing vlan filtering
offload on a new [yet-to-be-published] qlogic driver; Don't know if anyone
actually had that issue in-tree.
^ permalink raw reply
* [PATCH net-next] list_nulls: fix missing header
From: Ying Xue @ 2015-01-04 7:24 UTC (permalink / raw)
To: netdev; +Cc: davem
Fixup below build error:
include/linux/list_nulls.h: In function ‘hlist_nulls_del’:
include/linux/list_nulls.h:84:13: error: ‘LIST_POISON2’ undeclared (first use in this function)
Signed-off-by: Ying Xue <ying.xue@windriver.com>
---
include/linux/list_nulls.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/list_nulls.h b/include/linux/list_nulls.h
index e8c300e..f266661 100644
--- a/include/linux/list_nulls.h
+++ b/include/linux/list_nulls.h
@@ -1,6 +1,9 @@
#ifndef _LINUX_LIST_NULLS_H
#define _LINUX_LIST_NULLS_H
+#include <linux/poison.h>
+#include <linux/const.h>
+
/*
* Special version of lists, where end of list is not a NULL pointer,
* but a 'nulls' marker, which can have many different values.
--
1.7.9.5
^ permalink raw reply related
* [PATCH net-next] rhashtable: fix missing header
From: Ying Xue @ 2015-01-04 7:25 UTC (permalink / raw)
To: tgraf; +Cc: davem, netdev
Fixup below build error:
include/linux/rhashtable.h: At top level:
include/linux/rhashtable.h:118:34: error: field ‘mutex’ has incomplete type
Signed-off-by: Ying Xue <ying.xue@windriver.com>
---
include/linux/rhashtable.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index de7cac7..de1459c7 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -20,6 +20,7 @@
#include <linux/list_nulls.h>
#include <linux/workqueue.h>
+#include <linux/mutex.h>
/*
* The end of the chain is marked with a special nulls marks which has
--
1.7.9.5
^ permalink raw reply related
* [PATCH net-next] tipc: convert tipc reference table to use generic rhashtable
From: Ying Xue @ 2015-01-04 7:34 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, Paul.Gortmaker, tipc-discussion, tgraf, davem
As tipc reference table is statically allocated, its memory size
requested on stack initialization stage is quite big even if the
maximum port number is just restricted to 8191 currently, however,
the number already becomes insufficient in practice. But if the
maximum ports is allowed to its theory value - 2^32, its consumed
memory size will reach a ridiculously unacceptable value. Apart from
this, heavy tipc users spend a considerable amount of time in
tipc_sk_get() due to the read-lock on ref_table_lock.
If tipc reference table is converted with generic rhashtable, above
mentioned both disadvantages would be resolved respectively: making
use of the new resizable hash table can avoid locking on the lookup;
smaller memory size is required at initial stage, for example, 256
hash bucket slots are requested at the beginning phase instead of
allocating the entire 8191 slots in old mode. The hash table will
grow if entries exceeds 75% of table size up to a total table size
of 1M, and it will automatically shrink if usage falls below 30%,
but the minimum table size is allowed down to 256.
Also converts ref_table_lock to a separate mutex to protect hash table
mutations on write side. Lastly defers the release of the socket
reference using call_rcu() to allow using an RCU read-side protected
call to rhashtable_lookup().
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Erik Hugne <erik.hugne@ericsson.com>
---
net/tipc/Kconfig | 12 --
net/tipc/config.c | 24 +--
net/tipc/core.c | 10 +-
net/tipc/core.h | 3 -
net/tipc/socket.c | 493 ++++++++++++++++++++---------------------------------
net/tipc/socket.h | 4 +-
6 files changed, 196 insertions(+), 350 deletions(-)
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index c890848..91c8a8e 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -20,18 +20,6 @@ menuconfig TIPC
If in doubt, say N.
-config TIPC_PORTS
- int "Maximum number of ports in a node"
- depends on TIPC
- range 127 65535
- default "8191"
- help
- Specifies how many ports can be supported by a node.
- Can range from 127 to 65535 ports; default is 8191.
-
- Setting this to a smaller value saves some memory,
- setting it to higher allows for more ports.
-
config TIPC_MEDIA_IB
bool "InfiniBand media type support"
depends on TIPC && INFINIBAND_IPOIB
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 876f4c6..0b3a90e 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -183,22 +183,6 @@ static struct sk_buff *cfg_set_own_addr(void)
return tipc_cfg_reply_error_string("cannot change to network mode");
}
-static struct sk_buff *cfg_set_max_ports(void)
-{
- u32 value;
-
- if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
- return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
- value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
- if (value == tipc_max_ports)
- return tipc_cfg_reply_none();
- if (value < 127 || value > 65535)
- return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
- " (max ports must be 127-65535)");
- return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
- " (cannot change max ports while TIPC is active)");
-}
-
static struct sk_buff *cfg_set_netid(void)
{
u32 value;
@@ -285,15 +269,9 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
case TIPC_CMD_SET_NODE_ADDR:
rep_tlv_buf = cfg_set_own_addr();
break;
- case TIPC_CMD_SET_MAX_PORTS:
- rep_tlv_buf = cfg_set_max_ports();
- break;
case TIPC_CMD_SET_NETID:
rep_tlv_buf = cfg_set_netid();
break;
- case TIPC_CMD_GET_MAX_PORTS:
- rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_ports);
- break;
case TIPC_CMD_GET_NETID:
rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
break;
@@ -317,6 +295,8 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
case TIPC_CMD_SET_REMOTE_MNG:
case TIPC_CMD_GET_REMOTE_MNG:
case TIPC_CMD_DUMP_LOG:
+ case TIPC_CMD_SET_MAX_PORTS:
+ case TIPC_CMD_GET_MAX_PORTS:
rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (obsolete command)");
break;
diff --git a/net/tipc/core.c b/net/tipc/core.c
index a5737b8..71b2ada 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -34,6 +34,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "core.h"
#include "name_table.h"
#include "subscr.h"
@@ -47,7 +49,6 @@ int tipc_random __read_mostly;
/* configurable TIPC parameters */
u32 tipc_own_addr __read_mostly;
-int tipc_max_ports __read_mostly;
int tipc_net_id __read_mostly;
int sysctl_tipc_rmem[3] __read_mostly; /* min/default/max */
@@ -84,9 +85,9 @@ static void tipc_core_stop(void)
tipc_netlink_stop();
tipc_subscr_stop();
tipc_nametbl_stop();
- tipc_sk_ref_table_stop();
tipc_socket_stop();
tipc_unregister_sysctl();
+ tipc_sk_rht_destroy();
}
/**
@@ -98,7 +99,7 @@ static int tipc_core_start(void)
get_random_bytes(&tipc_random, sizeof(tipc_random));
- err = tipc_sk_ref_table_init(tipc_max_ports, tipc_random);
+ err = tipc_sk_rht_init();
if (err)
goto out_reftbl;
@@ -138,7 +139,7 @@ out_socket:
out_netlink:
tipc_nametbl_stop();
out_nametbl:
- tipc_sk_ref_table_stop();
+ tipc_sk_rht_destroy();
out_reftbl:
return err;
}
@@ -150,7 +151,6 @@ static int __init tipc_init(void)
pr_info("Activated (version " TIPC_MOD_VER ")\n");
tipc_own_addr = 0;
- tipc_max_ports = CONFIG_TIPC_PORTS;
tipc_net_id = 4711;
sysctl_tipc_rmem[0] = TIPC_CONN_OVERLOAD_LIMIT >> 4 <<
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 8460213..56fe422 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -37,8 +37,6 @@
#ifndef _TIPC_CORE_H
#define _TIPC_CORE_H
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/tipc.h>
#include <linux/tipc_config.h>
#include <linux/tipc_netlink.h>
@@ -79,7 +77,6 @@ int tipc_snprintf(char *buf, int len, const char *fmt, ...);
* Global configuration variables
*/
extern u32 tipc_own_addr __read_mostly;
-extern int tipc_max_ports __read_mostly;
extern int tipc_net_id __read_mostly;
extern int sysctl_tipc_rmem[3] __read_mostly;
extern int sysctl_tipc_named_timeout __read_mostly;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 4731cad..a521727 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -34,22 +34,25 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/rhashtable.h>
+#include <linux/jhash.h>
#include "core.h"
#include "name_table.h"
#include "node.h"
#include "link.h"
-#include <linux/export.h>
#include "config.h"
#include "socket.h"
-#define SS_LISTENING -1 /* socket is listening */
-#define SS_READY -2 /* socket is connectionless */
+#define SS_LISTENING -1 /* socket is listening */
+#define SS_READY -2 /* socket is connectionless */
-#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
-#define CONN_PROBING_INTERVAL 3600000 /* [ms] => 1 h */
-#define TIPC_FWD_MSG 1
-#define TIPC_CONN_OK 0
-#define TIPC_CONN_PROBING 1
+#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
+#define CONN_PROBING_INTERVAL 3600000 /* [ms] => 1 h */
+#define TIPC_FWD_MSG 1
+#define TIPC_CONN_OK 0
+#define TIPC_CONN_PROBING 1
+#define TIPC_MAX_PORT 0xffffffff
+#define TIPC_MIN_PORT 1
/**
* struct tipc_sock - TIPC socket structure
@@ -59,7 +62,7 @@
* @conn_instance: TIPC instance used when connection was established
* @published: non-zero if port has one or more associated names
* @max_pkt: maximum packet size "hint" used when building messages sent by port
- * @ref: unique reference to port in TIPC object registry
+ * @portid: unique port identity in TIPC socket hash table
* @phdr: preformatted message header used when sending messages
* @port_list: adjacent ports in TIPC's global list of ports
* @publications: list of publications for port
@@ -74,6 +77,8 @@
* @link_cong: non-zero if owner must sleep because of link congestion
* @sent_unacked: # messages sent by socket, and not yet acked by peer
* @rcv_unacked: # messages read by user, but not yet acked back to peer
+ * @node: hash table node
+ * @rcu: rcu struct for tipc_sock
*/
struct tipc_sock {
struct sock sk;
@@ -82,7 +87,7 @@ struct tipc_sock {
u32 conn_instance;
int published;
u32 max_pkt;
- u32 ref;
+ u32 portid;
struct tipc_msg phdr;
struct list_head sock_list;
struct list_head publications;
@@ -95,6 +100,8 @@ struct tipc_sock {
bool link_cong;
uint sent_unacked;
uint rcv_unacked;
+ struct rhash_head node;
+ struct rcu_head rcu;
};
static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb);
@@ -103,16 +110,14 @@ static void tipc_write_space(struct sock *sk);
static int tipc_release(struct socket *sock);
static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags);
static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p);
-static void tipc_sk_timeout(unsigned long ref);
+static void tipc_sk_timeout(unsigned long portid);
static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
struct tipc_name_seq const *seq);
static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope,
struct tipc_name_seq const *seq);
-static u32 tipc_sk_ref_acquire(struct tipc_sock *tsk);
-static void tipc_sk_ref_discard(u32 ref);
-static struct tipc_sock *tipc_sk_get(u32 ref);
-static struct tipc_sock *tipc_sk_get_next(u32 *ref);
-static void tipc_sk_put(struct tipc_sock *tsk);
+static struct tipc_sock *tipc_sk_lookup(u32 portid);
+static int tipc_sk_insert(struct tipc_sock *tsk);
+static void tipc_sk_remove(struct tipc_sock *tsk);
static const struct proto_ops packet_ops;
static const struct proto_ops stream_ops;
@@ -174,6 +179,10 @@ static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = {
* - port reference
*/
+/* Protects tipc socket hash table mutations */
+static DEFINE_MUTEX(tipc_sk_hash_mutex);
+static struct rhashtable tipc_sk_rht;
+
static u32 tsk_peer_node(struct tipc_sock *tsk)
{
return msg_destnode(&tsk->phdr);
@@ -305,7 +314,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
struct sock *sk;
struct tipc_sock *tsk;
struct tipc_msg *msg;
- u32 ref;
/* Validate arguments */
if (unlikely(protocol != 0))
@@ -339,24 +347,22 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
return -ENOMEM;
tsk = tipc_sk(sk);
- ref = tipc_sk_ref_acquire(tsk);
- if (!ref) {
- pr_warn("Socket create failed; reference table exhausted\n");
- return -ENOMEM;
- }
tsk->max_pkt = MAX_PKT_DEFAULT;
- tsk->ref = ref;
INIT_LIST_HEAD(&tsk->publications);
msg = &tsk->phdr;
tipc_msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG,
NAMED_H_SIZE, 0);
- msg_set_origport(msg, ref);
/* Finish initializing socket data structures */
sock->ops = ops;
sock->state = state;
sock_init_data(sock, sk);
- k_init_timer(&tsk->timer, (Handler)tipc_sk_timeout, ref);
+ if (tipc_sk_insert(tsk)) {
+ pr_warn("Socket create failed; port numbrer exhausted\n");
+ return -EINVAL;
+ }
+ msg_set_origport(msg, tsk->portid);
+ k_init_timer(&tsk->timer, (Handler)tipc_sk_timeout, tsk->portid);
sk->sk_backlog_rcv = tipc_backlog_rcv;
sk->sk_rcvbuf = sysctl_tipc_rmem[1];
sk->sk_data_ready = tipc_data_ready;
@@ -442,6 +448,13 @@ int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
return ret;
}
+static void tipc_sk_callback(struct rcu_head *head)
+{
+ struct tipc_sock *tsk = container_of(head, struct tipc_sock, rcu);
+
+ sock_put(&tsk->sk);
+}
+
/**
* tipc_release - destroy a TIPC socket
* @sock: socket to destroy
@@ -491,7 +504,7 @@ static int tipc_release(struct socket *sock)
(sock->state == SS_CONNECTED)) {
sock->state = SS_DISCONNECTING;
tsk->connected = 0;
- tipc_node_remove_conn(dnode, tsk->ref);
+ tipc_node_remove_conn(dnode, tsk->portid);
}
if (tipc_msg_reverse(skb, &dnode, TIPC_ERR_NO_PORT))
tipc_link_xmit_skb(skb, dnode, 0);
@@ -499,16 +512,16 @@ static int tipc_release(struct socket *sock)
}
tipc_sk_withdraw(tsk, 0, NULL);
- tipc_sk_ref_discard(tsk->ref);
k_cancel_timer(&tsk->timer);
+ tipc_sk_remove(tsk);
if (tsk->connected) {
skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
SHORT_H_SIZE, 0, dnode, tipc_own_addr,
tsk_peer_port(tsk),
- tsk->ref, TIPC_ERR_NO_PORT);
+ tsk->portid, TIPC_ERR_NO_PORT);
if (skb)
- tipc_link_xmit_skb(skb, dnode, tsk->ref);
- tipc_node_remove_conn(dnode, tsk->ref);
+ tipc_link_xmit_skb(skb, dnode, tsk->portid);
+ tipc_node_remove_conn(dnode, tsk->portid);
}
k_term_timer(&tsk->timer);
@@ -518,7 +531,8 @@ static int tipc_release(struct socket *sock)
/* Reject any messages that accumulated in backlog queue */
sock->state = SS_DISCONNECTING;
release_sock(sk);
- sock_put(sk);
+
+ call_rcu(&tsk->rcu, tipc_sk_callback);
sock->sk = NULL;
return 0;
@@ -611,7 +625,7 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
addr->addr.id.ref = tsk_peer_port(tsk);
addr->addr.id.node = tsk_peer_node(tsk);
} else {
- addr->addr.id.ref = tsk->ref;
+ addr->addr.id.ref = tsk->portid;
addr->addr.id.node = tipc_own_addr;
}
@@ -946,7 +960,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
}
new_mtu:
- mtu = tipc_node_get_mtu(dnode, tsk->ref);
+ mtu = tipc_node_get_mtu(dnode, tsk->portid);
__skb_queue_head_init(&head);
rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &head);
if (rc < 0)
@@ -955,7 +969,7 @@ new_mtu:
do {
skb = skb_peek(&head);
TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong;
- rc = tipc_link_xmit(&head, dnode, tsk->ref);
+ rc = tipc_link_xmit(&head, dnode, tsk->portid);
if (likely(rc >= 0)) {
if (sock->state != SS_READY)
sock->state = SS_CONNECTING;
@@ -1028,7 +1042,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
struct tipc_msg *mhdr = &tsk->phdr;
struct sk_buff_head head;
DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
- u32 ref = tsk->ref;
+ u32 portid = tsk->portid;
int rc = -EINVAL;
long timeo;
u32 dnode;
@@ -1067,7 +1081,7 @@ next:
goto exit;
do {
if (likely(!tsk_conn_cong(tsk))) {
- rc = tipc_link_xmit(&head, dnode, ref);
+ rc = tipc_link_xmit(&head, dnode, portid);
if (likely(!rc)) {
tsk->sent_unacked++;
sent += send;
@@ -1076,7 +1090,7 @@ next:
goto next;
}
if (rc == -EMSGSIZE) {
- tsk->max_pkt = tipc_node_get_mtu(dnode, ref);
+ tsk->max_pkt = tipc_node_get_mtu(dnode, portid);
goto next;
}
if (rc != -ELINKCONG)
@@ -1130,8 +1144,8 @@ static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port,
tsk->probing_state = TIPC_CONN_OK;
tsk->connected = 1;
k_start_timer(&tsk->timer, tsk->probing_interval);
- tipc_node_add_conn(peer_node, tsk->ref, peer_port);
- tsk->max_pkt = tipc_node_get_mtu(peer_node, tsk->ref);
+ tipc_node_add_conn(peer_node, tsk->portid, peer_port);
+ tsk->max_pkt = tipc_node_get_mtu(peer_node, tsk->portid);
}
/**
@@ -1238,7 +1252,7 @@ static void tipc_sk_send_ack(struct tipc_sock *tsk, uint ack)
if (!tsk->connected)
return;
skb = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode,
- tipc_own_addr, peer_port, tsk->ref, TIPC_OK);
+ tipc_own_addr, peer_port, tsk->portid, TIPC_OK);
if (!skb)
return;
msg = buf_msg(skb);
@@ -1552,7 +1566,7 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
tsk->connected = 0;
/* let timer expire on it's own */
tipc_node_remove_conn(tsk_peer_node(tsk),
- tsk->ref);
+ tsk->portid);
}
retval = TIPC_OK;
}
@@ -1743,7 +1757,7 @@ int tipc_sk_rcv(struct sk_buff *skb)
u32 dnode;
/* Validate destination and message */
- tsk = tipc_sk_get(dport);
+ tsk = tipc_sk_lookup(dport);
if (unlikely(!tsk)) {
rc = tipc_msg_eval(skb, &dnode);
goto exit;
@@ -1763,7 +1777,7 @@ int tipc_sk_rcv(struct sk_buff *skb)
rc = -TIPC_ERR_OVERLOAD;
}
spin_unlock_bh(&sk->sk_lock.slock);
- tipc_sk_put(tsk);
+ sock_put(sk);
if (likely(!rc))
return 0;
exit:
@@ -2050,20 +2064,20 @@ restart:
goto restart;
}
if (tipc_msg_reverse(skb, &dnode, TIPC_CONN_SHUTDOWN))
- tipc_link_xmit_skb(skb, dnode, tsk->ref);
- tipc_node_remove_conn(dnode, tsk->ref);
+ tipc_link_xmit_skb(skb, dnode, tsk->portid);
+ tipc_node_remove_conn(dnode, tsk->portid);
} else {
dnode = tsk_peer_node(tsk);
skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
TIPC_CONN_MSG, SHORT_H_SIZE,
0, dnode, tipc_own_addr,
tsk_peer_port(tsk),
- tsk->ref, TIPC_CONN_SHUTDOWN);
- tipc_link_xmit_skb(skb, dnode, tsk->ref);
+ tsk->portid, TIPC_CONN_SHUTDOWN);
+ tipc_link_xmit_skb(skb, dnode, tsk->portid);
}
tsk->connected = 0;
sock->state = SS_DISCONNECTING;
- tipc_node_remove_conn(dnode, tsk->ref);
+ tipc_node_remove_conn(dnode, tsk->portid);
/* fall through */
case SS_DISCONNECTING:
@@ -2084,14 +2098,14 @@ restart:
return res;
}
-static void tipc_sk_timeout(unsigned long ref)
+static void tipc_sk_timeout(unsigned long portid)
{
struct tipc_sock *tsk;
struct sock *sk;
struct sk_buff *skb = NULL;
u32 peer_port, peer_node;
- tsk = tipc_sk_get(ref);
+ tsk = tipc_sk_lookup(portid);
if (!tsk)
return;
@@ -2108,20 +2122,20 @@ static void tipc_sk_timeout(unsigned long ref)
/* Previous probe not answered -> self abort */
skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
SHORT_H_SIZE, 0, tipc_own_addr,
- peer_node, ref, peer_port,
+ peer_node, portid, peer_port,
TIPC_ERR_NO_PORT);
} else {
skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE,
0, peer_node, tipc_own_addr,
- peer_port, ref, TIPC_OK);
+ peer_port, portid, TIPC_OK);
tsk->probing_state = TIPC_CONN_PROBING;
k_start_timer(&tsk->timer, tsk->probing_interval);
}
bh_unlock_sock(sk);
if (skb)
- tipc_link_xmit_skb(skb, peer_node, ref);
+ tipc_link_xmit_skb(skb, peer_node, portid);
exit:
- tipc_sk_put(tsk);
+ sock_put(sk);
}
static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
@@ -2132,12 +2146,12 @@ static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
if (tsk->connected)
return -EINVAL;
- key = tsk->ref + tsk->pub_count + 1;
- if (key == tsk->ref)
+ key = tsk->portid + tsk->pub_count + 1;
+ if (key == tsk->portid)
return -EADDRINUSE;
publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
- scope, tsk->ref, key);
+ scope, tsk->portid, key);
if (unlikely(!publ))
return -EINVAL;
@@ -2188,9 +2202,9 @@ static int tipc_sk_show(struct tipc_sock *tsk, char *buf,
ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:",
tipc_zone(tipc_own_addr),
tipc_cluster(tipc_own_addr),
- tipc_node(tipc_own_addr), tsk->ref);
+ tipc_node(tipc_own_addr), tsk->portid);
else
- ret = tipc_snprintf(buf, len, "%-10u:", tsk->ref);
+ ret = tipc_snprintf(buf, len, "%-10u:", tsk->portid);
if (tsk->connected) {
u32 dport = tsk_peer_port(tsk);
@@ -2224,13 +2238,15 @@ static int tipc_sk_show(struct tipc_sock *tsk, char *buf,
struct sk_buff *tipc_sk_socks_show(void)
{
+ const struct bucket_table *tbl;
+ struct rhash_head *pos;
struct sk_buff *buf;
struct tlv_desc *rep_tlv;
char *pb;
int pb_len;
struct tipc_sock *tsk;
int str_len = 0;
- u32 ref = 0;
+ int i;
buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
if (!buf)
@@ -2239,14 +2255,18 @@ struct sk_buff *tipc_sk_socks_show(void)
pb = TLV_DATA(rep_tlv);
pb_len = ULTRA_STRING_MAX_LEN;
- tsk = tipc_sk_get_next(&ref);
- for (; tsk; tsk = tipc_sk_get_next(&ref)) {
- lock_sock(&tsk->sk);
- str_len += tipc_sk_show(tsk, pb + str_len,
- pb_len - str_len, 0);
- release_sock(&tsk->sk);
- tipc_sk_put(tsk);
+ rcu_read_lock();
+ tbl = rht_dereference_rcu((&tipc_sk_rht)->tbl, &tipc_sk_rht);
+ for (i = 0; i < tbl->size; i++) {
+ rht_for_each_entry_rcu(tsk, pos, tbl, i, node) {
+ spin_lock_bh(&tsk->sk.sk_lock.slock);
+ str_len += tipc_sk_show(tsk, pb + str_len,
+ pb_len - str_len, 0);
+ spin_unlock_bh(&tsk->sk.sk_lock.slock);
+ }
}
+ rcu_read_unlock();
+
str_len += 1; /* for "\0" */
skb_put(buf, TLV_SPACE(str_len));
TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
@@ -2259,255 +2279,109 @@ struct sk_buff *tipc_sk_socks_show(void)
*/
void tipc_sk_reinit(void)
{
+ const struct bucket_table *tbl;
+ struct rhash_head *pos;
+ struct tipc_sock *tsk;
struct tipc_msg *msg;
- u32 ref = 0;
- struct tipc_sock *tsk = tipc_sk_get_next(&ref);
+ int i;
- for (; tsk; tsk = tipc_sk_get_next(&ref)) {
- lock_sock(&tsk->sk);
- msg = &tsk->phdr;
- msg_set_prevnode(msg, tipc_own_addr);
- msg_set_orignode(msg, tipc_own_addr);
- release_sock(&tsk->sk);
- tipc_sk_put(tsk);
+ rcu_read_lock();
+ tbl = rht_dereference_rcu((&tipc_sk_rht)->tbl, &tipc_sk_rht);
+ for (i = 0; i < tbl->size; i++) {
+ rht_for_each_entry_rcu(tsk, pos, tbl, i, node) {
+ spin_lock_bh(&tsk->sk.sk_lock.slock);
+ msg = &tsk->phdr;
+ msg_set_prevnode(msg, tipc_own_addr);
+ msg_set_orignode(msg, tipc_own_addr);
+ spin_unlock_bh(&tsk->sk.sk_lock.slock);
+ }
}
+ rcu_read_unlock();
}
-/**
- * struct reference - TIPC socket reference entry
- * @tsk: pointer to socket associated with reference entry
- * @ref: reference value for socket (combines instance & array index info)
- */
-struct reference {
- struct tipc_sock *tsk;
- u32 ref;
-};
-
-/**
- * struct tipc_ref_table - table of TIPC socket reference entries
- * @entries: pointer to array of reference entries
- * @capacity: array index of first unusable entry
- * @init_point: array index of first uninitialized entry
- * @first_free: array index of first unused socket reference entry
- * @last_free: array index of last unused socket reference entry
- * @index_mask: bitmask for array index portion of reference values
- * @start_mask: initial value for instance value portion of reference values
- */
-struct ref_table {
- struct reference *entries;
- u32 capacity;
- u32 init_point;
- u32 first_free;
- u32 last_free;
- u32 index_mask;
- u32 start_mask;
-};
-
-/* Socket reference table consists of 2**N entries.
- *
- * State Socket ptr Reference
- * ----- ---------- ---------
- * In use non-NULL XXXX|own index
- * (XXXX changes each time entry is acquired)
- * Free NULL YYYY|next free index
- * (YYYY is one more than last used XXXX)
- * Uninitialized NULL 0
- *
- * Entry 0 is not used; this allows index 0 to denote the end of the free list.
- *
- * Note that a reference value of 0 does not necessarily indicate that an
- * entry is uninitialized, since the last entry in the free list could also
- * have a reference value of 0 (although this is unlikely).
- */
-
-static struct ref_table tipc_ref_table;
-
-static DEFINE_RWLOCK(ref_table_lock);
-
-/**
- * tipc_ref_table_init - create reference table for sockets
- */
-int tipc_sk_ref_table_init(u32 req_sz, u32 start)
+static struct tipc_sock *tipc_sk_lookup(u32 portid)
{
- struct reference *table;
- u32 actual_sz;
-
- /* account for unused entry, then round up size to a power of 2 */
-
- req_sz++;
- for (actual_sz = 16; actual_sz < req_sz; actual_sz <<= 1) {
- /* do nothing */
- };
-
- /* allocate table & mark all entries as uninitialized */
- table = vzalloc(actual_sz * sizeof(struct reference));
- if (table == NULL)
- return -ENOMEM;
-
- tipc_ref_table.entries = table;
- tipc_ref_table.capacity = req_sz;
- tipc_ref_table.init_point = 1;
- tipc_ref_table.first_free = 0;
- tipc_ref_table.last_free = 0;
- tipc_ref_table.index_mask = actual_sz - 1;
- tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask;
+ struct tipc_sock *tsk;
- return 0;
-}
+ rcu_read_lock();
+ tsk = rhashtable_lookup(&tipc_sk_rht, &portid);
+ if (tsk)
+ sock_hold(&tsk->sk);
+ rcu_read_unlock();
-/**
- * tipc_ref_table_stop - destroy reference table for sockets
- */
-void tipc_sk_ref_table_stop(void)
-{
- if (!tipc_ref_table.entries)
- return;
- vfree(tipc_ref_table.entries);
- tipc_ref_table.entries = NULL;
+ return tsk;
}
-/* tipc_ref_acquire - create reference to a socket
- *
- * Register an socket pointer in the reference table.
- * Returns a unique reference value that is used from then on to retrieve the
- * socket pointer, or to determine if the socket has been deregistered.
- */
-u32 tipc_sk_ref_acquire(struct tipc_sock *tsk)
+static u32 tipc_sk_get_port(void)
{
- u32 index;
- u32 index_mask;
- u32 next_plus_upper;
- u32 ref = 0;
- struct reference *entry;
-
- if (unlikely(!tsk)) {
- pr_err("Attempt to acquire ref. to non-existent obj\n");
- return 0;
- }
- if (unlikely(!tipc_ref_table.entries)) {
- pr_err("Ref. table not found in acquisition attempt\n");
- return 0;
- }
+ u32 remaining = (TIPC_MAX_PORT - TIPC_MIN_PORT) + 1;
+ u32 portid = prandom_u32() % remaining + TIPC_MIN_PORT;
- /* Take a free entry, if available; otherwise initialize a new one */
- write_lock_bh(&ref_table_lock);
- index = tipc_ref_table.first_free;
- entry = &tipc_ref_table.entries[index];
-
- if (likely(index)) {
- index = tipc_ref_table.first_free;
- entry = &tipc_ref_table.entries[index];
- index_mask = tipc_ref_table.index_mask;
- next_plus_upper = entry->ref;
- tipc_ref_table.first_free = next_plus_upper & index_mask;
- ref = (next_plus_upper & ~index_mask) + index;
- entry->tsk = tsk;
- } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
- index = tipc_ref_table.init_point++;
- entry = &tipc_ref_table.entries[index];
- ref = tipc_ref_table.start_mask + index;
+ while (remaining--) {
+ portid++;
+ if ((portid < TIPC_MIN_PORT) || (portid > TIPC_MAX_PORT))
+ portid = TIPC_MIN_PORT;
+ if (!rhashtable_lookup(&tipc_sk_rht, &portid))
+ break;
}
+ if (remaining <= 0)
+ portid = 0;
- if (ref) {
- entry->ref = ref;
- entry->tsk = tsk;
- }
- write_unlock_bh(&ref_table_lock);
- return ref;
+ return portid;
}
-/* tipc_sk_ref_discard - invalidate reference to an socket
- *
- * Disallow future references to an socket and free up the entry for re-use.
- */
-void tipc_sk_ref_discard(u32 ref)
+static int tipc_sk_insert(struct tipc_sock *tsk)
{
- struct reference *entry;
- u32 index;
- u32 index_mask;
+ u32 portid;
- if (unlikely(!tipc_ref_table.entries)) {
- pr_err("Ref. table not found during discard attempt\n");
- return;
+ mutex_lock(&tipc_sk_hash_mutex);
+ portid = tipc_sk_get_port();
+ if (!portid) {
+ mutex_unlock(&tipc_sk_hash_mutex);
+ return -1;
}
-
- index_mask = tipc_ref_table.index_mask;
- index = ref & index_mask;
- entry = &tipc_ref_table.entries[index];
-
- write_lock_bh(&ref_table_lock);
-
- if (unlikely(!entry->tsk)) {
- pr_err("Attempt to discard ref. to non-existent socket\n");
- goto exit;
- }
- if (unlikely(entry->ref != ref)) {
- pr_err("Attempt to discard non-existent reference\n");
- goto exit;
- }
-
- /* Mark entry as unused; increment instance part of entry's
- * reference to invalidate any subsequent references
- */
-
- entry->tsk = NULL;
- entry->ref = (ref & ~index_mask) + (index_mask + 1);
-
- /* Append entry to free entry list */
- if (unlikely(tipc_ref_table.first_free == 0))
- tipc_ref_table.first_free = index;
- else
- tipc_ref_table.entries[tipc_ref_table.last_free].ref |= index;
- tipc_ref_table.last_free = index;
-exit:
- write_unlock_bh(&ref_table_lock);
+ tsk->portid = portid;
+ sock_hold(&tsk->sk);
+ rhashtable_insert(&tipc_sk_rht, &tsk->node);
+ mutex_unlock(&tipc_sk_hash_mutex);
+ return 0;
}
-/* tipc_sk_get - find referenced socket and return pointer to it
- */
-struct tipc_sock *tipc_sk_get(u32 ref)
+static void tipc_sk_remove(struct tipc_sock *tsk)
{
- struct reference *entry;
- struct tipc_sock *tsk;
+ struct sock *sk = &tsk->sk;
- if (unlikely(!tipc_ref_table.entries))
- return NULL;
- read_lock_bh(&ref_table_lock);
- entry = &tipc_ref_table.entries[ref & tipc_ref_table.index_mask];
- tsk = entry->tsk;
- if (likely(tsk && (entry->ref == ref)))
- sock_hold(&tsk->sk);
- else
- tsk = NULL;
- read_unlock_bh(&ref_table_lock);
- return tsk;
+ mutex_lock(&tipc_sk_hash_mutex);
+ if (rhashtable_remove(&tipc_sk_rht, &tsk->node)) {
+ WARN_ON(atomic_read(&sk->sk_refcnt) == 1);
+ __sock_put(sk);
+ }
+ mutex_unlock(&tipc_sk_hash_mutex);
}
-/* tipc_sk_get_next - lock & return next socket after referenced one
-*/
-struct tipc_sock *tipc_sk_get_next(u32 *ref)
+int tipc_sk_rht_init(void)
{
- struct reference *entry;
- struct tipc_sock *tsk = NULL;
- uint index = *ref & tipc_ref_table.index_mask;
+ struct rhashtable_params rht_params = {
+ .nelem_hint = 256,
+ .head_offset = offsetof(struct tipc_sock, node),
+ .key_offset = offsetof(struct tipc_sock, portid),
+ .key_len = sizeof(u32), /* portid */
+ .hashfn = jhash,
+ .max_shift = 20, /* 1M */
+ .min_shift = 8, /* 256 */
+ .grow_decision = rht_grow_above_75,
+ .shrink_decision = rht_shrink_below_30,
+ };
- read_lock_bh(&ref_table_lock);
- while (++index < tipc_ref_table.capacity) {
- entry = &tipc_ref_table.entries[index];
- if (!entry->tsk)
- continue;
- tsk = entry->tsk;
- sock_hold(&tsk->sk);
- *ref = entry->ref;
- break;
- }
- read_unlock_bh(&ref_table_lock);
- return tsk;
+ return rhashtable_init(&tipc_sk_rht, &rht_params);
}
-static void tipc_sk_put(struct tipc_sock *tsk)
+void tipc_sk_rht_destroy(void)
{
- sock_put(&tsk->sk);
+ /* Wait for socket readers to complete */
+ synchronize_net();
+
+ rhashtable_destroy(&tipc_sk_rht);
}
/**
@@ -2829,7 +2703,7 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb,
attrs = nla_nest_start(skb, TIPC_NLA_SOCK);
if (!attrs)
goto genlmsg_cancel;
- if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->ref))
+ if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->portid))
goto attr_msg_cancel;
if (nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tipc_own_addr))
goto attr_msg_cancel;
@@ -2859,22 +2733,29 @@ int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
int err;
struct tipc_sock *tsk;
- u32 prev_ref = cb->args[0];
- u32 ref = prev_ref;
-
- tsk = tipc_sk_get_next(&ref);
- for (; tsk; tsk = tipc_sk_get_next(&ref)) {
- lock_sock(&tsk->sk);
- err = __tipc_nl_add_sk(skb, cb, tsk);
- release_sock(&tsk->sk);
- tipc_sk_put(tsk);
- if (err)
- break;
+ const struct bucket_table *tbl;
+ struct rhash_head *pos;
+ u32 prev_portid = cb->args[0];
+ u32 portid = prev_portid;
+ int i;
- prev_ref = ref;
+ rcu_read_lock();
+ tbl = rht_dereference_rcu((&tipc_sk_rht)->tbl, &tipc_sk_rht);
+ for (i = 0; i < tbl->size; i++) {
+ rht_for_each_entry_rcu(tsk, pos, tbl, i, node) {
+ spin_lock_bh(&tsk->sk.sk_lock.slock);
+ portid = tsk->portid;
+ err = __tipc_nl_add_sk(skb, cb, tsk);
+ spin_unlock_bh(&tsk->sk.sk_lock.slock);
+ if (err)
+ break;
+
+ prev_portid = portid;
+ }
}
+ rcu_read_unlock();
- cb->args[0] = prev_ref;
+ cb->args[0] = prev_portid;
return skb->len;
}
@@ -2962,12 +2843,12 @@ static int __tipc_nl_list_sk_publ(struct sk_buff *skb,
int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
int err;
- u32 tsk_ref = cb->args[0];
+ u32 tsk_portid = cb->args[0];
u32 last_publ = cb->args[1];
u32 done = cb->args[2];
struct tipc_sock *tsk;
- if (!tsk_ref) {
+ if (!tsk_portid) {
struct nlattr **attrs;
struct nlattr *sock[TIPC_NLA_SOCK_MAX + 1];
@@ -2984,13 +2865,13 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb)
if (!sock[TIPC_NLA_SOCK_REF])
return -EINVAL;
- tsk_ref = nla_get_u32(sock[TIPC_NLA_SOCK_REF]);
+ tsk_portid = nla_get_u32(sock[TIPC_NLA_SOCK_REF]);
}
if (done)
return 0;
- tsk = tipc_sk_get(tsk_ref);
+ tsk = tipc_sk_lookup(tsk_portid);
if (!tsk)
return -EINVAL;
@@ -2999,9 +2880,9 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb)
if (!err)
done = 1;
release_sock(&tsk->sk);
- tipc_sk_put(tsk);
+ sock_put(&tsk->sk);
- cb->args[0] = tsk_ref;
+ cb->args[0] = tsk_portid;
cb->args[1] = last_publ;
cb->args[2] = done;
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index d340893..c7d46d06 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -46,8 +46,8 @@ int tipc_sk_rcv(struct sk_buff *buf);
struct sk_buff *tipc_sk_socks_show(void);
void tipc_sk_mcast_rcv(struct sk_buff *buf);
void tipc_sk_reinit(void);
-int tipc_sk_ref_table_init(u32 requested_size, u32 start);
-void tipc_sk_ref_table_stop(void);
+int tipc_sk_rht_init(void);
+void tipc_sk_rht_destroy(void);
int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb);
int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb);
--
1.7.9.5
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
^ permalink raw reply related
* [PATCH net-next v3 0/4] net: bcmgenet: Tx init improvements
From: Petri Gynther @ 2015-01-04 7:45 UTC (permalink / raw)
To: netdev; +Cc: davem, f.fainelli
Four small patches to improve bcmgenet Tx init:
1. bcmgenet_init_tx_ring() cleanup
2. rework Tx queue init
3. precalculate TxCB->bd_addr
4. rename bcmgenet_hw_params->bds_cnt and GENET_DEFAULT_BD_CNT
^ permalink raw reply
* [PATCH net-next v3 1/4] net: bcmgenet: bcmgenet_init_tx_ring() cleanup
From: Petri Gynther @ 2015-01-04 7:45 UTC (permalink / raw)
To: netdev; +Cc: davem, f.fainelli
Signed-off-by: Petri Gynther <pgynther@google.com>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 23 ++++++++---------------
1 file changed, 8 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index ff83c46b..6636182 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1680,17 +1680,14 @@ static int init_umac(struct bcmgenet_priv *priv)
return 0;
}
-/* Initialize all house-keeping variables for a TX ring, along
- * with corresponding hardware registers
- */
+/* Initialize a Tx ring along with corresponding hardware registers */
static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
unsigned int index, unsigned int size,
- unsigned int write_ptr, unsigned int end_ptr)
+ unsigned int start_ptr, unsigned int end_ptr)
{
struct bcmgenet_tx_ring *ring = &priv->tx_rings[index];
u32 words_per_bd = WORDS_PER_BD(priv);
u32 flow_period_val = 0;
- unsigned int first_bd;
spin_lock_init(&ring->lock);
ring->index = index;
@@ -1703,12 +1700,12 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
ring->int_enable = bcmgenet_tx_ring_int_enable;
ring->int_disable = bcmgenet_tx_ring_int_disable;
}
- ring->cbs = priv->tx_cbs + write_ptr;
+ ring->cbs = priv->tx_cbs + start_ptr;
ring->size = size;
ring->c_index = 0;
ring->free_bds = size;
- ring->write_ptr = write_ptr;
- ring->cb_ptr = write_ptr;
+ ring->write_ptr = start_ptr;
+ ring->cb_ptr = start_ptr;
ring->end_ptr = end_ptr - 1;
ring->prod_index = 0;
@@ -1719,22 +1716,18 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_PROD_INDEX);
bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_CONS_INDEX);
bcmgenet_tdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH);
- /* Disable rate control for now */
bcmgenet_tdma_ring_writel(priv, index, flow_period_val,
TDMA_FLOW_PERIOD);
- /* Unclassified traffic goes to ring 16 */
bcmgenet_tdma_ring_writel(priv, index,
((size << DMA_RING_SIZE_SHIFT) |
RX_BUF_LENGTH), DMA_RING_BUF_SIZE);
- first_bd = write_ptr;
-
/* Set start and end address, read and write pointers */
- bcmgenet_tdma_ring_writel(priv, index, first_bd * words_per_bd,
+ bcmgenet_tdma_ring_writel(priv, index, start_ptr * words_per_bd,
DMA_START_ADDR);
- bcmgenet_tdma_ring_writel(priv, index, first_bd * words_per_bd,
+ bcmgenet_tdma_ring_writel(priv, index, start_ptr * words_per_bd,
TDMA_READ_PTR);
- bcmgenet_tdma_ring_writel(priv, index, first_bd,
+ bcmgenet_tdma_ring_writel(priv, index, start_ptr * words_per_bd,
TDMA_WRITE_PTR);
bcmgenet_tdma_ring_writel(priv, index, end_ptr * words_per_bd - 1,
DMA_END_ADDR);
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH net-next v3 2/4] net: bcmgenet: rework Tx queue init
From: Petri Gynther @ 2015-01-04 7:45 UTC (permalink / raw)
To: netdev; +Cc: davem, f.fainelli
1. Rename bcmgenet_init_multiq() to bcmgenet_init_tx_queues()
2. Move Tx default queue init inside bcmgenet_init_tx_queues()
Signed-off-by: Petri Gynther <pgynther@google.com>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 81 +++++++++++---------------
1 file changed, 35 insertions(+), 46 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 6636182..bd06573 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1775,78 +1775,73 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,
return ret;
}
-/* init multi xmit queues, only available for GENET2+
- * the queue is partitioned as follows:
+/* Initialize Tx queues
*
- * queue 0 - 3 is priority based, each one has 32 descriptors,
+ * Queues 0-3 are priority-based, each one has 32 descriptors,
* with queue 0 being the highest priority queue.
*
- * queue 16 is the default tx queue with GENET_DEFAULT_BD_CNT
- * descriptors: 256 - (number of tx queues * bds per queues) = 128
- * descriptors.
+ * Queue 16 is the default Tx queue with
+ * GENET_DEFAULT_BD_CNT = 256 - 4 * 32 = 128 descriptors.
*
- * The transmit control block pool is then partitioned as following:
- * - tx_cbs[0...127] are for queue 16
- * - tx_ring_cbs[0] points to tx_cbs[128..159]
- * - tx_ring_cbs[1] points to tx_cbs[160..191]
- * - tx_ring_cbs[2] points to tx_cbs[192..223]
- * - tx_ring_cbs[3] points to tx_cbs[224..255]
+ * The transmit control block pool is then partitioned as follows:
+ * - Tx queue 0 uses tx_cbs[0..31]
+ * - Tx queue 1 uses tx_cbs[32..63]
+ * - Tx queue 2 uses tx_cbs[64..95]
+ * - Tx queue 3 uses tx_cbs[96..127]
+ * - Tx queue 16 uses tx_cbs[128..255]
*/
-static void bcmgenet_init_multiq(struct net_device *dev)
+static void bcmgenet_init_tx_queues(struct net_device *dev)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
- unsigned int i, dma_enable;
- u32 reg, dma_ctrl, ring_cfg = 0;
+ u32 i, dma_enable;
+ u32 dma_ctrl, ring_cfg;
u32 dma_priority[3] = {0, 0, 0};
- if (!netif_is_multiqueue(dev)) {
- netdev_warn(dev, "called with non multi queue aware HW\n");
- return;
- }
-
dma_ctrl = bcmgenet_tdma_readl(priv, DMA_CTRL);
dma_enable = dma_ctrl & DMA_EN;
dma_ctrl &= ~DMA_EN;
bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL);
+ dma_ctrl = 0;
+ ring_cfg = 0;
+
/* Enable strict priority arbiter mode */
bcmgenet_tdma_writel(priv, DMA_ARBITER_SP, DMA_ARB_CTRL);
+ /* Initialize Tx priority queues */
for (i = 0; i < priv->hw_params->tx_queues; i++) {
- /* first 64 tx_cbs are reserved for default tx queue
- * (ring 16)
- */
bcmgenet_init_tx_ring(priv, i, priv->hw_params->bds_cnt,
i * priv->hw_params->bds_cnt,
(i + 1) * priv->hw_params->bds_cnt);
-
- /* Configure ring as descriptor ring and setup priority */
- ring_cfg |= 1 << i;
- dma_ctrl |= 1 << (i + DMA_RING_BUF_EN_SHIFT);
-
+ ring_cfg |= (1 << i);
+ dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
dma_priority[DMA_PRIO_REG_INDEX(i)] |=
((GENET_Q0_PRIORITY + i) << DMA_PRIO_REG_SHIFT(i));
}
- /* Set ring 16 priority and program the hardware registers */
+ /* Initialize Tx default queue 16 */
+ bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_DEFAULT_BD_CNT,
+ priv->hw_params->tx_queues *
+ priv->hw_params->bds_cnt,
+ TOTAL_DESC);
+ ring_cfg |= (1 << DESC_INDEX);
+ dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT));
dma_priority[DMA_PRIO_REG_INDEX(DESC_INDEX)] |=
((GENET_Q0_PRIORITY + priv->hw_params->tx_queues) <<
DMA_PRIO_REG_SHIFT(DESC_INDEX));
+
+ /* Set Tx queue priorities */
bcmgenet_tdma_writel(priv, dma_priority[0], DMA_PRIORITY_0);
bcmgenet_tdma_writel(priv, dma_priority[1], DMA_PRIORITY_1);
bcmgenet_tdma_writel(priv, dma_priority[2], DMA_PRIORITY_2);
- /* Enable rings */
- reg = bcmgenet_tdma_readl(priv, DMA_RING_CFG);
- reg |= ring_cfg;
- bcmgenet_tdma_writel(priv, reg, DMA_RING_CFG);
+ /* Enable Tx queues */
+ bcmgenet_tdma_writel(priv, ring_cfg, DMA_RING_CFG);
- /* Configure ring as descriptor ring and re-enable DMA if enabled */
- reg = bcmgenet_tdma_readl(priv, DMA_CTRL);
- reg |= dma_ctrl;
+ /* Enable Tx DMA */
if (dma_enable)
- reg |= DMA_EN;
- bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
+ dma_ctrl |= DMA_EN;
+ bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL);
}
static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv)
@@ -1949,14 +1944,8 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv)
return -ENOMEM;
}
- /* initialize multi xmit queue */
- bcmgenet_init_multiq(priv->dev);
-
- /* initialize special ring 16 */
- bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_DEFAULT_BD_CNT,
- priv->hw_params->tx_queues *
- priv->hw_params->bds_cnt,
- TOTAL_DESC);
+ /* Initialize Tx queues */
+ bcmgenet_init_tx_queues(priv->dev);
return 0;
}
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH net-next v3 3/4] net: bcmgenet: precalculate TxCB->bd_addr
From: Petri Gynther @ 2015-01-04 7:45 UTC (permalink / raw)
To: netdev; +Cc: davem, f.fainelli
There is 1-to-1 mapping between TxCBs and TxBDs. Precalculate TxCB->bd_addr
once in bcmgenet_init_dma() instead of doing it over and over needlessly in
bcmgenet_get_txcb().
Signed-off-by: Petri Gynther <pgynther@google.com>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index bd06573..134d3bf 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -920,7 +920,7 @@ static struct enet_cb *bcmgenet_get_txcb(struct bcmgenet_priv *priv,
tx_cb_ptr = ring->cbs;
tx_cb_ptr += ring->write_ptr - ring->cb_ptr;
- tx_cb_ptr->bd_addr = priv->tx_bds + ring->write_ptr * DMA_DESC_SIZE;
+
/* Advancing local write pointer */
if (ring->write_ptr == ring->end_ptr)
ring->write_ptr = ring->cb_ptr;
@@ -1918,6 +1918,8 @@ static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
static int bcmgenet_init_dma(struct bcmgenet_priv *priv)
{
int ret;
+ unsigned int i;
+ struct enet_cb *cb;
netif_dbg(priv, hw, priv->dev, "bcmgenet: init_edma\n");
@@ -1944,6 +1946,11 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv)
return -ENOMEM;
}
+ for (i = 0; i < priv->num_tx_bds; i++) {
+ cb = priv->tx_cbs + i;
+ cb->bd_addr = priv->tx_bds + i * DMA_DESC_SIZE;
+ }
+
/* Initialize Tx queues */
bcmgenet_init_tx_queues(priv->dev);
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH net-next v3 4/4] net: bcmgenet: rename bcmgenet_hw_params->bds_cnt and GENET_DEFAULT_BD_CNT
From: Petri Gynther @ 2015-01-04 7:45 UTC (permalink / raw)
To: netdev; +Cc: davem, f.fainelli
bcmgenet_hw_params->bds_cnt and GENET_DEFAULT_BD_CNT are used only in Tx init.
Rename them accordingly:
- bcmgenet_hw_params->bds_cnt => bcmgenet_hw_params->tx_bds_per_q
- GENET_DEFAULT_BD_CNT => GENET_Q16_TX_BD_CNT
Signed-off-by: Petri Gynther <pgynther@google.com>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 29 +++++++++++++-------------
drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 +-
2 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 134d3bf..f5116c2 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -54,8 +54,8 @@
/* Default highest priority queue for multi queue support */
#define GENET_Q0_PRIORITY 0
-#define GENET_DEFAULT_BD_CNT \
- (TOTAL_DESC - priv->hw_params->tx_queues * priv->hw_params->bds_cnt)
+#define GENET_Q16_TX_BD_CNT \
+ (TOTAL_DESC - priv->hw_params->tx_queues * priv->hw_params->tx_bds_per_q)
#define RX_BUF_LENGTH 2048
#define SKB_ALIGNMENT 32
@@ -1781,7 +1781,7 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,
* with queue 0 being the highest priority queue.
*
* Queue 16 is the default Tx queue with
- * GENET_DEFAULT_BD_CNT = 256 - 4 * 32 = 128 descriptors.
+ * GENET_Q16_TX_BD_CNT = 256 - 4 * 32 = 128 descriptors.
*
* The transmit control block pool is then partitioned as follows:
* - Tx queue 0 uses tx_cbs[0..31]
@@ -1810,9 +1810,9 @@ static void bcmgenet_init_tx_queues(struct net_device *dev)
/* Initialize Tx priority queues */
for (i = 0; i < priv->hw_params->tx_queues; i++) {
- bcmgenet_init_tx_ring(priv, i, priv->hw_params->bds_cnt,
- i * priv->hw_params->bds_cnt,
- (i + 1) * priv->hw_params->bds_cnt);
+ bcmgenet_init_tx_ring(priv, i, priv->hw_params->tx_bds_per_q,
+ i * priv->hw_params->tx_bds_per_q,
+ (i + 1) * priv->hw_params->tx_bds_per_q);
ring_cfg |= (1 << i);
dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
dma_priority[DMA_PRIO_REG_INDEX(i)] |=
@@ -1820,9 +1820,9 @@ static void bcmgenet_init_tx_queues(struct net_device *dev)
}
/* Initialize Tx default queue 16 */
- bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_DEFAULT_BD_CNT,
+ bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_Q16_TX_BD_CNT,
priv->hw_params->tx_queues *
- priv->hw_params->bds_cnt,
+ priv->hw_params->tx_bds_per_q,
TOTAL_DESC);
ring_cfg |= (1 << DESC_INDEX);
dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT));
@@ -2426,8 +2426,8 @@ static const struct net_device_ops bcmgenet_netdev_ops = {
static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
[GENET_V1] = {
.tx_queues = 0,
+ .tx_bds_per_q = 0,
.rx_queues = 0,
- .bds_cnt = 0,
.bp_in_en_shift = 16,
.bp_in_mask = 0xffff,
.hfb_filter_cnt = 16,
@@ -2439,8 +2439,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
},
[GENET_V2] = {
.tx_queues = 4,
+ .tx_bds_per_q = 32,
.rx_queues = 4,
- .bds_cnt = 32,
.bp_in_en_shift = 16,
.bp_in_mask = 0xffff,
.hfb_filter_cnt = 16,
@@ -2455,8 +2455,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
},
[GENET_V3] = {
.tx_queues = 4,
+ .tx_bds_per_q = 32,
.rx_queues = 4,
- .bds_cnt = 32,
.bp_in_en_shift = 17,
.bp_in_mask = 0x1ffff,
.hfb_filter_cnt = 48,
@@ -2471,8 +2471,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
},
[GENET_V4] = {
.tx_queues = 4,
+ .tx_bds_per_q = 32,
.rx_queues = 4,
- .bds_cnt = 32,
.bp_in_en_shift = 17,
.bp_in_mask = 0x1ffff,
.hfb_filter_cnt = 48,
@@ -2572,14 +2572,15 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv)
#endif
pr_debug("Configuration for version: %d\n"
- "TXq: %1d, RXq: %1d, BDs: %1d\n"
+ "TXq: %1d, TXqBDs: %1d, RXq: %1d\n"
"BP << en: %2d, BP msk: 0x%05x\n"
"HFB count: %2d, QTAQ msk: 0x%05x\n"
"TBUF: 0x%04x, HFB: 0x%04x, HFBreg: 0x%04x\n"
"RDMA: 0x%05x, TDMA: 0x%05x\n"
"Words/BD: %d\n",
priv->version,
- params->tx_queues, params->rx_queues, params->bds_cnt,
+ params->tx_queues, params->tx_bds_per_q,
+ params->rx_queues,
params->bp_in_en_shift, params->bp_in_mask,
params->hfb_filter_cnt, params->qtag_mask,
params->tbuf_offset, params->hfb_offset,
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index b36ddec..3a8a90f 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -503,8 +503,8 @@ enum bcmgenet_version {
*/
struct bcmgenet_hw_params {
u8 tx_queues;
+ u8 tx_bds_per_q;
u8 rx_queues;
- u8 bds_cnt;
u8 bp_in_en_shift;
u32 bp_in_mask;
u8 hfb_filter_cnt;
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* Re: [net-next PATCH v1 00/11] A flow API
From: Or Gerlitz @ 2015-01-04 8:30 UTC (permalink / raw)
To: John Fastabend
Cc: Thomas Graf, sfeldma, Jiří Pírko, Jamal Hadi Salim,
simon.horman, Linux Netdev List, David Miller, Andy Gospodarek
In-Reply-To: <20141231194057.31070.5244.stgit@nitbit.x32>
On Wed, Dec 31, 2014 at 9:45 PM, John Fastabend
<john.fastabend@gmail.com> wrote:
> So... I could continue to mull over this and tweak bits and pieces
> here and there but I decided its best to get a wider group of folks
> looking at it and hopefulyl with any luck using it so here it is.
[...]
> I could use some help reviewing
[...]
Hi John,
It would be very helpful to get access to the actual patches, I don't
see them on the netdev patchwork queue, and assume
it's b/c this is still in RFC stage. Cloning your github tree and
looking there, I see some earlier/WIP versions of the code, but it's
not
the submitted patches.
Or.
[1] https://github.com/jrfastab/flow-net-next.git
^ 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