* [PATCH V1 0/4] net/mlx4: Fixes to mlx4 driver
From: Yevgeny Petrilin @ 2012-08-03 10:38 UTC (permalink / raw)
To: davem; +Cc: netdev, Yevgeny Petrilin
Hello Dave,
This is a patchset of 3 fixes and additional change that removes
a port Link layer type restriction that is no longer relevant.
Thanks,
Yevgeny
---
Diff from V0:
-Removed the NETIF_F_GRO patch
Yevgeny Petrilin (2):
net/mlx4_en: Fixing TX queue stop/wake flow
net/mlx4_core: Remove port type restrictions
Amir Vadai (1):
net/mlx4_en: loopbacked packets are dropped when SMAC=DMAC
drivers/net/ethernet/mellanox/mlx4/en_rx.c | 4 ++--
drivers/net/ethernet/mellanox/mlx4/en_tx.c | 17 +++++++----------
drivers/net/ethernet/mellanox/mlx4/main.c | 3 ---
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 -
drivers/net/ethernet/mellanox/mlx4/sense.c | 14 --------------
5 files changed, 9 insertions(+), 30 deletions(-)
^ permalink raw reply
* Re: [PATCH V1 0/4] net/mlx4: Fixes to mlx4 driver
From: David Miller @ 2012-08-03 10:56 UTC (permalink / raw)
To: yevgenyp; +Cc: netdev
In-Reply-To: <1343990318-10744-1-git-send-email-yevgenyp@mellanox.co.il>
"0/4" eh?
^ permalink raw reply
* [PATCH net] net_sched: gact: Fix potential panic in tcf_gact().
From: Hiroaki SHIMODA @ 2012-08-03 10:57 UTC (permalink / raw)
To: davem; +Cc: netdev
gact_rand array is accessed by gact->tcfg_ptype whose value
is assumed to less than MAX_RAND, but any range checks are
not performed.
So add a check in tcf_gact_init(). And in tcf_gact(), we can
reduce a branch.
Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
---
net/sched/act_gact.c | 14 +++++++++++---
1 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index f10fb82..05d60859 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -67,6 +67,9 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
struct tcf_common *pc;
int ret = 0;
int err;
+#ifdef CONFIG_GACT_PROB
+ struct tc_gact_p *p_parm = NULL;
+#endif
if (nla == NULL)
return -EINVAL;
@@ -82,6 +85,12 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
#ifndef CONFIG_GACT_PROB
if (tb[TCA_GACT_PROB] != NULL)
return -EOPNOTSUPP;
+#else
+ if (tb[TCA_GACT_PROB]) {
+ p_parm = nla_data(tb[TCA_GACT_PROB]);
+ if (p_parm->ptype >= MAX_RAND)
+ return -EINVAL;
+ }
#endif
pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info);
@@ -103,8 +112,7 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
spin_lock_bh(&gact->tcf_lock);
gact->tcf_action = parm->action;
#ifdef CONFIG_GACT_PROB
- if (tb[TCA_GACT_PROB] != NULL) {
- struct tc_gact_p *p_parm = nla_data(tb[TCA_GACT_PROB]);
+ if (p_parm) {
gact->tcfg_paction = p_parm->paction;
gact->tcfg_pval = p_parm->pval;
gact->tcfg_ptype = p_parm->ptype;
@@ -133,7 +141,7 @@ static int tcf_gact(struct sk_buff *skb, const struct tc_action *a,
spin_lock(&gact->tcf_lock);
#ifdef CONFIG_GACT_PROB
- if (gact->tcfg_ptype && gact_rand[gact->tcfg_ptype] != NULL)
+ if (gact->tcfg_ptype)
action = gact_rand[gact->tcfg_ptype](gact);
else
action = gact->tcf_action;
--
1.7.8.6
^ permalink raw reply related
* Re: [PATCH v2] ipv4/ipv6: multicast api unappropriate errno fix.
From: David Stevens @ 2012-08-03 12:09 UTC (permalink / raw)
To: Li Wei; +Cc: davem, Li Wei, netdev, netdev-owner
In-Reply-To: <501B99E1.9090803@cn.fujitsu.com>
netdev-owner@vger.kernel.org wrote on 08/03/2012 05:29:05 AM:
> @@ -1933,10 +1933,8 @@ int ip_mc_source(int add, int omode, struct
> sock *sk, struct
> (pmc->multi.imr_ifindex == imr.imr_ifindex))
> break;
> }
> - if (!pmc) { /* must have a prior join */
> - err = -EINVAL;
> - goto done;
> - }
> + if (!pmc) /* must have a prior join */
> + goto done; /* err = -EADDRNOTAVAIL */
RFC3678, section 4.1.3:
"When the option itself is not legal on the group (i.e., when
trying a
Source-Specific option on a group after doing IP_ADD_MEMBERSHIP, or
when trying an Any-Source option without doing IP_ADD_MEMBERSHIP) the
error generated is EINVAL."
> }
> - if (rv == 0) /* address already there is an error */
> + if (rv == 0) { /* address already there is an error */
> + err = -EADDRINUSE;
> goto done;
> + }
EADDRINUSE is not one of the API's listed error codes. Section 4.1.3
of RFC3678 specifies:
"When the option would be legal on the group, but an address is
invalid (e.g., when trying to block a source that is already blocked
by the socket, or when trying to drop an unjoined group) the error
generated is EADDRNOTAVAIL."
At least some of this patch directly differs with RFC3678.
+-DLS
^ permalink raw reply
* [PATCH] emulex: benet: Add a missing CR in the end of message
From: Masanari Iida @ 2012-08-03 12:36 UTC (permalink / raw)
To: linux-kernel, netdev, sathya.perla, subbu.seetharaman,
ajit.khaparde
Cc: Masanari Iida
Missing a CR in printk causes 2 messages printed in one line.
Signed-off-by: Masanari Iida <standby24x7@gmail.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 896f283..82031d3 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1916,7 +1916,7 @@ static int be_rx_cqs_create(struct be_adapter *adapter)
if (adapter->num_rx_qs != MAX_RX_QS)
dev_info(&adapter->pdev->dev,
- "Created only %d receive queues", adapter->num_rx_qs);
+ "Created only %d receive queues\n", adapter->num_rx_qs);
return 0;
}
--
1.7.12.rc1
^ permalink raw reply related
* Re: Premature timeout for MLDv1 Host compatibility mode?
From: David Stevens @ 2012-08-03 13:00 UTC (permalink / raw)
To: Dragos Ilie; +Cc: netdev, netdev-owner
In-Reply-To: <CAOLNa-e0DB7Vhvv8tcSdW_JSWavpmyNt0vFYHLymh_zDaqUiMw@mail.gmail.com>
Dragos Ilie <dragos.ilie@gmail.com> wrote on 08/03/2012 04:54:09 AM:
> a) Section 5.1.9 states that the QQIC field is meant for other
> multicast routers that are not the current querier. I "grep-ed" after
> mld2q_qqic in the entire kernel source tree and it is not being used
> at all. I take this as a sign that the field is not to be interpreted
> by listeners. Of course, that does not mean we cannot use it, but see
> b) below
The kernel doesn't use it because it doesn't use the QI in the
timer to switch back to MLDv2 -- the problem you're trying to address.
If you think that's a bug (and I agree it is), the QQIC is how we
determine the QI. Missing functionality isn't evidence we shouldn't
use the QQIC. :-)
> b) Section 8.3.1 says that "if an MLDv1 router is present on the link,
> the Querier MUST use the lowest version of MLD present on the
> network". Also, "if an MLDv1 router is present on the link, the system
> administrator must explicitly configure all MLDv2 routers to act in
> MLDv1 mode". It seems to me that these statements together preclude a
> scenario with MLDv1 and MLDv2 routers mixed together on the same link,
> unless all routers speak MLDv1.
MLDv2 requires MLDv1 compatibility mode so there's no such thing
as an MLDv2 implementation that doesn't support MLDv1. The mechanism
for falling back to MLDv1 is required for exactly the case when there
is a mix of versions on the link; if that could never happen, none
of this code would be necessary or required by RFC.
> The current implementation for MLDv1 compatibility mode works very
> badly. The listeners fail most of the time to join the groups on the
> MLDv1 server.
I'm not sure what you mean here. Certainly you can, as suggested
above, force all hosts on the subnet to use MLDv1 using the
"force_mld_version" sysctl and an MLDv1 querier will also do that.
They'll switch back to MLDv2 too soon, if the v1 queries happen
infrequently which you can trivially work around by querying more
often.
>I suggest that my patch sent earlier this week is
> pushed upstream, unless there are concerns that it will make things
> worse than they are today. This will improve the behavior of MLDv2
> listeners with MLDv1 routers and keep us compliant with the RFC. What
> do you think?
I think it should be correct, and a fixed QI isn't. If we're going to
do a hack, I think a v2-based QI is better than a fixed value.
However, I was thinking we could directly
measure the v1 QI based on received v1 queries. The main problem with
that is you don't know if you lost one or not, but we could work
around that by using the min of a saved QI and the measured interval
since the last query from the same source. The measured QI with losses
is always a multiple of the actual QI.
So, when we get a v1 query, save a timestamp of it and use the timestamp,
if set, to compute the interval since the last query. If the interval
is less than our current QI, it's the new QI. For the switchback time,
we use QI if set and 125 if not, where not being set would indicate
we haven't gotten more than 2 v1 queries.
Finally, periodically (e.g., based on query counts, or multiple
larger QIs) reset in case an admin has increased the QI without a
reboot.
The QI value only matters if it's the same querier, so also
with the timestamp save the source querier IP address and reset
if you get a general query from a different querier.
+-DLS
^ permalink raw reply
* Re: [PATCH] mlx4_en: add UFO support
From: Thadeu Lima de Souza Cascardo @ 2012-08-03 13:34 UTC (permalink / raw)
To: Yevgeny Petrilin; +Cc: David S. Miller, netdev@vger.kernel.org, Or Gerlitz
In-Reply-To: <953B660C027164448AE903364AC447D2871F0CCC@MTLDAG01.mtl.com>
On Fri, Aug 03, 2012 at 08:29:26AM +0000, Yevgeny Petrilin wrote:
> >
> > Mellanox Ethernet adapters support Large Segmentation Offload for UDP
> > packets. The only change needed is using the proper header size when the
> > packet is UDP instead of TCP.
> >
> > This significantly increases performance for large UDP packets on platforms
> > which have an expensive dma_map call, like pseries.
> >
> > On a simple test with 64000 payload size, throughput has increased from
> > about 6Gbps to 9.5Gbps, while CPU use dropped from about 600% to about
> > 80% or less, on a 8-core Power7 machine.
> >
> Hi Thadeu,
> Can you please send the info regarding the adapter you are testing with? What test are you running?
> I just tried this patch with netperf on my x86_64, and it doesn't work. Packets are not fragmented properly (fragment offsets are not calculated).
> It is true that the TX side doesn't work as hard (OS doesn't need to do the fragmentation), but traffic is not sent properly on the wire.
>
> I'll do further investigation and get back with more details.
>
> Yevgeny
>
Hi, Yevgeny.
At first, I only added the UFO feature. When testing that, I got lots of
errors on the receiving end, like:
UDP: short packet: From 10.0.0.2:0 0/1480 to 10.0.0.3:0
After finding out what the driver was writing to the LSO descriptor, it
was obvious why this happened. The driver was using as the header size
the TCP header size, which would use a value from the UDP packet
payload.
After the other change, however, everything should work fine. I ran a
uperf test with 64000-sized payload packets and everything seemed to
work fine.
The card I have in here is:
0001:01:00.0 Ethernet controller: Mellanox Technologies MT26448 [ConnectX EN 10GigE, PCIe 2.0 5GT/s] (rev b0)
Subsystem: Mellanox Technologies Device 0016
Flags: bus master, fast devsel, latency 0, IRQ 17
Memory at 3da0fbe00000 (64-bit, non-prefetchable) [size=1M]
Memory at 3da0fc000000 (64-bit, prefetchable) [size=32M]
Expansion ROM at 3da0fbf00000 [disabled] [size=1M]
Capabilities: [40] Power Management version 3
Capabilities: [48] Vital Product Data
Capabilities: [9c] MSI-X: Enable+ Count=128 Masked-
Capabilities: [60] Express Endpoint, MSI 00
Capabilities: [100] Alternative Routing-ID Interpretation (ARI)
Capabilities: [148] Device Serial Number 00-02-c9-03-00-4b-97-c4
Kernel driver in use: mlx4_core
Kernel modules: mlx4_core
I will try some other tests in here and report my results.
Regards.
Cascardo.
^ permalink raw reply
* Re: [PATCH] mlx4_en: add UFO support
From: Thadeu Lima de Souza Cascardo @ 2012-08-03 13:54 UTC (permalink / raw)
To: Yevgeny Petrilin; +Cc: David S. Miller, netdev@vger.kernel.org, Or Gerlitz
In-Reply-To: <953B660C027164448AE903364AC447D2871F0CCC@MTLDAG01.mtl.com>
On Fri, Aug 03, 2012 at 08:29:26AM +0000, Yevgeny Petrilin wrote:
> >
> > Mellanox Ethernet adapters support Large Segmentation Offload for UDP
> > packets. The only change needed is using the proper header size when the
> > packet is UDP instead of TCP.
> >
> > This significantly increases performance for large UDP packets on platforms
> > which have an expensive dma_map call, like pseries.
> >
> > On a simple test with 64000 payload size, throughput has increased from
> > about 6Gbps to 9.5Gbps, while CPU use dropped from about 600% to about
> > 80% or less, on a 8-core Power7 machine.
> >
> Hi Thadeu,
> Can you please send the info regarding the adapter you are testing with? What test are you running?
> I just tried this patch with netperf on my x86_64, and it doesn't work. Packets are not fragmented properly (fragment offsets are not calculated).
> It is true that the TX side doesn't work as hard (OS doesn't need to do the fragmentation), but traffic is not sent properly on the wire.
>
> I'll do further investigation and get back with more details.
>
> Yevgeny
>
Hi, Yevgeny.
You are right. After generating a dump on the receiving end, and sending
a single large packet, I did notice that fragment offsets were all 0,
more fragments flag is not set and id is incremented.
Does the hardware really support UFO as documented? Should we just write
the IP header to the descriptor? I will try this and report my results.
Meanwhile, can you find out what is needed to get this working?
Thanks a lot.
Cascardo.
^ permalink raw reply
* [RFC v2 0/7] generic hashtable implementation
From: Sasha Levin @ 2012-08-03 14:23 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, Sasha Levin
There are quite a few places in the kernel which implement a hashtable
in a very similar way. Instead of having implementations of a hashtable
all over the kernel, we can re-use the code.
This patch series introduces a very simple hashtable implementation, and
modifies three (random) modules to use it. I've limited it to 3 only
so that it would be easy to review and modify, and to show that even
at this number we already eliminate a big amount of duplicated code.
If this basic hashtable looks ok, future code will include:
- RCU support
- Self locking (list_bl?)
- Converting more code to use the hashtable
Changes in V2:
- Address review comments by Tejun Heo, Josh Triplett and Eric Beiderman (Thanks all!).
- Rebase on top of latest master.
- Convert more places to use the hashtable. Hopefully it will trigger more reviews by
touching more subsystems.
Sasha Levin (7):
hashtable: introduce a small and naive hashtable
user_ns: use new hashtable implementation
mm,ksm: use new hashtable implementation
workqueue: use new hashtable implementation
mm/huge_memory: use new hashtable implementation
tracepoint: use new hashtable implementation
net,9p: use new hashtable implementation
include/linux/hashtable.h | 75 ++++++++++++++++++++++++++++++++++++
kernel/tracepoint.c | 26 ++++--------
kernel/user.c | 53 +++++++++-----------------
kernel/workqueue.c | 93 +++++++--------------------------------------
mm/huge_memory.c | 56 +++++----------------------
mm/ksm.c | 29 ++++----------
net/9p/error.c | 17 ++++----
7 files changed, 144 insertions(+), 205 deletions(-)
create mode 100644 include/linux/hashtable.h
--
1.7.8.6
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [RFC v2 1/7] hashtable: introduce a small and naive hashtable
From: Sasha Levin @ 2012-08-03 14:23 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, Sasha Levin
In-Reply-To: <1344003788-1417-1-git-send-email-levinsasha928@gmail.com>
This hashtable implementation is using hlist buckets to provide a simple
hashtable to prevent it from getting reimplemented all over the kernel.
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
include/linux/hashtable.h | 75 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 75 insertions(+), 0 deletions(-)
create mode 100644 include/linux/hashtable.h
diff --git a/include/linux/hashtable.h b/include/linux/hashtable.h
new file mode 100644
index 0000000..b004cf7
--- /dev/null
+++ b/include/linux/hashtable.h
@@ -0,0 +1,75 @@
+#ifndef _LINUX_HASHTABLE_H
+#define _LINUX_HASHTABLE_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/hash.h>
+
+struct hash_table {
+ size_t bits;
+ struct hlist_head buckets[];
+};
+
+#define DEFINE_STATIC_HASHTABLE(n, b) \
+ static struct hash_table n = { .bits = (b), \
+ .buckets = { [0 ... ((1 << (b)) - 1)] = HLIST_HEAD_INIT } }
+
+#define DEFINE_HASHTABLE(n, b) \
+ union { \
+ struct hash_table n; \
+ struct { \
+ size_t bits; \
+ struct hlist_head buckets[1 << (b)]; \
+ } __##n ; \
+ };
+
+#define HASH_BITS(name) ((name)->bits)
+#define HASH_SIZE(name) (1 << (HASH_BITS(name)))
+
+__attribute__ ((unused))
+static void hash_init(struct hash_table *ht, size_t bits)
+{
+ size_t i;
+
+ ht->bits = bits;
+ for (i = 0; i < (1 << bits); i++)
+ INIT_HLIST_HEAD(&ht->buckets[i]);
+}
+
+static void hash_add(struct hash_table *ht, struct hlist_node *node, long key)
+{
+ hlist_add_head(node,
+ &ht->buckets[hash_long((unsigned long)key, HASH_BITS(ht))]);
+}
+
+
+#define hash_get(name, key, type, member, cmp_fn) \
+({ \
+ struct hlist_node *__node; \
+ typeof(key) __key = key; \
+ type *__obj = NULL; \
+ hlist_for_each_entry(__obj, __node, &(name)->buckets[ \
+ hash_long((unsigned long) __key, \
+ HASH_BITS(name))], member) \
+ if (cmp_fn(__obj, __key)) \
+ break; \
+ __obj; \
+})
+
+__attribute__ ((unused))
+static void hash_del(struct hlist_node *node)
+{
+ hlist_del_init(node);
+}
+
+#define hash_for_each(bkt, node, name, obj, member) \
+ for (bkt = 0; bkt < HASH_SIZE(name); bkt++) \
+ hlist_for_each_entry(obj, node, &(name)->buckets[i], member)
+
+#define hash_for_each_possible(name, node, obj, member, key) \
+ hlist_for_each_entry(obj, node, \
+ &(name)->buckets[hash_long((unsigned long) key, \
+ HASH_BITS(name))], member)
+
+#endif
--
1.7.8.6
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [RFC v2 2/7] user_ns: use new hashtable implementation
From: Sasha Levin @ 2012-08-03 14:23 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, Sasha Levin
In-Reply-To: <1344003788-1417-1-git-send-email-levinsasha928@gmail.com>
Switch user_ns to use the new hashtable implementation. This reduces the amount of
generic unrelated code in user_ns.
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
kernel/user.c | 53 ++++++++++++++++++-----------------------------------
1 files changed, 18 insertions(+), 35 deletions(-)
diff --git a/kernel/user.c b/kernel/user.c
index b815fef..555c71a 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/export.h>
#include <linux/user_namespace.h>
+#include <linux/hashtable.h>
/*
* userns count is 1 for root user, 1 for init_uts_ns,
@@ -50,15 +51,14 @@ EXPORT_SYMBOL_GPL(init_user_ns);
* UID task count cache, to get fast user lookup in "alloc_uid"
* when changing user ID's (ie setuid() and friends).
*/
-
-#define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 7)
-#define UIDHASH_SZ (1 << UIDHASH_BITS)
-#define UIDHASH_MASK (UIDHASH_SZ - 1)
-#define __uidhashfn(uid) (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK)
-#define uidhashentry(uid) (uidhash_table + __uidhashfn((__kuid_val(uid))))
+#define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 7)
+#define UIDHASH_CMP(obj, key) ((obj)->uid == (key))
+#define uidhash_entry(key) (hash_get(&uidhash_table, key, \
+ struct user_struct, uidhash_node, \
+ UIDHASH_CMP))
static struct kmem_cache *uid_cachep;
-struct hlist_head uidhash_table[UIDHASH_SZ];
+DEFINE_STATIC_HASHTABLE(uidhash_table, UIDHASH_BITS);
/*
* The uidhash_lock is mostly taken from process context, but it is
@@ -84,29 +84,14 @@ struct user_struct root_user = {
/*
* These routines must be called with the uidhash spinlock held!
*/
-static void uid_hash_insert(struct user_struct *up, struct hlist_head *hashent)
+static void uid_hash_insert(struct user_struct *up)
{
- hlist_add_head(&up->uidhash_node, hashent);
+ hash_add(&uidhash_table, &up->uidhash_node, up->uid);
}
static void uid_hash_remove(struct user_struct *up)
{
- hlist_del_init(&up->uidhash_node);
-}
-
-static struct user_struct *uid_hash_find(kuid_t uid, struct hlist_head *hashent)
-{
- struct user_struct *user;
- struct hlist_node *h;
-
- hlist_for_each_entry(user, h, hashent, uidhash_node) {
- if (uid_eq(user->uid, uid)) {
- atomic_inc(&user->__count);
- return user;
- }
- }
-
- return NULL;
+ hash_del(&up->uidhash_node);
}
/* IRQs are disabled and uidhash_lock is held upon function entry.
@@ -135,7 +120,9 @@ struct user_struct *find_user(kuid_t uid)
unsigned long flags;
spin_lock_irqsave(&uidhash_lock, flags);
- ret = uid_hash_find(uid, uidhashentry(uid));
+ ret = uidhash_entry(uid);
+ if (ret)
+ atomic_inc(&ret->__count);
spin_unlock_irqrestore(&uidhash_lock, flags);
return ret;
}
@@ -156,11 +143,10 @@ void free_uid(struct user_struct *up)
struct user_struct *alloc_uid(kuid_t uid)
{
- struct hlist_head *hashent = uidhashentry(uid);
struct user_struct *up, *new;
spin_lock_irq(&uidhash_lock);
- up = uid_hash_find(uid, hashent);
+ up = uidhash_entry(uid);
spin_unlock_irq(&uidhash_lock);
if (!up) {
@@ -176,13 +162,13 @@ struct user_struct *alloc_uid(kuid_t uid)
* on adding the same user already..
*/
spin_lock_irq(&uidhash_lock);
- up = uid_hash_find(uid, hashent);
+ up = uidhash_entry(uid);
if (up) {
key_put(new->uid_keyring);
key_put(new->session_keyring);
kmem_cache_free(uid_cachep, new);
} else {
- uid_hash_insert(new, hashent);
+ uid_hash_insert(new);
up = new;
}
spin_unlock_irq(&uidhash_lock);
@@ -196,17 +182,14 @@ out_unlock:
static int __init uid_cache_init(void)
{
- int n;
-
uid_cachep = kmem_cache_create("uid_cache", sizeof(struct user_struct),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
- for(n = 0; n < UIDHASH_SZ; ++n)
- INIT_HLIST_HEAD(uidhash_table + n);
+ hash_init(&uidhash_table, UIDHASH_BITS);
/* Insert the root user immediately (init already runs as root) */
spin_lock_irq(&uidhash_lock);
- uid_hash_insert(&root_user, uidhashentry(GLOBAL_ROOT_UID));
+ uid_hash_insert(&root_user);
spin_unlock_irq(&uidhash_lock);
return 0;
--
1.7.8.6
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [RFC v2 3/7] mm,ksm: use new hashtable implementation
From: Sasha Levin @ 2012-08-03 14:23 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, Sasha Levin
In-Reply-To: <1344003788-1417-1-git-send-email-levinsasha928@gmail.com>
Switch ksm to use the new hashtable implementation. This reduces the amount of
generic unrelated code in the ksm module.
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
mm/ksm.c | 29 +++++++++--------------------
1 files changed, 9 insertions(+), 20 deletions(-)
diff --git a/mm/ksm.c b/mm/ksm.c
index 47c8853..72d062a 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -33,7 +33,7 @@
#include <linux/mmu_notifier.h>
#include <linux/swap.h>
#include <linux/ksm.h>
-#include <linux/hash.h>
+#include <linux/hashtable.h>
#include <linux/freezer.h>
#include <linux/oom.h>
@@ -157,8 +157,8 @@ static struct rb_root root_stable_tree = RB_ROOT;
static struct rb_root root_unstable_tree = RB_ROOT;
#define MM_SLOTS_HASH_SHIFT 10
-#define MM_SLOTS_HASH_HEADS (1 << MM_SLOTS_HASH_SHIFT)
-static struct hlist_head mm_slots_hash[MM_SLOTS_HASH_HEADS];
+#define mm_hash_cmp(slot, key) ((slot)->mm == (key))
+DEFINE_STATIC_HASHTABLE(mm_slots_hash, MM_SLOTS_HASH_SHIFT);
static struct mm_slot ksm_mm_head = {
.mm_list = LIST_HEAD_INIT(ksm_mm_head.mm_list),
@@ -275,26 +275,15 @@ static inline void free_mm_slot(struct mm_slot *mm_slot)
static struct mm_slot *get_mm_slot(struct mm_struct *mm)
{
- struct mm_slot *mm_slot;
- struct hlist_head *bucket;
- struct hlist_node *node;
-
- bucket = &mm_slots_hash[hash_ptr(mm, MM_SLOTS_HASH_SHIFT)];
- hlist_for_each_entry(mm_slot, node, bucket, link) {
- if (mm == mm_slot->mm)
- return mm_slot;
- }
- return NULL;
+ return hash_get(&mm_slots_hash, mm, struct mm_slot,
+ link, mm_hash_cmp);
}
static void insert_to_mm_slots_hash(struct mm_struct *mm,
struct mm_slot *mm_slot)
{
- struct hlist_head *bucket;
-
- bucket = &mm_slots_hash[hash_ptr(mm, MM_SLOTS_HASH_SHIFT)];
mm_slot->mm = mm;
- hlist_add_head(&mm_slot->link, bucket);
+ hash_add(&mm_slots_hash, &mm_slot->link, (long)mm);
}
static inline int in_stable_tree(struct rmap_item *rmap_item)
@@ -647,7 +636,7 @@ static int unmerge_and_remove_all_rmap_items(void)
ksm_scan.mm_slot = list_entry(mm_slot->mm_list.next,
struct mm_slot, mm_list);
if (ksm_test_exit(mm)) {
- hlist_del(&mm_slot->link);
+ hash_del(&mm_slot->link);
list_del(&mm_slot->mm_list);
spin_unlock(&ksm_mmlist_lock);
@@ -1385,7 +1374,7 @@ next_mm:
* or when all VM_MERGEABLE areas have been unmapped (and
* mmap_sem then protects against race with MADV_MERGEABLE).
*/
- hlist_del(&slot->link);
+ hash_del(&slot->link);
list_del(&slot->mm_list);
spin_unlock(&ksm_mmlist_lock);
@@ -1548,7 +1537,7 @@ void __ksm_exit(struct mm_struct *mm)
mm_slot = get_mm_slot(mm);
if (mm_slot && ksm_scan.mm_slot != mm_slot) {
if (!mm_slot->rmap_list) {
- hlist_del(&mm_slot->link);
+ hash_del(&mm_slot->link);
list_del(&mm_slot->mm_list);
easy_to_free = 1;
} else {
--
1.7.8.6
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [RFC v2 4/7] workqueue: use new hashtable implementation
From: Sasha Levin @ 2012-08-03 14:23 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, Sasha Levin
In-Reply-To: <1344003788-1417-1-git-send-email-levinsasha928@gmail.com>
Switch workqueues to use the new hashtable implementation. This reduces the amount of
generic unrelated code in the workqueues.
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
kernel/workqueue.c | 93 ++++++++--------------------------------------------
1 files changed, 14 insertions(+), 79 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 692d976..480975d 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -41,6 +41,7 @@
#include <linux/debug_locks.h>
#include <linux/lockdep.h>
#include <linux/idr.h>
+#include <linux/hashtable.h>
#include "workqueue_sched.h"
@@ -82,8 +83,6 @@ enum {
NR_WORKER_POOLS = 2, /* # worker pools per gcwq */
BUSY_WORKER_HASH_ORDER = 6, /* 64 pointers */
- BUSY_WORKER_HASH_SIZE = 1 << BUSY_WORKER_HASH_ORDER,
- BUSY_WORKER_HASH_MASK = BUSY_WORKER_HASH_SIZE - 1,
MAX_IDLE_WORKERS_RATIO = 4, /* 1/4 of busy can be idle */
IDLE_WORKER_TIMEOUT = 300 * HZ, /* keep idle ones for 5 mins */
@@ -102,6 +101,8 @@ enum {
HIGHPRI_NICE_LEVEL = -20,
};
+#define worker_hash_cmp(obj, key) ((obj)->current_work == (key))
+
/*
* Structure fields follow one of the following exclusion rules.
*
@@ -180,7 +181,7 @@ struct global_cwq {
unsigned int flags; /* L: GCWQ_* flags */
/* workers are chained either in busy_hash or pool idle_list */
- struct hlist_head busy_hash[BUSY_WORKER_HASH_SIZE];
+ DEFINE_HASHTABLE(busy_hash, BUSY_WORKER_HASH_ORDER);
/* L: hash of busy workers */
struct worker_pool pools[2]; /* normal and highpri pools */
@@ -287,10 +288,6 @@ EXPORT_SYMBOL_GPL(system_nrt_freezable_wq);
for ((pool) = &(gcwq)->pools[0]; \
(pool) < &(gcwq)->pools[NR_WORKER_POOLS]; (pool)++)
-#define for_each_busy_worker(worker, i, pos, gcwq) \
- for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++) \
- hlist_for_each_entry(worker, pos, &gcwq->busy_hash[i], hentry)
-
static inline int __next_gcwq_cpu(int cpu, const struct cpumask *mask,
unsigned int sw)
{
@@ -822,70 +819,11 @@ static inline void worker_clr_flags(struct worker *worker, unsigned int flags)
}
/**
- * busy_worker_head - return the busy hash head for a work
- * @gcwq: gcwq of interest
- * @work: work to be hashed
- *
- * Return hash head of @gcwq for @work.
- *
- * CONTEXT:
- * spin_lock_irq(gcwq->lock).
- *
- * RETURNS:
- * Pointer to the hash head.
- */
-static struct hlist_head *busy_worker_head(struct global_cwq *gcwq,
- struct work_struct *work)
-{
- const int base_shift = ilog2(sizeof(struct work_struct));
- unsigned long v = (unsigned long)work;
-
- /* simple shift and fold hash, do we need something better? */
- v >>= base_shift;
- v += v >> BUSY_WORKER_HASH_ORDER;
- v &= BUSY_WORKER_HASH_MASK;
-
- return &gcwq->busy_hash[v];
-}
-
-/**
- * __find_worker_executing_work - find worker which is executing a work
- * @gcwq: gcwq of interest
- * @bwh: hash head as returned by busy_worker_head()
- * @work: work to find worker for
- *
- * Find a worker which is executing @work on @gcwq. @bwh should be
- * the hash head obtained by calling busy_worker_head() with the same
- * work.
- *
- * CONTEXT:
- * spin_lock_irq(gcwq->lock).
- *
- * RETURNS:
- * Pointer to worker which is executing @work if found, NULL
- * otherwise.
- */
-static struct worker *__find_worker_executing_work(struct global_cwq *gcwq,
- struct hlist_head *bwh,
- struct work_struct *work)
-{
- struct worker *worker;
- struct hlist_node *tmp;
-
- hlist_for_each_entry(worker, tmp, bwh, hentry)
- if (worker->current_work == work)
- return worker;
- return NULL;
-}
-
-/**
* find_worker_executing_work - find worker which is executing a work
* @gcwq: gcwq of interest
* @work: work to find worker for
*
- * Find a worker which is executing @work on @gcwq. This function is
- * identical to __find_worker_executing_work() except that this
- * function calculates @bwh itself.
+ * Find a worker which is executing @work on @gcwq.
*
* CONTEXT:
* spin_lock_irq(gcwq->lock).
@@ -897,8 +835,8 @@ static struct worker *__find_worker_executing_work(struct global_cwq *gcwq,
static struct worker *find_worker_executing_work(struct global_cwq *gcwq,
struct work_struct *work)
{
- return __find_worker_executing_work(gcwq, busy_worker_head(gcwq, work),
- work);
+ return hash_get(&gcwq->busy_hash, work, struct worker,
+ hentry, worker_hash_cmp);
}
/**
@@ -959,7 +897,7 @@ static bool is_chained_work(struct workqueue_struct *wq)
int i;
spin_lock_irqsave(&gcwq->lock, flags);
- for_each_busy_worker(worker, i, pos, gcwq) {
+ hash_for_each(i, pos, &gcwq->busy_hash, worker, hentry) {
if (worker->task != current)
continue;
spin_unlock_irqrestore(&gcwq->lock, flags);
@@ -1432,7 +1370,7 @@ retry:
wake_up_all(&gcwq->rebind_hold);
/* rebind busy workers */
- for_each_busy_worker(worker, i, pos, gcwq) {
+ hash_for_each(i, pos, &gcwq->busy_hash, worker, hentry) {
struct work_struct *rebind_work = &worker->rebind_work;
/* morph UNBOUND to REBIND */
@@ -1932,7 +1870,6 @@ __acquires(&gcwq->lock)
struct cpu_workqueue_struct *cwq = get_work_cwq(work);
struct worker_pool *pool = worker->pool;
struct global_cwq *gcwq = pool->gcwq;
- struct hlist_head *bwh = busy_worker_head(gcwq, work);
bool cpu_intensive = cwq->wq->flags & WQ_CPU_INTENSIVE;
work_func_t f = work->func;
int work_color;
@@ -1964,7 +1901,7 @@ __acquires(&gcwq->lock)
* already processing the work. If so, defer the work to the
* currently executing one.
*/
- collision = __find_worker_executing_work(gcwq, bwh, work);
+ collision = find_worker_executing_work(gcwq, work);
if (unlikely(collision)) {
move_linked_works(work, &collision->scheduled, NULL);
return;
@@ -1972,7 +1909,7 @@ __acquires(&gcwq->lock)
/* claim and process */
debug_work_deactivate(work);
- hlist_add_head(&worker->hentry, bwh);
+ hash_add(&gcwq->busy_hash, &worker->hentry, (long)work);
worker->current_work = work;
worker->current_cwq = cwq;
work_color = get_work_color(work);
@@ -2027,7 +1964,7 @@ __acquires(&gcwq->lock)
worker_clr_flags(worker, WORKER_CPU_INTENSIVE);
/* we're done with it, release */
- hlist_del_init(&worker->hentry);
+ hash_del(&worker->hentry);
worker->current_work = NULL;
worker->current_cwq = NULL;
cwq_dec_nr_in_flight(cwq, work_color, false);
@@ -3405,7 +3342,7 @@ static void gcwq_unbind_fn(struct work_struct *work)
list_for_each_entry(worker, &pool->idle_list, entry)
worker->flags |= WORKER_UNBOUND;
- for_each_busy_worker(worker, i, pos, gcwq)
+ hash_for_each(i, pos, &gcwq->busy_hash, worker, hentry)
worker->flags |= WORKER_UNBOUND;
gcwq->flags |= GCWQ_DISASSOCIATED;
@@ -3690,7 +3627,6 @@ out_unlock:
static int __init init_workqueues(void)
{
unsigned int cpu;
- int i;
cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP);
cpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN);
@@ -3704,8 +3640,7 @@ static int __init init_workqueues(void)
gcwq->cpu = cpu;
gcwq->flags |= GCWQ_DISASSOCIATED;
- for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++)
- INIT_HLIST_HEAD(&gcwq->busy_hash[i]);
+ hash_init(&gcwq->busy_hash, BUSY_WORKER_HASH_ORDER);
for_each_worker_pool(pool, gcwq) {
pool->gcwq = gcwq;
--
1.7.8.6
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [RFC v2 5/7] mm/huge_memory: use new hashtable implementation
From: Sasha Levin @ 2012-08-03 14:23 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, Sasha Levin
In-Reply-To: <1344003788-1417-1-git-send-email-levinsasha928@gmail.com>
Switch hugemem to use the new hashtable implementation. This reduces the amount of
generic unrelated code in the hugemem.
This also removes the dymanic allocation of the hash table. The size of the table is
constant so there's no point in paying the price of an extra dereference when accessing
it.
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
mm/huge_memory.c | 56 ++++++++++-------------------------------------------
1 files changed, 11 insertions(+), 45 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 57c4b93..7b2cad5 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -17,6 +17,7 @@
#include <linux/khugepaged.h>
#include <linux/freezer.h>
#include <linux/mman.h>
+#include <linux/hashtable.h>
#include <asm/tlb.h>
#include <asm/pgalloc.h>
#include "internal.h"
@@ -57,12 +58,13 @@ static DECLARE_WAIT_QUEUE_HEAD(khugepaged_wait);
static unsigned int khugepaged_max_ptes_none __read_mostly = HPAGE_PMD_NR-1;
static int khugepaged(void *none);
-static int mm_slots_hash_init(void);
static int khugepaged_slab_init(void);
static void khugepaged_slab_free(void);
-#define MM_SLOTS_HASH_HEADS 1024
-static struct hlist_head *mm_slots_hash __read_mostly;
+#define MM_SLOTS_HASH_BITS 10
+#define MM_SLOTS_HASH_CMP(mm_slot, obj) ((mm_slot)->mm == (obj))
+DEFINE_STATIC_HASHTABLE(mm_slots_hash, MM_SLOTS_HASH_BITS);
+
static struct kmem_cache *mm_slot_cache __read_mostly;
/**
@@ -140,7 +142,7 @@ static int start_khugepaged(void)
int err = 0;
if (khugepaged_enabled()) {
int wakeup;
- if (unlikely(!mm_slot_cache || !mm_slots_hash)) {
+ if (unlikely(!mm_slot_cache)) {
err = -ENOMEM;
goto out;
}
@@ -554,12 +556,6 @@ static int __init hugepage_init(void)
if (err)
goto out;
- err = mm_slots_hash_init();
- if (err) {
- khugepaged_slab_free();
- goto out;
- }
-
/*
* By default disable transparent hugepages on smaller systems,
* where the extra memory used could hurt more than TLB overhead
@@ -1562,47 +1558,17 @@ static inline void free_mm_slot(struct mm_slot *mm_slot)
kmem_cache_free(mm_slot_cache, mm_slot);
}
-static int __init mm_slots_hash_init(void)
-{
- mm_slots_hash = kzalloc(MM_SLOTS_HASH_HEADS * sizeof(struct hlist_head),
- GFP_KERNEL);
- if (!mm_slots_hash)
- return -ENOMEM;
- return 0;
-}
-
-#if 0
-static void __init mm_slots_hash_free(void)
-{
- kfree(mm_slots_hash);
- mm_slots_hash = NULL;
-}
-#endif
-
static struct mm_slot *get_mm_slot(struct mm_struct *mm)
{
- struct mm_slot *mm_slot;
- struct hlist_head *bucket;
- struct hlist_node *node;
-
- bucket = &mm_slots_hash[((unsigned long)mm / sizeof(struct mm_struct))
- % MM_SLOTS_HASH_HEADS];
- hlist_for_each_entry(mm_slot, node, bucket, hash) {
- if (mm == mm_slot->mm)
- return mm_slot;
- }
- return NULL;
+ return hash_get(&mm_slots_hash, mm, struct mm_slot,
+ hash, MM_SLOTS_HASH_CMP);
}
static void insert_to_mm_slots_hash(struct mm_struct *mm,
struct mm_slot *mm_slot)
{
- struct hlist_head *bucket;
-
- bucket = &mm_slots_hash[((unsigned long)mm / sizeof(struct mm_struct))
- % MM_SLOTS_HASH_HEADS];
mm_slot->mm = mm;
- hlist_add_head(&mm_slot->hash, bucket);
+ hash_add(&mm_slots_hash, &mm_slot->hash, (long)mm);
}
static inline int khugepaged_test_exit(struct mm_struct *mm)
@@ -1675,7 +1641,7 @@ void __khugepaged_exit(struct mm_struct *mm)
spin_lock(&khugepaged_mm_lock);
mm_slot = get_mm_slot(mm);
if (mm_slot && khugepaged_scan.mm_slot != mm_slot) {
- hlist_del(&mm_slot->hash);
+ hash_del(&mm_slot->hash);
list_del(&mm_slot->mm_node);
free = 1;
}
@@ -2089,7 +2055,7 @@ static void collect_mm_slot(struct mm_slot *mm_slot)
if (khugepaged_test_exit(mm)) {
/* free mm_slot */
- hlist_del(&mm_slot->hash);
+ hash_del(&mm_slot->hash);
list_del(&mm_slot->mm_node);
/*
--
1.7.8.6
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [RFC v2 6/7] tracepoint: use new hashtable implementation
From: Sasha Levin @ 2012-08-03 14:23 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, Sasha Levin
In-Reply-To: <1344003788-1417-1-git-send-email-levinsasha928@gmail.com>
Switch tracepoints to use the new hashtable implementation. This reduces the amount of
generic unrelated code in the tracepoints.
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
kernel/tracepoint.c | 26 +++++++++-----------------
1 files changed, 9 insertions(+), 17 deletions(-)
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index d96ba22..b5a2650 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -26,6 +26,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/static_key.h>
+#include <linux/hashtable.h>
extern struct tracepoint * const __start___tracepoints_ptrs[];
extern struct tracepoint * const __stop___tracepoints_ptrs[];
@@ -49,8 +50,7 @@ static LIST_HEAD(tracepoint_module_list);
* Protected by tracepoints_mutex.
*/
#define TRACEPOINT_HASH_BITS 6
-#define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
-static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
+DEFINE_STATIC_HASHTABLE(tracepoint_table, TRACEPOINT_HASH_BITS);
/*
* Note about RCU :
@@ -191,16 +191,14 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry,
*/
static struct tracepoint_entry *get_tracepoint(const char *name)
{
- struct hlist_head *head;
struct hlist_node *node;
struct tracepoint_entry *e;
u32 hash = jhash(name, strlen(name), 0);
- head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
- hlist_for_each_entry(e, node, head, hlist) {
+ hash_for_each_possible(&tracepoint_table, node, e, hlist, hash)
if (!strcmp(name, e->name))
return e;
- }
+
return NULL;
}
@@ -210,19 +208,13 @@ static struct tracepoint_entry *get_tracepoint(const char *name)
*/
static struct tracepoint_entry *add_tracepoint(const char *name)
{
- struct hlist_head *head;
- struct hlist_node *node;
struct tracepoint_entry *e;
size_t name_len = strlen(name) + 1;
u32 hash = jhash(name, name_len-1, 0);
- head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
- hlist_for_each_entry(e, node, head, hlist) {
- if (!strcmp(name, e->name)) {
- printk(KERN_NOTICE
- "tracepoint %s busy\n", name);
- return ERR_PTR(-EEXIST); /* Already there */
- }
+ if (get_tracepoint(name)) {
+ printk(KERN_NOTICE "tracepoint %s busy\n", name);
+ return ERR_PTR(-EEXIST); /* Already there */
}
/*
* Using kmalloc here to allocate a variable length element. Could
@@ -234,7 +226,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
memcpy(&e->name[0], name, name_len);
e->funcs = NULL;
e->refcount = 0;
- hlist_add_head(&e->hlist, head);
+ hash_add(&tracepoint_table, &e->hlist, hash);
return e;
}
@@ -244,7 +236,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
*/
static inline void remove_tracepoint(struct tracepoint_entry *e)
{
- hlist_del(&e->hlist);
+ hash_del(&e->hlist);
kfree(e);
}
--
1.7.8.6
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [RFC v2 7/7] net,9p: use new hashtable implementation
From: Sasha Levin @ 2012-08-03 14:23 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, Sasha Levin
In-Reply-To: <1344003788-1417-1-git-send-email-levinsasha928@gmail.com>
Switch 9p error table to use the new hashtable implementation. This reduces the amount of
generic unrelated code in 9p.
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
net/9p/error.c | 17 ++++++++---------
1 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/net/9p/error.c b/net/9p/error.c
index 2ab2de7..f1037db 100644
--- a/net/9p/error.c
+++ b/net/9p/error.c
@@ -34,7 +34,7 @@
#include <linux/jhash.h>
#include <linux/errno.h>
#include <net/9p/9p.h>
-
+#include <linux/hashtable.h>
/**
* struct errormap - map string errors from Plan 9 to Linux numeric ids
* @name: string sent over 9P
@@ -50,8 +50,8 @@ struct errormap {
struct hlist_node list;
};
-#define ERRHASHSZ 32
-static struct hlist_head hash_errmap[ERRHASHSZ];
+#define ERRHASHSZ 5
+DEFINE_STATIC_HASHTABLE(hash_errmap, ERRHASHSZ);
/* FixMe - reduce to a reasonable size */
static struct errormap errmap[] = {
@@ -196,15 +196,14 @@ int p9_error_init(void)
int bucket;
/* initialize hash table */
- for (bucket = 0; bucket < ERRHASHSZ; bucket++)
- INIT_HLIST_HEAD(&hash_errmap[bucket]);
+ hash_init(&hash_errmap, ERRHASHSZ);
/* load initial error map into hash table */
for (c = errmap; c->name != NULL; c++) {
c->namelen = strlen(c->name);
- bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ;
+ bucket = jhash(c->name, c->namelen, 0);
INIT_HLIST_NODE(&c->list);
- hlist_add_head(&c->list, &hash_errmap[bucket]);
+ hash_add(&hash_errmap, &c->list, bucket);
}
return 1;
@@ -228,8 +227,8 @@ int p9_errstr2errno(char *errstr, int len)
errno = 0;
p = NULL;
c = NULL;
- bucket = jhash(errstr, len, 0) % ERRHASHSZ;
- hlist_for_each_entry(c, p, &hash_errmap[bucket], list) {
+ bucket = jhash(errstr, len, 0);
+ hash_for_each_possible(&hash_errmap, p, c, list, bucket) {
if (c->namelen == len && !memcmp(c->name, errstr, len)) {
errno = c->val;
break;
--
1.7.8.6
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* Re: CPU: 0 Not tainted (3.1.9+ #1) when ifconfig rose0 down
From: folkert @ 2012-08-03 14:32 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: Bernard Pidoux, linux-hams, Linux Netdev List
In-Reply-To: <87ipd0ykdg.fsf@xmission.com>
> You might want to simply try moving unregister_netdevice_notifier a bit
> earlier in rose_exit and see if that helps. Otherwise I would recommend
> instrumenting the code up with some printk so you can understand what
> part of unregistration is failing.
Or bisect! Give e.g. the oldest 2.6 kernel a try to find a last known
good and then do a bisect upto a known bad kernel.
Folkert van Heusden
--
To MultiTail einai ena polymorfiko ergaleio gia ta logfiles kai tin
eksodo twn entolwn. Prosferei: filtrarisma, xrwmatismo, sygxwneysi,
diaforetikes provoles. http://www.vanheusden.com/multitail/
----------------------------------------------------------------------
Phone: +31-6-41278122, PGP-key: 1F28D8AE, www.vanheusden.com
^ permalink raw reply
* pull request: wireless 2012-08-03
From: John W. Linville @ 2012-08-03 14:56 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 22472 bytes --]
commit d4e5979c0da95791aa717c18e162540c7a596360
Dave,
This request covers a batch of fixes intended for the 3.6 stream.
Daniel Drake provides a pair of libertas fixes: one to avoid
unnecessary resets in order to keep the MMC layer happy; and another
to correct a couple of memory leaks.
Eliad Peller gives us a mac80211 fix for an issue that could fail to
notify userland of a completed scan.
Johannes Berg provides "a few fixes for various things [Johannes]
found doing code inspection for [his] multi-channel work".
Mohammed Shafi Shajakhan provides a simple hardware-enablement
(i.e. device ID) patch for ath9k.
Paul Stewart provides a cfg80211 fix to ensure that the presence of
beacons on a channel is recorded correctly.
Rafał Miłecki gives us a bcma device ID patch to support BCM43228
devices, and a b43 GPIO fix.
Seth Forshee provide a pair of patches to properly expose some
regulatory information needed by brcmsmac. This corrects a lockdep
issue created by a patch that is already in the tree.
Stanislaw Gruszka provides a regulatory code fix to correct an earlier
regression with the rt2x00 drivers.
Woody Hung offers an rt2x00 fix to correct a regression when resuming
an rt3290 device from S3/S4. This one seems big, but most of its
size comes from moving a function between two source files.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit e33cdac014d50dd9753e1399ae8b0b5cd98d7aa0:
ipv4: route.c cleanup (2012-08-02 02:54:43 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git tags/master-2012-08-03
for you to fetch changes up to d4e5979c0da95791aa717c18e162540c7a596360:
ath9k: Add PID/VID support for AR1111 (2012-08-03 10:11:14 -0400)
----------------------------------------------------------------
Daniel Drake (2):
libertas: don't reset card on error when it is being removed
libertas: fix two memory leaks
Eliad Peller (1):
mac80211: don't clear sched_scan_sdata on sched scan stop request
Johannes Berg (4):
mac80211: fix scan_sdata assignment
Merge remote-tracking branch 'wireless/master' into mac80211
mac80211: clear timer bits when disconnecting
mac80211: cancel mesh path timer
John W. Linville (1):
Merge branch 'for-john' of git://git.kernel.org/.../jberg/mac80211
Mohammed Shafi Shajakhan (1):
ath9k: Add PID/VID support for AR1111
Paul Stewart (1):
cfg80211: Clear "beacon_found" on regulatory restore
Rafał Miłecki (2):
bcma: BCM43228 support
b43: fix logic in GPIO init
Seth Forshee (2):
cfg80211: add channel flag to prohibit OFDM operation
brcmsmac: use channel flags to restrict OFDM
Stanislaw Gruszka (1):
wireless: reg: restore previous behaviour of chan->max_power calculations
Woody Hung (1):
rt2x00 : fix rt3290 resuming failed.
drivers/bcma/host_pci.c | 1 +
drivers/bcma/sprom.c | 4 +-
drivers/net/wireless/ath/ath9k/hw.c | 1 +
drivers/net/wireless/ath/ath9k/hw.h | 1 +
drivers/net/wireless/ath/ath9k/pci.c | 1 +
drivers/net/wireless/b43/main.c | 21 +++---
drivers/net/wireless/brcm80211/brcmsmac/channel.c | 5 +-
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 3 +-
drivers/net/wireless/libertas/cfg.c | 1 +
drivers/net/wireless/libertas/if_sdio.c | 1 +
drivers/net/wireless/libertas/main.c | 5 +-
drivers/net/wireless/rt2x00/rt2800lib.c | 68 +++++++++++++++++++
drivers/net/wireless/rt2x00/rt2800pci.c | 71 --------------------
include/linux/bcma/bcma_driver_chipcommon.h | 6 ++
include/net/cfg80211.h | 2 +
net/mac80211/mesh.c | 3 +
net/mac80211/mlme.c | 2 +
net/mac80211/scan.c | 3 +-
net/wireless/reg.c | 19 +++++-
19 files changed, 129 insertions(+), 89 deletions(-)
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index 11b32d2..a6e5672 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -272,6 +272,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
{ 0, },
};
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 26823d9..9ea4627 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -507,7 +507,9 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
/* for these chips OTP is always available */
present = true;
break;
-
+ case BCMA_CHIP_ID_BCM43228:
+ present = chip_status & BCMA_CC_CHIPST_43228_OTP_PRESENT;
+ break;
default:
present = false;
break;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index cfa91ab..60b6a9d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -730,6 +730,7 @@ int ath9k_hw_init(struct ath_hw *ah)
case AR9300_DEVID_QCA955X:
case AR9300_DEVID_AR9580:
case AR9300_DEVID_AR9462:
+ case AR9485_DEVID_AR1111:
break;
default:
if (common->bus_ops->ath_bus_type == ATH_USB)
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index dd0c146..ce7332c 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -49,6 +49,7 @@
#define AR9300_DEVID_AR9462 0x0034
#define AR9300_DEVID_AR9330 0x0035
#define AR9300_DEVID_QCA955X 0x0038
+#define AR9485_DEVID_AR1111 0x0037
#define AR5416_AR9100_DEVID 0x000b
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 87b89d5..d455de9 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -37,6 +37,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
{ PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */
{ PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */
{ PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */
+ { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */
{ 0 }
};
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index b80352b..a140165 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2719,32 +2719,37 @@ static int b43_gpio_init(struct b43_wldev *dev)
if (dev->dev->chip_id == 0x4301) {
mask |= 0x0060;
set |= 0x0060;
+ } else if (dev->dev->chip_id == 0x5354) {
+ /* Don't allow overtaking buttons GPIOs */
+ set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */
}
- if (dev->dev->chip_id == 0x5354)
- set &= 0xff02;
+
if (0 /* FIXME: conditional unknown */ ) {
b43_write16(dev, B43_MMIO_GPIO_MASK,
b43_read16(dev, B43_MMIO_GPIO_MASK)
| 0x0100);
- mask |= 0x0180;
- set |= 0x0180;
+ /* BT Coexistance Input */
+ mask |= 0x0080;
+ set |= 0x0080;
+ /* BT Coexistance Out */
+ mask |= 0x0100;
+ set |= 0x0100;
}
if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) {
+ /* PA is controlled by gpio 9, let ucode handle it */
b43_write16(dev, B43_MMIO_GPIO_MASK,
b43_read16(dev, B43_MMIO_GPIO_MASK)
| 0x0200);
mask |= 0x0200;
set |= 0x0200;
}
- if (dev->dev->core_rev >= 2)
- mask |= 0x0010; /* FIXME: This is redundant. */
switch (dev->dev->bus_type) {
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL,
(bcma_cc_read32(&dev->dev->bdev->bus->drv_cc,
- BCMA_CC_GPIOCTL) & mask) | set);
+ BCMA_CC_GPIOCTL) & ~mask) | set);
break;
#endif
#ifdef CONFIG_B43_SSB
@@ -2753,7 +2758,7 @@ static int b43_gpio_init(struct b43_wldev *dev)
if (gpiodev)
ssb_write32(gpiodev, B43_GPIO_CONTROL,
(ssb_read32(gpiodev, B43_GPIO_CONTROL)
- & mask) | set);
+ & ~mask) | set);
break;
#endif
}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
index 9a4c63f..7ed7d75 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
@@ -382,9 +382,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
{
struct brcms_c_info *wlc = wlc_cm->wlc;
struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel;
- const struct ieee80211_reg_rule *reg_rule;
struct txpwr_limits txpwr;
- int ret;
brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr);
@@ -393,8 +391,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
);
/* set or restore gmode as required by regulatory */
- ret = freq_reg_info(wlc->wiphy, ch->center_freq, 0, ®_rule);
- if (!ret && (reg_rule->flags & NL80211_RRF_NO_OFDM))
+ if (ch->flags & IEEE80211_CHAN_NO_OFDM)
brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false);
else
brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 9e79d47..192ad5c 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -121,7 +121,8 @@ static struct ieee80211_channel brcms_2ghz_chantable[] = {
IEEE80211_CHAN_NO_HT40PLUS),
CHAN2GHZ(14, 2484,
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
- IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
+ IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS |
+ IEEE80211_CHAN_NO_OFDM)
};
static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index eb5de80..1c10b54 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -1254,6 +1254,7 @@ static int lbs_associate(struct lbs_private *priv,
netif_tx_wake_all_queues(priv->dev);
}
+ kfree(cmd);
done:
lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
return ret;
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 76caeba..e970897 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -1314,6 +1314,7 @@ static void if_sdio_remove(struct sdio_func *func)
kfree(packet);
}
+ kfree(card);
lbs_deb_leave(LBS_DEB_SDIO);
}
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 5804818..fe1ea43 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -571,7 +571,10 @@ static int lbs_thread(void *data)
netdev_info(dev, "Timeout submitting command 0x%04x\n",
le16_to_cpu(cmdnode->cmdbuf->command));
lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
- if (priv->reset_card)
+
+ /* Reset card, but only when it isn't in the process
+ * of being shutdown anyway. */
+ if (!dev->dismantle && priv->reset_card)
priv->reset_card(priv);
}
priv->cmd_timed_out = 0;
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 88455b1..cb8c2ac 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -221,6 +221,67 @@ static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev,
mutex_unlock(&rt2x00dev->csr_mutex);
}
+static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+ int i, count;
+
+ rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®);
+ if (rt2x00_get_field32(reg, WLAN_EN))
+ return 0;
+
+ rt2x00_set_field32(®, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff);
+ rt2x00_set_field32(®, FRC_WL_ANT_SET, 1);
+ rt2x00_set_field32(®, WLAN_CLK_EN, 0);
+ rt2x00_set_field32(®, WLAN_EN, 1);
+ rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
+
+ udelay(REGISTER_BUSY_DELAY);
+
+ count = 0;
+ do {
+ /*
+ * Check PLL_LD & XTAL_RDY.
+ */
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2800_register_read(rt2x00dev, CMB_CTRL, ®);
+ if (rt2x00_get_field32(reg, PLL_LD) &&
+ rt2x00_get_field32(reg, XTAL_RDY))
+ break;
+ udelay(REGISTER_BUSY_DELAY);
+ }
+
+ if (i >= REGISTER_BUSY_COUNT) {
+
+ if (count >= 10)
+ return -EIO;
+
+ rt2800_register_write(rt2x00dev, 0x58, 0x018);
+ udelay(REGISTER_BUSY_DELAY);
+ rt2800_register_write(rt2x00dev, 0x58, 0x418);
+ udelay(REGISTER_BUSY_DELAY);
+ rt2800_register_write(rt2x00dev, 0x58, 0x618);
+ udelay(REGISTER_BUSY_DELAY);
+ count++;
+ } else {
+ count = 0;
+ }
+
+ rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®);
+ rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 0);
+ rt2x00_set_field32(®, WLAN_CLK_EN, 1);
+ rt2x00_set_field32(®, WLAN_RESET, 1);
+ rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
+ udelay(10);
+ rt2x00_set_field32(®, WLAN_RESET, 0);
+ rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
+ udelay(10);
+ rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff);
+ } while (count != 0);
+
+ return 0;
+}
+
void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
const u8 command, const u8 token,
const u8 arg0, const u8 arg1)
@@ -400,6 +461,13 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
{
unsigned int i;
u32 reg;
+ int retval;
+
+ if (rt2x00_rt(rt2x00dev, RT3290)) {
+ retval = rt2800_enable_wlan_rt3290(rt2x00dev);
+ if (retval)
+ return -EBUSY;
+ }
/*
* If driver doesn't wake up firmware here,
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 235376e..98aa426 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -980,66 +980,6 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
return rt2800_validate_eeprom(rt2x00dev);
}
-static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
-{
- u32 reg;
- int i, count;
-
- rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®);
- if (rt2x00_get_field32(reg, WLAN_EN))
- return 0;
-
- rt2x00_set_field32(®, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff);
- rt2x00_set_field32(®, FRC_WL_ANT_SET, 1);
- rt2x00_set_field32(®, WLAN_CLK_EN, 0);
- rt2x00_set_field32(®, WLAN_EN, 1);
- rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
-
- udelay(REGISTER_BUSY_DELAY);
-
- count = 0;
- do {
- /*
- * Check PLL_LD & XTAL_RDY.
- */
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2800_register_read(rt2x00dev, CMB_CTRL, ®);
- if (rt2x00_get_field32(reg, PLL_LD) &&
- rt2x00_get_field32(reg, XTAL_RDY))
- break;
- udelay(REGISTER_BUSY_DELAY);
- }
-
- if (i >= REGISTER_BUSY_COUNT) {
-
- if (count >= 10)
- return -EIO;
-
- rt2800_register_write(rt2x00dev, 0x58, 0x018);
- udelay(REGISTER_BUSY_DELAY);
- rt2800_register_write(rt2x00dev, 0x58, 0x418);
- udelay(REGISTER_BUSY_DELAY);
- rt2800_register_write(rt2x00dev, 0x58, 0x618);
- udelay(REGISTER_BUSY_DELAY);
- count++;
- } else {
- count = 0;
- }
-
- rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®);
- rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 0);
- rt2x00_set_field32(®, WLAN_CLK_EN, 1);
- rt2x00_set_field32(®, WLAN_RESET, 1);
- rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
- udelay(10);
- rt2x00_set_field32(®, WLAN_RESET, 0);
- rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
- udelay(10);
- rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff);
- } while (count != 0);
-
- return 0;
-}
static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
@@ -1063,17 +1003,6 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
return retval;
/*
- * In probe phase call rt2800_enable_wlan_rt3290 to enable wlan
- * clk for rt3290. That avoid the MCU fail in start phase.
- */
- if (rt2x00_rt(rt2x00dev, RT3290)) {
- retval = rt2800_enable_wlan_rt3290(rt2x00dev);
-
- if (retval)
- return retval;
- }
-
- /*
* This device has multiple filters for control frames
* and has a separate filter for PS Poll frames.
*/
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index 3c80885..d323a4b 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -89,6 +89,12 @@
#define BCMA_CC_CHIPST_4313_OTP_PRESENT 2
#define BCMA_CC_CHIPST_4331_SPROM_PRESENT 2
#define BCMA_CC_CHIPST_4331_OTP_PRESENT 4
+#define BCMA_CC_CHIPST_43228_ILP_DIV_EN 0x00000001
+#define BCMA_CC_CHIPST_43228_OTP_PRESENT 0x00000002
+#define BCMA_CC_CHIPST_43228_SERDES_REFCLK_PADSEL 0x00000004
+#define BCMA_CC_CHIPST_43228_SDIO_MODE 0x00000008
+#define BCMA_CC_CHIPST_43228_SDIO_OTP_PRESENT 0x00000010
+#define BCMA_CC_CHIPST_43228_SDIO_RESET 0x00000020
#define BCMA_CC_CHIPST_4706_PKG_OPTION BIT(0) /* 0: full-featured package 1: low-cost package */
#define BCMA_CC_CHIPST_4706_SFLASH_PRESENT BIT(1) /* 0: parallel, 1: serial flash is present */
#define BCMA_CC_CHIPST_4706_SFLASH_TYPE BIT(2) /* 0: 8b-p/ST-s flash, 1: 16b-p/Atmal-s flash */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 493fa0c..3d254e1 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -96,6 +96,7 @@ enum ieee80211_band {
* is not permitted.
* @IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel
* is not permitted.
+ * @IEEE80211_CHAN_NO_OFDM: OFDM is not allowed on this channel.
*/
enum ieee80211_channel_flags {
IEEE80211_CHAN_DISABLED = 1<<0,
@@ -104,6 +105,7 @@ enum ieee80211_channel_flags {
IEEE80211_CHAN_RADAR = 1<<3,
IEEE80211_CHAN_NO_HT40PLUS = 1<<4,
IEEE80211_CHAN_NO_HT40MINUS = 1<<5,
+ IEEE80211_CHAN_NO_OFDM = 1<<6,
};
#define IEEE80211_CHAN_NO_HT40 \
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 6fac18c..8557235 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -622,6 +622,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
del_timer_sync(&sdata->u.mesh.housekeeping_timer);
del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
+ del_timer_sync(&sdata->u.mesh.mesh_path_timer);
/*
* If the timer fired while we waited for it, it will have
* requeued the work. Now the work will be running again
@@ -634,6 +635,8 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
local->fif_other_bss--;
atomic_dec(&local->iff_allmultis);
ieee80211_configure_filter(local);
+
+ sdata->u.mesh.timers_running = 0;
}
static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index cef0c9e..a4a5acd 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1430,6 +1430,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
del_timer_sync(&sdata->u.mgd.timer);
del_timer_sync(&sdata->u.mgd.chswitch_timer);
+
+ sdata->u.mgd.timers_running = 0;
}
void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index bcaee5d..839dd97 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -299,7 +299,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
if (local->scan_req != local->int_scan_req)
cfg80211_scan_done(local->scan_req, aborted);
local->scan_req = NULL;
- local->scan_sdata = NULL;
+ rcu_assign_pointer(local->scan_sdata, NULL);
local->scanning = 0;
local->scan_channel = NULL;
@@ -984,7 +984,6 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
kfree(local->sched_scan_ies.ie[i]);
drv_sched_scan_stop(local, sdata);
- rcu_assign_pointer(local->sched_scan_sdata, NULL);
}
out:
mutex_unlock(&local->mtx);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 2303ee7..2ded3c7 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -680,6 +680,8 @@ static u32 map_regdom_flags(u32 rd_flags)
channel_flags |= IEEE80211_CHAN_NO_IBSS;
if (rd_flags & NL80211_RRF_DFS)
channel_flags |= IEEE80211_CHAN_RADAR;
+ if (rd_flags & NL80211_RRF_NO_OFDM)
+ channel_flags |= IEEE80211_CHAN_NO_OFDM;
return channel_flags;
}
@@ -901,7 +903,21 @@ static void handle_channel(struct wiphy *wiphy,
chan->max_antenna_gain = min(chan->orig_mag,
(int) MBI_TO_DBI(power_rule->max_antenna_gain));
chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
- chan->max_power = min(chan->max_power, chan->max_reg_power);
+ if (chan->orig_mpwr) {
+ /*
+ * Devices that have their own custom regulatory domain
+ * but also use WIPHY_FLAG_STRICT_REGULATORY will follow the
+ * passed country IE power settings.
+ */
+ if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
+ wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY &&
+ wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
+ chan->max_power = chan->max_reg_power;
+ else
+ chan->max_power = min(chan->orig_mpwr,
+ chan->max_reg_power);
+ } else
+ chan->max_power = chan->max_reg_power;
}
static void handle_band(struct wiphy *wiphy,
@@ -1885,6 +1901,7 @@ static void restore_custom_reg_settings(struct wiphy *wiphy)
chan->flags = chan->orig_flags;
chan->max_antenna_gain = chan->orig_mag;
chan->max_power = chan->orig_mpwr;
+ chan->beacon_found = false;
}
}
}
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related
* Re: skb_warn_bad_offload with kernel 3.5 (maybe gso/bridge related ?)
From: Ben Hutchings @ 2012-08-03 15:40 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Yann Dupont, netdev@vger.kernel.org, Herbert Xu
In-Reply-To: <1343983887.9299.817.camel@edumazet-glaptop>
On Fri, 2012-08-03 at 10:51 +0200, Eric Dumazet wrote:
> On Fri, 2012-08-03 at 10:10 +0200, Yann Dupont wrote:
> > Hello everybody,
> >
> > I have a machine using ceph rbd volume, as a client (rbd module) to
> > backup data.
> >
> > I was running kernel 3.2.22 ok. Tried 3.5.0 because some rbd fixes went in.
> >
> > Now, shortly after the start, my logs are filled by that :
> >
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.780860]
> > WARNING: at net/core/dev.c:1888 skb_warn_bad_offload+0xb6/0xc1()
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.780920]
> > Hardware name: PowerEdge M605
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.780990] :
> > caps=(0x0000000000005000, 0x0000000000000000) len=7292 data_len=5792
> > gso_size=1448 gso_type=1 ip_summed=1
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.781071]
> > Modules linked in: rbd libceph ipt_MASQUERADE iptable_nat nf_nat
> > ipt_REJECT veth fuse xt_physdev xt_iprange xt_multiport ip6table_filter
> > ip6_tables xt_LOG xt_limit xt_tcpudp xt_state iptable_filter ip_tables
> > x_tables nf_conntrack_tftp nf_conntrack_ftp nf_conntrack_ipv4
> > nf_defrag_ipv4 8021q bridge stp llc ext2 mbcache dm_round_robin
> > dm_multipath scsi_dh nf_conntrack_ipv6 nf_conntrack nf_defrag_ipv6 ipv6
> > powernow_k8 freq_table mperf kvm_amd snd_pcm kvm snd_timer snd soundcore
> > snd_page_alloc tpm_tis tpm tpm_bios pcspkr evdev psmouse microcode
> > joydev dcdbas shpchp i2c_nforce2 pci_hotplug serio_raw processor
> > i2c_core hid_generic thermal_sys hed button xfs exportfs dm_mod ses
> > enclosure usbhid hid sg sr_mod sd_mod cdrom usb_storage lpfc
> > scsi_transport_fc scsi_tgt ohci_hcd bnx2x mptsas mptscsih bnx2 mptbase
> > scsi_transport_sas crc32c scsi_mod libcrc32c mdio ehci_hcd [last
> > unloaded: scsi_wait_scan]
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.785995]
> > Pid: 0, comm: swapper/0 Not tainted 3.5.0-dsiun-120521 #5
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.786055]
> > Call Trace:
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.786108]
> > <IRQ> [<ffffffff813bde00>] ? skb_warn_bad_offload+0x6f/0xc1
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.786209]
> > [<ffffffff8103a109>] ? warn_slowpath_common+0x79/0xc0
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.786269]
> > [<ffffffff8103a205>] ? warn_slowpath_fmt+0x45/0x50
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.786330]
> > [<ffffffff81068647>] ? get_nohz_timer_target+0x57/0xd0
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.786390]
> > [<ffffffff813bde47>] ? skb_warn_bad_offload+0xb6/0xc1
> > Jul 31 18:15:01 singleton.u06.univ-nantes.prive kernel: [ 1175.786452]
> > [<ffffffff813110e7>] ? skb_gso_segment+0x207/0x280
[...]
> I dont know, maybe its more a GRO issue ?
>
> When a NIC delivers skbs with ip_summed set to CHECKSUM_UNNECESSARY,
> should resulting GRO packet have ip_summed set to CHECKSUM_PARTIAL ?
I think GRO is doing the right thing, and I can't think why we should
see ip_summed = CHECKSUM_PARTIAL if the skb is forwarded by a bridge. I
think skb_gso_segment() now needs to handle CHECKSUM_UNNECESSARY
without warning, and it can be done somewhat more efficiently (as there
is no need to copy payload and generate checksums).
By the way, the warning in skb_gso_segment() is not new, even though I
changed it recently. I don't know why it might have started being
triggered between 3.2 and 3.5.
Ben.
--
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
* [REGRESSION][v3.5] iwlwifi: include rssi as part of decision making for reduce txpower
From: Joseph Salisbury @ 2012-08-03 16:24 UTC (permalink / raw)
To: wey-yi.w.guy-ral2JQCrhuEAvxtiuMwx3w,
johannes.berg-ral2JQCrhuEAvxtiuMwx3w, ilw-VuQAYsv1563Yd54FQh9/CA,
linville-2XuSBdqkA4R54TAoqtyWWQ,
emmanuel.grumbach-ral2JQCrhuEAvxtiuMwx3w
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Hello,
A bug[0] was reported against Ubuntu that reports a kernel panic when
using the hotkey to disable then re-enable wifi on a Dell XPS 14z. A
kernel bisect was performed, which indicated the following commit as the
source of the regression:
commit dd551ab7b47ace14753b0d73f79437cc35adcf6b
Author: Wey-Yi Guy <wey-yi.w.guy-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Thu May 3 14:22:01 2012 -0700
iwlwifi: include rssi as part of decision making for reduce txpower
In bt coex, consider the average rssi as part of decision making
process
Change-Id: I8d11d7f177a6875e2a9d08f7539d42253226fd7a
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Reviewed-on: http://git-mwg.jer.intel.com/gerrit/1945
Tested-by: Jenkins
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Signed-off-by: John W. Linville <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
A test kernel was created with this commit reverted, which stopped the
kernel panic from occurring.
A bugzilla bug[1] has been opened.
Thanks,
Joe
[0] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1029547
[1] https://bugzilla.kernel.org/show_bug.cgi?id=45491
--
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: [REGRESSION][v3.5] iwlwifi: include rssi as part of decision making for reduce txpower
From: Johannes Berg @ 2012-08-03 16:30 UTC (permalink / raw)
To: Joseph Salisbury
Cc: wey-yi.w.guy, ilw, linville, emmanuel.grumbach, linux-wireless,
netdev, linux-kernel
In-Reply-To: <501BFB29.7010801@canonical.com>
On Fri, 2012-08-03 at 12:24 -0400, Joseph Salisbury wrote:
> A test kernel was created with this commit reverted, which stopped the
> kernel panic from occurring.
>
> A bugzilla bug[1] has been opened.
> [0] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1029547
> [1] https://bugzilla.kernel.org/show_bug.cgi?id=45491
This is a duplicate of https://bugzilla.kernel.org/show_bug.cgi?id=45481
which I've already commented on with the correct fix. I've also sent the
fix to stable:
http://www.mail-archive.com/stable@vger.kernel.org/msg12286.html
Thanks,
johannes
^ permalink raw reply
* Re: [REGRESSION][v3.5] iwlwifi: include rssi as part of decision making for reduce txpower
From: Joseph Salisbury @ 2012-08-03 16:43 UTC (permalink / raw)
To: Johannes Berg
Cc: wey-yi.w.guy, ilw, linville, emmanuel.grumbach, linux-wireless,
netdev, linux-kernel
In-Reply-To: <1344011416.4482.11.camel@jlt3.sipsolutions.net>
On 08/03/2012 12:30 PM, Johannes Berg wrote:
> On Fri, 2012-08-03 at 12:24 -0400, Joseph Salisbury wrote:
>
>> A test kernel was created with this commit reverted, which stopped the
>> kernel panic from occurring.
>>
>> A bugzilla bug[1] has been opened.
>> [0] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1029547
>> [1] https://bugzilla.kernel.org/show_bug.cgi?id=45491
> This is a duplicate of https://bugzilla.kernel.org/show_bug.cgi?id=45481
> which I've already commented on with the correct fix. I've also sent the
> fix to stable:
>
> http://www.mail-archive.com/stable@vger.kernel.org/msg12286.html
>
> Thanks,
> johannes
>
Great! Thanks for the feedback, Johannes.
^ permalink raw reply
* Re: [RFC v2 1/7] hashtable: introduce a small and naive hashtable
From: Tejun Heo @ 2012-08-03 17:15 UTC (permalink / raw)
To: Sasha Levin
Cc: torvalds, akpm, linux-kernel, linux-mm, paul.gortmaker, davem,
rostedt, mingo, ebiederm, aarcange, ericvh, netdev
In-Reply-To: <1344003788-1417-2-git-send-email-levinsasha928@gmail.com>
Hello, Sasha.
On Fri, Aug 03, 2012 at 04:23:02PM +0200, Sasha Levin wrote:
> +#define DEFINE_STATIC_HASHTABLE(n, b) \
> + static struct hash_table n = { .bits = (b), \
> + .buckets = { [0 ... ((1 << (b)) - 1)] = HLIST_HEAD_INIT } }
What does this "static" mean?
> +#define DEFINE_HASHTABLE(n, b) \
> + union { \
> + struct hash_table n; \
> + struct { \
> + size_t bits; \
> + struct hlist_head buckets[1 << (b)]; \
> + } __##n ; \
> + };
Is this supposed to be embedded in struct definition? If so, the name
is rather misleading as DEFINE_* is supposed to define and initialize
stand-alone constructs. Also, for struct members, simply putting hash
entries after struct hash_table should work.
Wouldn't using DEFINE_HASHTABLE() for the first macro and
DEFINE_HASHTABLE_MEMBER() for the latter be better?
> +#define HASH_BITS(name) ((name)->bits)
> +#define HASH_SIZE(name) (1 << (HASH_BITS(name)))
> +
> +__attribute__ ((unused))
Are we using __attribute__((unused)) for functions defined in headers
instead of static inline now? If so, why?
> +static void hash_init(struct hash_table *ht, size_t bits)
> +{
> + size_t i;
I would prefer int here but no biggie.
> + ht->bits = bits;
> + for (i = 0; i < (1 << bits); i++)
> + INIT_HLIST_HEAD(&ht->buckets[i]);
> +}
> +
> +static void hash_add(struct hash_table *ht, struct hlist_node *node, long key)
> +{
> + hlist_add_head(node,
> + &ht->buckets[hash_long((unsigned long)key, HASH_BITS(ht))]);
> +}
> +
> +
> +#define hash_get(name, key, type, member, cmp_fn) \
> +({ \
> + struct hlist_node *__node; \
> + typeof(key) __key = key; \
> + type *__obj = NULL; \
> + hlist_for_each_entry(__obj, __node, &(name)->buckets[ \
> + hash_long((unsigned long) __key, \
> + HASH_BITS(name))], member) \
> + if (cmp_fn(__obj, __key)) \
> + break; \
> + __obj; \
> +})
As opposed to using hash_for_each_possible(), how much difference does
this make? Is it really worthwhile?
Thanks.
--
tejun
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [RFC v2 1/7] hashtable: introduce a small and naive hashtable
From: Tejun Heo @ 2012-08-03 17:16 UTC (permalink / raw)
To: Sasha Levin
Cc: torvalds, akpm, linux-kernel, linux-mm, paul.gortmaker, davem,
rostedt, mingo, ebiederm, aarcange, ericvh, netdev
In-Reply-To: <20120803171515.GH15477@google.com>
Ooh, one more thing. Comments please.
--
tejun
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [RFC v2 1/7] hashtable: introduce a small and naive hashtable
From: Eric Dumazet @ 2012-08-03 17:39 UTC (permalink / raw)
To: Sasha Levin
Cc: torvalds, tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem,
rostedt, mingo, ebiederm, aarcange, ericvh, netdev
In-Reply-To: <1344003788-1417-2-git-send-email-levinsasha928@gmail.com>
On Fri, 2012-08-03 at 16:23 +0200, Sasha Levin wrote:
> This hashtable implementation is using hlist buckets to provide a simple
> hashtable to prevent it from getting reimplemented all over the kernel.
>
> +static void hash_add(struct hash_table *ht, struct hlist_node *node, long key)
> +{
> + hlist_add_head(node,
> + &ht->buckets[hash_long((unsigned long)key, HASH_BITS(ht))]);
> +}
> +
Why key is a long, casted later to "unsigned long" ?
hash_long() is expensive on 64bit arches, and not really needed
if key is an u32 from the beginning ( I am referring to your patches 6 &
7 using jhash() )
Maybe you could use a macro, so that we can automatically select
hash_32() if key is an u32, and hash_long() for other types.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ 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