* [PATCH v2 06/16] tracepoint: use new hashtable implementation
From: Sasha Levin @ 2012-08-19 0:52 UTC (permalink / raw)
To: torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b
Cc: snitzer-H+wXaHxf7aLQT0dZR+AlfA, neilb-l3A5Bk7waGM,
fweisbec-Re5JQEeQqe8AvxtiuMwx3w,
Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
bfields-uC3wQj2KruNg9hUCZPvPmw,
paul.gortmaker-CWA4WttNNZF54TAoqtyWWQ,
dm-devel-H+wXaHxf7aLQT0dZR+AlfA, agk-H+wXaHxf7aLQT0dZR+AlfA,
aarcange-H+wXaHxf7aLQT0dZR+AlfA, rds-devel-N0ozoZBvEnrZJqsBc5GL+g,
eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
venkat.x.venkatsubra-QHcLZuEGTsvQT0dZR+AlfA,
ccaulfie-H+wXaHxf7aLQT0dZR+AlfA, mingo-X9Un+BFzKDI,
dev-yBygre7rU0TnMu66kgdUjQ, ericvh-Re5JQEeQqe8AvxtiuMwx3w,
josh-iaAMLnmF4UmaiuxdJuQwMA, rostedt-nx8X9YLhiw1AfugRpC6u6w,
lw-BthXqXjhjHXQFUHtdCDX3A,
mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w, Sasha Levin,
axboe-tSWWG44O7X1aa/9Udqfwiw, linux-nfs-u79uwXL29TY76Z2rM5mHXA,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, ejt-H+wXaHxf7aLQT0dZR+AlfA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, tj-DgEjT+Ai2ygdnm+yROfE0A,
teigland-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <1345337550-24304-1-git-send-email-levinsasha928-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
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-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
kernel/tracepoint.c | 27 +++++++++++----------------
1 files changed, 11 insertions(+), 16 deletions(-)
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index d96ba22..854df92 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];
+static DEFINE_HASHTABLE(tracepoint_table, TRACEPOINT_HASH_BITS);
/*
* Note about RCU :
@@ -191,16 +191,15 @@ 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, e, node, hlist, hash) {
if (!strcmp(name, e->name))
return e;
}
+
return NULL;
}
@@ -210,19 +209,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 +227,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 +237,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);
}
@@ -722,6 +715,8 @@ struct notifier_block tracepoint_module_nb = {
static int init_tracepoints(void)
{
+ hash_init(tracepoint_table);
+
return register_module_notifier(&tracepoint_module_nb);
}
__initcall(init_tracepoints);
--
1.7.8.6
^ permalink raw reply related
* [PATCH v2 05/16] mm/huge_memory: use new hashtable implementation
From: Sasha Levin @ 2012-08-19 0:52 UTC (permalink / raw)
To: torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b
Cc: snitzer-H+wXaHxf7aLQT0dZR+AlfA, neilb-l3A5Bk7waGM,
fweisbec-Re5JQEeQqe8AvxtiuMwx3w,
Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
bfields-uC3wQj2KruNg9hUCZPvPmw,
paul.gortmaker-CWA4WttNNZF54TAoqtyWWQ,
dm-devel-H+wXaHxf7aLQT0dZR+AlfA, agk-H+wXaHxf7aLQT0dZR+AlfA,
aarcange-H+wXaHxf7aLQT0dZR+AlfA, rds-devel-N0ozoZBvEnrZJqsBc5GL+g,
eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
venkat.x.venkatsubra-QHcLZuEGTsvQT0dZR+AlfA,
ccaulfie-H+wXaHxf7aLQT0dZR+AlfA, mingo-X9Un+BFzKDI,
dev-yBygre7rU0TnMu66kgdUjQ, ericvh-Re5JQEeQqe8AvxtiuMwx3w,
josh-iaAMLnmF4UmaiuxdJuQwMA, rostedt-nx8X9YLhiw1AfugRpC6u6w,
lw-BthXqXjhjHXQFUHtdCDX3A,
mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w, Sasha Levin,
axboe-tSWWG44O7X1aa/9Udqfwiw, linux-nfs-u79uwXL29TY76Z2rM5mHXA,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, ejt-H+wXaHxf7aLQT0dZR+AlfA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, tj-DgEjT+Ai2ygdnm+yROfE0A,
teigland-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <1345337550-24304-1-git-send-email-levinsasha928-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
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-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
mm/huge_memory.c | 57 ++++++++++++++---------------------------------------
1 files changed, 15 insertions(+), 42 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 8b3c55a..cebe345 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,12 @@ 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
+static DEFINE_HASHTABLE(mm_slots_hash, MM_SLOTS_HASH_BITS);
+
static struct kmem_cache *mm_slot_cache __read_mostly;
/**
@@ -140,7 +141,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 +555,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
@@ -1540,6 +1535,8 @@ static int __init khugepaged_slab_init(void)
if (!mm_slot_cache)
return -ENOMEM;
+ hash_init(mm_slots_hash);
+
return 0;
}
@@ -1561,47 +1558,23 @@ 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 mm_slot *slot;
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;
- }
+ hash_for_each_possible(mm_slots_hash, slot, node, hash, (unsigned long) mm)
+ if (slot->mm == mm)
+ return slot;
+
return NULL;
}
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)
@@ -1670,7 +1643,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;
}
@@ -2080,7 +2053,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
^ permalink raw reply related
* [PATCH v2 04/16] workqueue: use new hashtable implementation
From: Sasha Levin @ 2012-08-19 0:52 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, josh, eric.dumazet,
mathieu.desnoyers, axboe, agk, dm-devel, neilb, ccaulfie,
teigland, Trond.Myklebust, bfields, fweisbec, jesse,
venkat.x.venkatsubra, ejt, snitzer, edumazet, linux-nfs, dev,
rds-devel, lw, Sasha Levin
In-Reply-To: <1345337550-24304-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 | 86 +++++++++-------------------------------------------
1 files changed, 15 insertions(+), 71 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 11723c5..fca751e 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 */
@@ -180,7 +179,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 */
@@ -288,8 +287,7 @@ EXPORT_SYMBOL_GPL(system_nrt_freezable_wq);
(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)
+ hash_for_each(gcwq->busy_hash, i, pos, worker, hentry)
static inline int __next_gcwq_cpu(int cpu, const struct cpumask *mask,
unsigned int sw)
@@ -845,63 +843,6 @@ 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
@@ -920,8 +861,14 @@ 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);
+ struct worker *worker;
+ struct hlist_node *tmp;
+
+ hash_for_each_possible(gcwq->busy_hash, worker, tmp, hentry, (unsigned long)work)
+ if (worker->current_work == work)
+ return worker;
+
+ return NULL;
}
/**
@@ -2120,7 +2067,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;
@@ -2152,7 +2098,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;
@@ -2160,7 +2106,7 @@ __acquires(&gcwq->lock)
/* claim and dequeue */
debug_work_deactivate(work);
- hlist_add_head(&worker->hentry, bwh);
+ hash_add(gcwq->busy_hash, &worker->hentry, (unsigned long)worker);
worker->current_work = work;
worker->current_cwq = cwq;
work_color = get_work_color(work);
@@ -2223,7 +2169,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);
@@ -3855,7 +3801,6 @@ out_unlock:
static int __init init_workqueues(void)
{
unsigned int cpu;
- int i;
/* make sure we have enough bits for OFFQ CPU number */
BUILD_BUG_ON((1LU << (BITS_PER_LONG - WORK_OFFQ_CPU_SHIFT)) <
@@ -3873,8 +3818,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);
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
* [PATCH v2 03/16] mm, ksm: use new hashtable implementation
From: Sasha Levin @ 2012-08-19 0:52 UTC (permalink / raw)
To: torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b
Cc: snitzer-H+wXaHxf7aLQT0dZR+AlfA, neilb-l3A5Bk7waGM,
fweisbec-Re5JQEeQqe8AvxtiuMwx3w,
Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
bfields-uC3wQj2KruNg9hUCZPvPmw,
paul.gortmaker-CWA4WttNNZF54TAoqtyWWQ,
dm-devel-H+wXaHxf7aLQT0dZR+AlfA, agk-H+wXaHxf7aLQT0dZR+AlfA,
aarcange-H+wXaHxf7aLQT0dZR+AlfA, rds-devel-N0ozoZBvEnrZJqsBc5GL+g,
eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
venkat.x.venkatsubra-QHcLZuEGTsvQT0dZR+AlfA,
ccaulfie-H+wXaHxf7aLQT0dZR+AlfA, mingo-X9Un+BFzKDI,
dev-yBygre7rU0TnMu66kgdUjQ, ericvh-Re5JQEeQqe8AvxtiuMwx3w,
josh-iaAMLnmF4UmaiuxdJuQwMA, rostedt-nx8X9YLhiw1AfugRpC6u6w,
lw-BthXqXjhjHXQFUHtdCDX3A,
mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w, Sasha Levin,
axboe-tSWWG44O7X1aa/9Udqfwiw, linux-nfs-u79uwXL29TY76Z2rM5mHXA,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, ejt-H+wXaHxf7aLQT0dZR+AlfA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, tj-DgEjT+Ai2ygdnm+yROfE0A,
teigland-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <1345337550-24304-1-git-send-email-levinsasha928-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
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-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
mm/ksm.c | 33 +++++++++++++++------------------
1 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/mm/ksm.c b/mm/ksm.c
index 9638620..dd4d6af 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>
@@ -156,9 +156,8 @@ struct rmap_item {
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_SLOTS_HASH_BITS 10
+static DEFINE_HASHTABLE(mm_slots_hash, MM_SLOTS_HASH_BITS);
static struct mm_slot ksm_mm_head = {
.mm_list = LIST_HEAD_INIT(ksm_mm_head.mm_list),
@@ -275,26 +274,21 @@ 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;
+ struct mm_slot *slot;
+
+ hash_for_each_possible(mm_slots_hash, slot, node, link, (unsigned long)mm)
+ if (slot->mm == mm)
+ return slot;
- 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;
}
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, (unsigned long)mm);
}
static inline int in_stable_tree(struct rmap_item *rmap_item)
@@ -647,7 +641,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 +1379,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);
@@ -1552,7 +1546,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 {
@@ -2028,6 +2022,9 @@ static int __init ksm_init(void)
*/
hotplug_memory_notifier(ksm_memory_callback, 100);
#endif
+
+ hash_init(mm_slots_hash);
+
return 0;
out_free:
--
1.7.8.6
^ permalink raw reply related
* [PATCH v2 02/16] userns: use new hashtable implementation
From: Sasha Levin @ 2012-08-19 0:52 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, josh, eric.dumazet,
mathieu.desnoyers, axboe, agk, dm-devel, neilb, ccaulfie,
teigland, Trond.Myklebust, bfields, fweisbec, jesse,
venkat.x.venkatsubra, ejt, snitzer, edumazet, linux-nfs, dev,
rds-devel, lw, Sasha Levin
In-Reply-To: <1345337550-24304-1-git-send-email-levinsasha928@gmail.com>
Switch to using the new hashtable implementation to store user structs.
This reduces the amount of generic unrelated code in kernel/user.c.
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
kernel/user.c | 33 +++++++++++++--------------------
1 files changed, 13 insertions(+), 20 deletions(-)
diff --git a/kernel/user.c b/kernel/user.c
index b815fef..d10c484 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,
@@ -52,13 +53,9 @@ EXPORT_SYMBOL_GPL(init_user_ns);
*/
#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))))
static struct kmem_cache *uid_cachep;
-struct hlist_head uidhash_table[UIDHASH_SZ];
+static DEFINE_HASHTABLE(uidhash_table, UIDHASH_BITS)
/*
* The uidhash_lock is mostly taken from process context, but it is
@@ -84,22 +81,22 @@ 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, __kuid_val(up->uid));
}
static void uid_hash_remove(struct user_struct *up)
{
- hlist_del_init(&up->uidhash_node);
+ hash_del(&up->uidhash_node);
}
-static struct user_struct *uid_hash_find(kuid_t uid, struct hlist_head *hashent)
+static struct user_struct *uid_hash_find(kuid_t uid)
{
struct user_struct *user;
struct hlist_node *h;
- hlist_for_each_entry(user, h, hashent, uidhash_node) {
+ hash_for_each_possible(uidhash_table, user, h, uidhash_node, __kuid_val(uid)) {
if (uid_eq(user->uid, uid)) {
atomic_inc(&user->__count);
return user;
@@ -135,7 +132,7 @@ 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 = uid_hash_find(uid);
spin_unlock_irqrestore(&uidhash_lock, flags);
return ret;
}
@@ -156,11 +153,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 = uid_hash_find(uid);
spin_unlock_irq(&uidhash_lock);
if (!up) {
@@ -176,13 +172,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 = uid_hash_find(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 +192,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);
/* 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
* [PATCH 02/16] user_ns: use new hashtable implementation
From: Sasha Levin @ 2012-08-19 0:52 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, josh, eric.dumazet,
mathieu.desnoyers, axboe, agk, dm-devel, neilb, ccaulfie,
teigland, Trond.Myklebust, bfields, fweisbec, jesse,
venkat.x.venkatsubra, ejt, snitzer, edumazet, linux-nfs, dev,
rds-devel, lw, Sasha Levin
In-Reply-To: <1345337550-24304-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 | 33 +++++++++++++--------------------
1 files changed, 13 insertions(+), 20 deletions(-)
diff --git a/kernel/user.c b/kernel/user.c
index b815fef..d10c484 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,
@@ -52,13 +53,9 @@ EXPORT_SYMBOL_GPL(init_user_ns);
*/
#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))))
static struct kmem_cache *uid_cachep;
-struct hlist_head uidhash_table[UIDHASH_SZ];
+static DEFINE_HASHTABLE(uidhash_table, UIDHASH_BITS)
/*
* The uidhash_lock is mostly taken from process context, but it is
@@ -84,22 +81,22 @@ 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, __kuid_val(up->uid));
}
static void uid_hash_remove(struct user_struct *up)
{
- hlist_del_init(&up->uidhash_node);
+ hash_del(&up->uidhash_node);
}
-static struct user_struct *uid_hash_find(kuid_t uid, struct hlist_head *hashent)
+static struct user_struct *uid_hash_find(kuid_t uid)
{
struct user_struct *user;
struct hlist_node *h;
- hlist_for_each_entry(user, h, hashent, uidhash_node) {
+ hash_for_each_possible(uidhash_table, user, h, uidhash_node, __kuid_val(uid)) {
if (uid_eq(user->uid, uid)) {
atomic_inc(&user->__count);
return user;
@@ -135,7 +132,7 @@ 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 = uid_hash_find(uid);
spin_unlock_irqrestore(&uidhash_lock, flags);
return ret;
}
@@ -156,11 +153,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 = uid_hash_find(uid);
spin_unlock_irq(&uidhash_lock);
if (!up) {
@@ -176,13 +172,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 = uid_hash_find(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 +192,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);
/* 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
* [PATCH v2 01/16] hashtable: introduce a small and naive hashtable
From: Sasha Levin @ 2012-08-19 0:52 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, josh, eric.dumazet,
mathieu.desnoyers, axboe, agk, dm-devel, neilb, ccaulfie,
teigland, Trond.Myklebust, bfields, fweisbec, jesse,
venkat.x.venkatsubra, ejt, snitzer, edumazet, linux-nfs, dev,
rds-devel, lw, Sasha Levin
In-Reply-To: <1345337550-24304-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 | 284 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 284 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..b18827a
--- /dev/null
+++ b/include/linux/hashtable.h
@@ -0,0 +1,284 @@
+/*
+ * Hash table implementation
+ * (C) 2012 Sasha Levin <levinsasha928@gmail.com>
+ */
+
+#ifndef _LINUX_HASHTABLE_H
+#define _LINUX_HASHTABLE_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/hash.h>
+#include <linux/rculist.h>
+
+#define DEFINE_HASHTABLE(name, bits) \
+ struct hlist_head name[HASH_SIZE(bits)];
+
+#define HASH_SIZE(bits) (1 << (bits))
+#define HASH_BITS(name) (ilog2(ARRAY_SIZE(name)))
+
+/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */
+#define hash_min(val, bits) ((sizeof(val)==4) ? hash_32((val), (bits)) : hash_long((val), (bits)))
+
+/**
+ * hash_init_size - initialize a hash table
+ * @hashtable: hashtable to be initialized
+ * @bits: bit count of hashing function
+ *
+ * Initializes a hash table with 2**bits buckets.
+ */
+static inline void hash_init_size(struct hlist_head *hashtable, int bits)
+{
+ int i;
+
+ for (i = 0; i < HASH_SIZE(bits); i++)
+ INIT_HLIST_HEAD(hashtable + i);
+}
+
+/**
+ * hash_init - initialize a hash table
+ * @hashtable: hashtable to be initialized
+ *
+ * Calculates the size of the hashtable from the given parameter, otherwise
+ * same as hash_init_size.
+ */
+#define hash_init(name) hash_init_size(name, HASH_BITS(name))
+
+/**
+ * hash_add_size - add an object to a hashtable
+ * @hashtable: hashtable to add to
+ * @bits: bit count used for hashing
+ * @node: the &struct hlist_node of the object to be added
+ * @key: the key of the object to be added
+ */
+#define hash_add_size(hashtable, bits, node, key) \
+ hlist_add_head(node, &hashtable[hash_min(key, bits)]);
+
+/**
+ * hash_add - add an object to a hashtable
+ * @hashtable: hashtable to add to
+ * @node: the &struct hlist_node of the object to be added
+ * @key: the key of the object to be added
+ */
+#define hash_add(hashtable, node, key) \
+ hash_add_size(hashtable, HASH_BITS(hashtable), node, key)
+
+/**
+ * hash_add_rcu_size - add an object to a rcu enabled hashtable
+ * @hashtable: hashtable to add to
+ * @bits: bit count used for hashing
+ * @node: the &struct hlist_node of the object to be added
+ * @key: the key of the object to be added
+ */
+#define hash_add_rcu_size(hashtable, bits, node, key) \
+ hlist_add_head_rcu(node, &hashtable[hash_min(key, bits)]);
+
+/**
+ * hash_add_rcu - add an object to a rcu enabled hashtable
+ * @hashtable: hashtable to add to
+ * @node: the &struct hlist_node of the object to be added
+ * @key: the key of the object to be added
+ */
+#define hash_add_rcu(hashtable, node, key) \
+ hash_add_rcu_size(hashtable, HASH_BITS(hashtable), node, key)
+
+/**
+ * hash_hashed - check whether an object is in any hashtable
+ * @node: the &struct hlist_node of the object to be checked
+ */
+#define hash_hashed(node) (!hlist_unhashed(node))
+
+/**
+ * hash_empty_size - check whether a hashtable is empty
+ * @hashtable: hashtable to check
+ * @bits: bit count used for hashing
+ */
+static inline bool hash_empty_size(struct hlist_head *hashtable, int bits)
+{
+ int i;
+
+ for (i = 0; i < HASH_SIZE(bits); i++)
+ if (!hlist_empty(&hashtable[i]))
+ return false;
+
+ return true;
+}
+
+/**
+ * hash_empty - check whether a hashtable is empty
+ * @hashtable: hashtable to check
+ */
+#define hash_empty(name) hash_empty_size(name, HASH_BITS(name))
+
+/**
+ * hash_del - remove an object from a hashtable
+ * @node: &struct hlist_node of the object to remove
+ */
+static inline void hash_del(struct hlist_node *node)
+{
+ hlist_del_init(node);
+}
+
+/**
+ * hash_del_rcu - remove an object from a rcu enabled hashtable
+ * @node: &struct hlist_node of the object to remove
+ */
+static inline void hash_del_rcu(struct hlist_node *node)
+{
+ hlist_del_init_rcu(node);
+}
+
+/**
+ * hash_for_each_size - iterate over a hashtable
+ * @name: hashtable to iterate
+ * @bits: bit count of hashing function of the hashtable
+ * @bkt: integer to use as bucket loop cursor
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each_size(name, bits, bkt, node, obj, member) \
+ for (bkt = 0; bkt < HASH_SIZE(bits); bkt++) \
+ hlist_for_each_entry(obj, node, &name[bkt], member)
+
+/**
+ * hash_for_each - iterate over a hashtable
+ * @name: hashtable to iterate
+ * @bkt: integer to use as bucket loop cursor
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each(name, bkt, node, obj, member) \
+ hash_for_each_size(name, HASH_BITS(name), bkt, node, obj, member)
+
+/**
+ * hash_for_each_rcu_size - iterate over a rcu enabled hashtable
+ * @name: hashtable to iterate
+ * @bits: bit count of hashing function of the hashtable
+ * @bkt: integer to use as bucket loop cursor
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each_rcu_size(name, bits, bkt, node, obj, member) \
+ for (bkt = 0; bkt < HASH_SIZE(bits); bkt++) \
+ hlist_for_each_entry_rcu(obj, node, &name[bkt], member)
+
+/**
+ * hash_for_each_rcu - iterate over a rcu enabled hashtable
+ * @name: hashtable to iterate
+ * @bkt: integer to use as bucket loop cursor
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each_rcu(name, bkt, node, obj, member) \
+ hash_for_each_rcu_size(name, HASH_BITS(name), bkt, node, obj, member)
+
+/**
+ * hash_for_each_safe_size - iterate over a hashtable safe against removal of
+ * hash entry
+ * @name: hashtable to iterate
+ * @bkt: integer to use as bucket loop cursor
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @tmp: another &struct hlist_node to use as temporary storage
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each_safe_size(name, bits, bkt, node, tmp, obj, member) \
+ for (bkt = 0; bkt < HASH_SIZE(bits); bkt++) \
+ hlist_for_each_entry_safe(obj, node, tmp, &name[bkt], member)
+
+/**
+ * hash_for_each_safe_size - iterate over a hashtable safe against removal of
+ * hash entry
+ * @name: hashtable to iterate
+ * @bkt: integer to use as bucket loop cursor
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each_safe(name, bkt, node, tmp, obj, member) \
+ hash_for_each_safe_size(name, HASH_BITS(name), bkt, node, \
+ tmp, obj, member)
+
+/**
+ * hash_for_each_possible - iterate over all possible objects for a given key
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @bits: bit count of hashing function of the hashtable
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible_size(name, obj, bits, node, member, key) \
+ hlist_for_each_entry(obj, node, &name[hash_min(key, bits)], member)
+
+/**
+ * hash_for_each_possible - iterate over all possible objects for a given key
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @bits: bit count of hashing function of the hashtable
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible(name, obj, node, member, key) \
+ hash_for_each_possible_size(name, obj, HASH_BITS(name), node, member, key)
+
+/**
+ * hash_for_each_possible - iterate over all possible objects for a given key
+ * in a rcu enabled hashtable
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @bits: bit count of hashing function of the hashtable
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible_rcu_size(name, obj, bits, node, member, key) \
+ hlist_for_each_entry_rcu(obj, node, &name[hash_min(key, bits)], member)
+
+/**
+ * hash_for_each_possible - iterate over all possible objects for a given key
+ * in a rcu enabled hashtable
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible_rcu(name, obj, node, member, key) \
+ hash_for_each_possible_rcu_size(name, obj, HASH_BITS(name), \
+ node, member, key)
+
+/**
+ * hash_for_each_possible - iterate over all possible objects for a given key
+ * safe against removal of hash entry
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @bits: bit count of hashing function of the hashtable
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible_safe_size(name, obj, bits, node, tmp, member, key)\
+ hlist_for_each_entry_safe(obj, node, tmp, \
+ &name[hash_min(key, bits)], member)
+
+/**
+ * hash_for_each_possible - iterate over all possible objects for a given key
+ * safe against removal of hash entry
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each bucket
+ * @node: the &struct list_head to use as a loop cursor for each bucket
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible_safe(name, obj, node, tmp, member, key) \
+ hash_for_each_possible_safe_size(name, obj, HASH_BITS(name), \
+ node, tmp, member, key)
+
+#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
* [PATCH v2 00/16] generic hashtable implementation
From: Sasha Levin @ 2012-08-19 0:52 UTC (permalink / raw)
To: torvalds
Cc: tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem, rostedt,
mingo, ebiederm, aarcange, ericvh, netdev, josh, eric.dumazet,
mathieu.desnoyers, axboe, agk, dm-devel, neilb, ccaulfie,
teigland, Trond.Myklebust, bfields, fweisbec, jesse,
venkat.x.venkatsubra, ejt, snitzer, edumazet, linux-nfs, dev,
rds-devel, lw, 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.
Since it looks like all the major issues we're addressed in the RFC phase
and no major issues were raised with this patch set, I'd be happy to see
this getting merged so that work could continue on different aspects of
the hashtable. Some interesting directions include:
- Introducing a dynamic RCU hashtable such as the one Mathieu Desnoyers
wrote about out in the userspace RCU.
- Replacing the rest of the the kernel structures which use the same basec
hashtable construct to use this new interface.
- Same as above, but for non-obvious places (for example, I'm looking into
using the hashtable to store KVM vcpus instead of the linked list being used
there now - this should help performance with a large amount of vcpus).
Changes since v1:
- Added missing hash_init in rds and lockd.
- Addressed the userns comments by Eric Biederman.
- Ran a small test to confirm hash_32 does a good job for low key
values (1-10000), which showed it did - this resulted in no changes to the
code.
Sasha Levin (16):
hashtable: introduce a small and naive hashtable
userns: 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
block,elevator: use new hashtable implementation
SUNRPC/cache: use new hashtable implementation
dlm: use new hashtable implementation
net,l2tp: use new hashtable implementation
dm: use new hashtable implementation
lockd: use new hashtable implementation
net,rds: use new hashtable implementation
openvswitch: use new hashtable implementation
tracing output: use new hashtable implementation
block/blk.h | 2 +-
block/elevator.c | 23 +--
drivers/md/dm-snap.c | 24 +--
drivers/md/persistent-data/dm-block-manager.c | 1 -
.../persistent-data/dm-persistent-data-internal.h | 19 --
.../md/persistent-data/dm-transaction-manager.c | 30 +--
fs/dlm/lowcomms.c | 47 +---
fs/lockd/svcsubs.c | 66 +++--
include/linux/elevator.h | 5 +-
include/linux/hashtable.h | 284 ++++++++++++++++++++
kernel/trace/trace_output.c | 20 +-
kernel/tracepoint.c | 27 +--
kernel/user.c | 33 +--
kernel/workqueue.c | 86 +-----
mm/huge_memory.c | 57 +---
mm/ksm.c | 33 +--
net/9p/error.c | 21 +-
net/l2tp/l2tp_core.c | 134 ++++------
net/l2tp/l2tp_core.h | 8 +-
net/l2tp/l2tp_debugfs.c | 19 +-
net/openvswitch/vport.c | 30 +--
net/rds/bind.c | 28 ++-
net/rds/connection.c | 102 +++----
net/sunrpc/cache.c | 20 +-
24 files changed, 591 insertions(+), 528 deletions(-)
delete mode 100644 drivers/md/persistent-data/dm-persistent-data-internal.h
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
* [PATCH] net/core/dev.c: fix kernel-doc warning
From: Randy Dunlap @ 2012-08-19 0:36 UTC (permalink / raw)
To: netdev, David Miller
From: Randy Dunlap <rdunlap@xenotime.net>
Fix kernel-doc warning:
Warning(net/core/dev.c:5745): No description found for parameter 'dev'
Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
---
net/core/dev.c | 1 +
1 file changed, 1 insertion(+)
--- lnx-36-rc2.orig/net/core/dev.c
+++ lnx-36-rc2/net/core/dev.c
@@ -5732,6 +5732,7 @@ EXPORT_SYMBOL(netdev_refcnt_read);
/**
* netdev_wait_allrefs - wait until all references are gone.
+ * @dev: target net_device
*
* This is called when unregistering network devices.
*
^ permalink raw reply
* 500,000.00GBP Winner
From: National Geographic International @ 2012-08-18 12:38 UTC (permalink / raw)
To: Recipients
You have been award the sum of 500,000.00GBP National Geographic International Uk
Claims Requirements.
Fill the below:
1. Full Name:
2. Address:
3. Nationality:Sex:
4. Age: Date of Birth:
5. Occupation:
6. Cell Phone:Fax:
7. State of Origin:Country:
Congratulations!! once again.
Sincerely,
Mrs.Caroline Cole
^ permalink raw reply
* [PATCH 4/5] drivers/net/wireless/ath/ath6kl/main.c: introduce missing initialization
From: Julia Lawall @ 2012-08-18 21:25 UTC (permalink / raw)
To: Kalle Valo
Cc: kernel-janitors, John W. Linville, linux-wireless, netdev,
linux-kernel
From: Julia Lawall <Julia.Lawall@lip6.fr>
The result of one call to a function is tested, and then at the second call
to the same function, the previous result, and not the current result, is
tested again.
The semantic match that finds this problem is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@@
expression ret;
identifier f;
statement S1,S2;
@@
*ret = f(...);
if (\(ret != 0\|ret < 0\|ret == NULL\)) S1
... when any
*f(...);
if (\(ret != 0\|ret < 0\|ret == NULL\)) S2
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
---
drivers/net/wireless/ath/ath6kl/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index c189e28..c312c61 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -322,7 +322,8 @@ int ath6kl_read_fwlogs(struct ath6kl *ar)
address = TARG_VTOP(ar->target_type,
le32_to_cpu(debug_buf.next));
- ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
+ ret = ath6kl_diag_read(ar, address, &debug_buf,
+ sizeof(debug_buf));
if (ret)
goto out;
^ permalink raw reply related
* [PATCH 1/5] drivers/net/wireless/ipw2x00/ipw2100.c: introduce missing initialization
From: Julia Lawall @ 2012-08-18 21:25 UTC (permalink / raw)
To: Stanislav Yakovlev
Cc: kernel-janitors-u79uwXL29TY76Z2rM5mHXA, John W. Linville,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
From: Julia Lawall <Julia.Lawall-L2FTfq7BK8M@public.gmane.org>
The result of one call to a function is tested, and then at the second call
to the same function, the previous result, and not the current result, is
tested again.
The semantic match that finds this problem is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@@
expression ret;
identifier f;
statement S1,S2;
@@
*ret = f(...);
if (\(ret != 0\|ret < 0\|ret == NULL\)) S1
... when any
*f(...);
if (\(ret != 0\|ret < 0\|ret == NULL\)) S2
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall-L2FTfq7BK8M@public.gmane.org>
---
drivers/net/wireless/ipw2x00/ipw2100.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 8a34202..2f3f6f2 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -2042,7 +2042,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
return;
}
len = ETH_ALEN;
- ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len);
+ ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid,
+ &len);
if (ret) {
IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
__LINE__);
--
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 related
* Re: [PATCH] NET: xfrm, use correct rcu dereference helper
From: David Miller @ 2012-08-18 21:08 UTC (permalink / raw)
To: jslaby; +Cc: netdev, jirislaby, linux-kernel, Priyanka.Jain
In-Reply-To: <1345210716-24556-1-git-send-email-jslaby@suse.cz>
From: Jiri Slaby <jslaby@suse.cz>
Date: Fri, 17 Aug 2012 15:38:36 +0200
> Use rcu_dereference_bh while holding bh rcu lock. Otherwise we get:
> ===============================
> [ INFO: suspicious RCU usage. ]
> 3.6.0-rc1-next-20120816+ #10 Not tainted
> -------------------------------
> net/xfrm/xfrm_policy.c:2504 suspicious rcu_dereference_check() usage!
>
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Cc: Priyanka Jain <Priyanka.Jain@freescale.com>
Should already be fixed in net-next for at least a whole day now.
^ permalink raw reply
* [Patch] netconsole: remove a redundant netconsole_target_put()
From: Cong Wang @ 2012-08-18 17:02 UTC (permalink / raw)
To: netdev; +Cc: David Miller, stable, Cong Wang
This netconsole_target_put() is obviously redundant, and it
causes a kernel segfault when removing a bridge device which has
netconsole running on it.
This is caused by:
commit 8d8fc29d02a33e4bd5f4fa47823c1fd386346093
Author: Amerigo Wang <amwang@redhat.com>
Date: Thu May 19 21:39:10 2011 +0000
netpoll: disable netpoll when enslave a device
Cc: David Miller <davem@davemloft.net>
(for all 3.x stable releases)
Cc: stable@vger.kernel.org
Signed-off-by: Cong Wang <amwang@redhat.com>
---
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index f0ad56c..b332112 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -643,7 +643,6 @@ static int netconsole_netdev_event(struct notifier_block *this,
__netpoll_cleanup(&nt->np);
dev_put(nt->np.dev);
nt->np.dev = NULL;
- netconsole_target_put(nt);
}
nt->enabled = 0;
stopped = true;
^ permalink raw reply related
* [PATCH]: net: ipv6: fix oops in inet_putpeer()
From: Patrick McHardy @ 2012-08-18 15:32 UTC (permalink / raw)
To: davem; +Cc: netdev
[-- Attachment #1: Type: TEXT/PLAIN, Size: 259 bytes --]
The attached patch fixes an oops in inet_putpeer(). Please see the
changelog entry for details.
An alternative fix would be to check whether rt6_peer_ptr() returns
NULL before invoking inet_putpeer(), but properly initializing the
peer looks cleaner to me.
[-- Attachment #2: Type: TEXT/PLAIN, Size: 3608 bytes --]
commit 9bf0a619538e6667676cdcfd91018da9397c6fce
Author: Patrick McHardy <kaber@trash.net>
Date: Sat Aug 18 17:17:30 2012 +0200
net: ipv6: fix oops in inet_putpeer()
Commit 97bab73f (inet: Hide route peer accesses behind helpers.) introduced
a bug in xfrm6_policy_destroy(). The xfrm_dst's _rt6i_peer member is not
initialized, causing a false positive result from inetpeer_ptr_is_peer(),
which in turn causes a NULL pointer dereference in inet_putpeer().
Pid: 314, comm: kworker/0:1 Not tainted 3.6.0-rc1+ #17 To Be Filled By O.E.M. To Be Filled By O.E.M./P4S800D-X
EIP: 0060:[<c03abf93>] EFLAGS: 00010246 CPU: 0
EIP is at inet_putpeer+0xe/0x16
EAX: 00000000 EBX: f3481700 ECX: 00000000 EDX: 000dd641
ESI: f3481700 EDI: c05e949c EBP: f551def4 ESP: f551def4
DS: 007b ES: 007b FS: 0000 GS: 00e0 SS: 0068
CR0: 8005003b CR2: 00000070 CR3: 3243d000 CR4: 00000750
DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
DR6: ffff0ff0 DR7: 00000400
f551df04 c0423de1 00000000 f3481700 f551df18 c038d5f7 f254b9f8 f551df28
f34f85d8 f551df20 c03ef48d f551df3c c0396870 f30697e8 f24e1738 c05e98f4
f5509540 c05cd2b4 f551df7c c0142d2b c043feb5 f5509540 00000000 c05cd2e8
[<c0423de1>] xfrm6_dst_destroy+0x42/0xdb
[<c038d5f7>] dst_destroy+0x1d/0xa4
[<c03ef48d>] xfrm_bundle_flo_delete+0x2b/0x36
[<c0396870>] flow_cache_gc_task+0x85/0x9f
[<c0142d2b>] process_one_work+0x122/0x441
[<c043feb5>] ? apic_timer_interrupt+0x31/0x38
[<c03967eb>] ? flow_cache_new_hashrnd+0x2b/0x2b
[<c0143e2d>] worker_thread+0x113/0x3cc
Fix by adding a init_dst() callback to struct xfrm_policy_afinfo to
properly initialize the dst's peer pointer.
Signed-off-by: Patrick McHardy <kaber@trash.net>
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 62b619e..976a81a 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -292,6 +292,8 @@ struct xfrm_policy_afinfo {
struct flowi *fl,
int reverse);
int (*get_tos)(const struct flowi *fl);
+ void (*init_dst)(struct net *net,
+ struct xfrm_dst *dst);
int (*init_path)(struct xfrm_dst *path,
struct dst_entry *dst,
int nfheader_len);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index ef39812..f8c4c08 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -73,6 +73,13 @@ static int xfrm6_get_tos(const struct flowi *fl)
return 0;
}
+static void xfrm6_init_dst(struct net *net, struct xfrm_dst *xdst)
+{
+ struct rt6_info *rt = (struct rt6_info *)xdst;
+
+ rt6_init_peer(rt, net->ipv6.peers);
+}
+
static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
int nfheader_len)
{
@@ -286,6 +293,7 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
.get_saddr = xfrm6_get_saddr,
.decode_session = _decode_session6,
.get_tos = xfrm6_get_tos,
+ .init_dst = xfrm6_init_dst,
.init_path = xfrm6_init_path,
.fill_dst = xfrm6_fill_dst,
.blackhole_route = ip6_blackhole_route,
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index c5a5165..5a2aa17 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1357,6 +1357,8 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
memset(dst + 1, 0, sizeof(*xdst) - sizeof(*dst));
xdst->flo.ops = &xfrm_bundle_fc_ops;
+ if (afinfo->init_dst)
+ afinfo->init_dst(net, xdst);
} else
xdst = ERR_PTR(-ENOBUFS);
^ permalink raw reply related
* Re: BUG: unable to handle kernel paging request at 00010016
From: Dave Jones @ 2012-08-18 15:00 UTC (permalink / raw)
To: Dave Haywood; +Cc: netdev
In-Reply-To: <502ECC74.9030605@oak.selfip.net>
[ trimmed, and cc'd to netdev. oops-tracing.txt asks for an excessive amount
of info, we should probably rewrite that, as it's rare that 160KB bug reports
are necessary ]
> BUG: unable to handle kernel paging request at 00010016
> IP: [<c15acfc9>] inet6_sk_rx_dst_set+0x29/0x40
> *pde = 00000000
> Oops: 0000 [#1] SMP
> Pid: 2168, comm: mprime Not tainted 3.6.0-rc2 #297 Compaq Deskpro/06C4h
> EIP: 0060:[<c15acfc9>] EFLAGS: 00010202 CPU: 0
> EIP is at inet6_sk_rx_dst_set+0x29/0x40
> EAX: ce738508 EBX: ce73a760 ECX: cf377000 EDX: 00010002
> ESI: ca06c900 EDI: ce738000 EBP: cf80bc7c ESP: cf80bc7c
> DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
> CR0: 80050033 CR2: 00010016 CR3: 0a036000 CR4: 000007d0
> DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
> DR6: ffff0ff0 DR7: 00000400
> Process mprime (pid: 2168, ti=cf80a000 task=ce4f7390 task.ti=ca052000)
> Stack:
> cf80bc9c c15449cb ffffffff ce436780 00000000 ce738508 ca06c900 ce738000
> cf80bcc0 c154337e c167545e cf80bcec c124b318 ce436780 ce738508 ce738000
> ce436780 cf80bd48 c15aff9d 00000000 00000001 cf80bcec c1236880 ce691ec0
> Call Trace:
> [<c15449cb>] tcp_create_openreq_child+0x3b/0x4a0
> [<c154337e>] tcp_v4_syn_recv_sock+0x2e/0x2a0
> [<c167545e>] ? _raw_spin_unlock_bh+0xe/0x10
> [<c124b318>] ? selinux_netlbl_sock_rcv_skb+0x18/0x190
> [<c15aff9d>] tcp_v6_syn_recv_sock+0x3ed/0x6d0
> [<c1236880>] ? selinux_parse_skb+0x50/0xb0
> [<c15450b3>] tcp_check_req+0x283/0x450
> [<c1541191>] tcp_v4_hnd_req+0x51/0x140
> [<c1542e69>] tcp_v4_do_rcv+0x129/0x1b0
> [<c14f5b45>] ? sk_filter+0x25/0xb0
> [<c154407e>] tcp_v4_rcv+0x5fe/0x730
> [<c15209b0>] ? ip_rcv_finish+0x2f0/0x2f0
> [<c1520a3c>] ip_local_deliver_finish+0x8c/0x260
> [<c15206c0>] ? inet_del_protocol+0x30/0x30
> [<c1520d9f>] ip_local_deliver+0x7f/0x90
> [<c15209b0>] ? ip_rcv_finish+0x2f0/0x2f0
> [<c15207b1>] ip_rcv_finish+0xf1/0x2f0
> [<c15206c0>] ? inet_del_protocol+0x30/0x30
> [<c1521002>] ip_rcv+0x252/0x320
> [<c15206c0>] ? inet_del_protocol+0x30/0x30
> [<c14e19bb>] __netif_receive_skb+0x46b/0x670
> [<c14e4b72>] netif_receive_skb+0x22/0x80
> [<c13eb6e2>] rtl8139_rx+0xd2/0x370
> [<c13eb9c2>] rtl8139_poll+0x42/0xb0
> [<c14e56dd>] net_rx_action+0xed/0x1c0
> [<c12c6110>] ? fbcon_add_cursor_timer+0xd0/0xd0
> [<c10427a7>] __do_softirq+0xa7/0x200
> [<c1042700>] ? local_bh_enable_ip+0x80/0x80
> <IRQ>
> [<c1042b0e>] ? irq_exit+0x6e/0x90
> [<c1004176>] ? do_IRQ+0x46/0xb0
> [<c1042af7>] ? irq_exit+0x57/0x90
> [<c10224a6>] ? smp_apic_timer_interrupt+0x56/0x90
> [<c1676289>] ? common_interrupt+0x29/0x30
> Code: 90 90 55 8b 4a 48 89 e5 83 e1 fe 3e ff 41 40 89 88 8c 00 00 00 8b 52 74 89 90 cc 01 00 00 8b 51 58 85 d2 74 0c 8b 80 a0 01 00 00 <8b> 52 14 89 50 68 5d c3 eb 0d 90 90 90 90 90 90 90 90 90 90 90
> EIP: [<c15acfc9>] inet6_sk_rx_dst_set+0x29/0x40 SS:ESP 0068:cf80bc7c
> CR2: 0000000000010016
> ---[ end trace 1fcc7fe92846c9d3 ]---
> Kernel panic - not syncing: Fatal exception in interrupt
^ permalink raw reply
* hii
From: sonia @ 2012-08-18 13:34 UTC (permalink / raw)
To: sonialife2
Hello my dear
How was your living life today i hope all is well, am Sonia by name i just
went into your profile at this site linux-archive.org and saw how you have
pest
your explanation over it i feel to know who your are so that we can shear one
thing or the
other from there i can send you my photo you can know who am ok . i am waiting
for your reply yours Sonia
^ permalink raw reply
* Re: [PATCH] net: tcp: ipv6_mapped needs sk_rx_dst_set method
From: Artem Savkov @ 2012-08-18 13:06 UTC (permalink / raw)
To: David Miller; +Cc: eric.dumazet, akpm, netdev
In-Reply-To: <20120809.210600.638327100706973152.davem@davemloft.net>
On Thu, Aug 09, 2012 at 09:06:00PM -0700, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Fri, 10 Aug 2012 02:11:00 +0200
>
> > From: Eric Dumazet <edumazet@google.com>
> >
> > commit 5d299f3d3c8a2fb (net: ipv6: fix TCP early demux) added a
> > regression for ipv6_mapped case.
> ...
> > Fix this using inet_sk_rx_dst_set(), and export this function in case
> > IPv6 is modular.
> >
> > Reported-by: Andrew Morton <akpm@linux-foundation.org>
> > Signed-off-by: Eric Dumazet <edumazet@google.com>
>
> Applied.
It doesn't seem to fix the problem with mapped ipv6 completely.
I'm still hitting a NULL pointer dereference with mapped ipv6:
[ 1699.191775] BUG: unable to handle kernel NULL pointer dereference at 00000016
[ 1699.192083] IP: [<c15d11d0>] inet6_sk_rx_dst_set+0x40/0xa0
[ 1699.192290] *pde = 00000000
[ 1699.192455] Oops: 0000 [#1] SMP
[ 1699.192686] Modules linked in: netconsole fuse iwldvm mac80211 btusb bluetooth kvm_intel iwlwifi cpufreq_ondemand kvm cfg80211 acpi_cpufreq mperf freq_table lpc_ich joydev crc32c_intel r8169 thermal thinkpad_acpi battery ac intel_ips processor
[ 1699.194710] Pid: 9823, comm: ncmpcpp Not tainted 3.6.0-rc1-next-20120810 #96 LENOVO 0578A21/0578A21
[ 1699.194896] EIP: 0060:[<c15d11d0>] EFLAGS: 00210202 CPU: 0
[ 1699.195040] EIP is at inet6_sk_rx_dst_set+0x40/0xa0
[ 1699.195176] EAX: 00000002 EBX: ef880780 ECX: f3264700 EDX: efc18e54
[ 1699.195325] ESI: edb01540 EDI: 00000000 EBP: f540dce8 ESP: f540dce0
[ 1699.195473] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
[ 1699.195610] CR0: 8005003b CR2: 00000016 CR3: 2d61a000 CR4: 000007d0
[ 1699.195757] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
[ 1699.195904] DR6: ffff0ff0 DR7: 00000400
[ 1699.196025] Process ncmpcpp (pid: 9823, ti=f540c000 task=eca26680 task.ti=e5354000)
[ 1699.196189] Stack:
[ 1699.196280] ef880780 f3264c80 f540dd04 c15662a1 edb01540 efc18780 efc18780 f3264c80
[ 1699.197242] efc18780 f540dd2c c1563b54 3401a499 3a200680 34932749 00d00680 edb01540
[ 1699.197933] efc18780 f3264c80 c16c0de0 f540dd9c c15d162e 00000000 c12691d1 f540dd54
[ 1699.198630] Call Trace:
[ 1699.198736] [<c15662a1>] tcp_create_openreq_child+0x41/0x4e0
[ 1699.198884] [<c1563b54>] tcp_v4_syn_recv_sock+0x34/0x330
[ 1699.199032] [<c15d162e>] tcp_v6_syn_recv_sock+0x3fe/0x660
[ 1699.199178] [<c12691d1>] ? selinux_sock_rcv_skb_compat+0xb1/0xc0
[ 1699.199332] [<c106c95d>] ? sched_clock_cpu+0xfd/0x180
[ 1699.199474] [<c1566b76>] tcp_check_req+0x2b6/0x410
[ 1699.199610] [<c1564756>] tcp_v4_do_rcv+0x266/0x420
[ 1699.199746] [<c15659a2>] ? tcp_v4_rcv+0x732/0xb20
[ 1699.199881] [<c162e25a>] ? _raw_spin_lock_nested+0x6a/0x80
[ 1699.200031] [<c1565c9d>] tcp_v4_rcv+0xa2d/0xb20
[ 1699.200167] [<c1541e0a>] ip_local_deliver_finish+0xda/0x370
[ 1699.200312] [<c1541d6c>] ? ip_local_deliver_finish+0x3c/0x370
[ 1699.200460] [<c15426cf>] ip_local_deliver+0x7f/0x90
[ 1699.200597] [<c1541d30>] ? inet_del_protocol+0x40/0x40
[ 1699.200737] [<c15421c2>] ip_rcv_finish+0x122/0x4a0
[ 1699.200873] [<c1542965>] ip_rcv+0x285/0x370
[ 1699.201005] [<c15420a0>] ? ip_local_deliver_finish+0x370/0x370
[ 1699.201156] [<c1503b30>] __netif_receive_skb+0x540/0x790
[ 1699.201298] [<c15036e1>] ? __netif_receive_skb+0xf1/0x790
[ 1699.201442] [<c1503e13>] process_backlog+0x93/0x150
[ 1699.201578] [<c1504915>] net_rx_action+0x105/0x1d0
[ 1699.201716] [<c103d72f>] __do_softirq+0x9f/0x1d0
[ 1699.201854] [<c103d690>] ? local_bh_enable_ip+0x90/0x90
[ 1699.202260] <IRQ>
[ 1699.202397] [<c103d679>] ? local_bh_enable_ip+0x79/0x90
[ 1699.202682] [<c162ec35>] ? _raw_spin_unlock_bh+0x35/0x40
[ 1699.202826] [<c14f3cbc>] ? release_sock+0x14c/0x1c0
[ 1699.205792] [<c157537f>] ? inet_stream_connect+0x3f/0x50
[ 1699.208723] [<c14f07c2>] ? sys_connect+0xb2/0xd0
[ 1699.211642] [<c1125b9c>] ? fd_install+0x4c/0x60
[ 1699.214583] [<c162ecf2>] ? _raw_spin_unlock+0x22/0x30
[ 1699.217400] [<c1125b9c>] ? fd_install+0x4c/0x60
[ 1699.220080] [<c14ee794>] ? sock_map_fd+0x24/0x30
[ 1699.222690] [<c12b33e2>] ? _copy_from_user+0x52/0x70
[ 1699.225259] [<c14f134f>] ? sys_socketcall+0xef/0x2d0
[ 1699.227803] [<c105eceb>] ? up_write+0x1b/0x30
[ 1699.230325] [<c16355cc>] ? sysenter_do_call+0x12/0x2d
[ 1699.232835] Code: c3 89 d6 f6 c1 01 75 33 83 e1 fe f0 ff 41 40 89 8b 10 01 00 00 8b 46 74 89 83 fc 02 00 00 8b 41 58 85 c0 74 0c 8b 93 d0 02 00 00 <8b> 40 14 89 42 68 8b 5d f8 8b 75 fc 89 ec 5d c3 e8 cb 21 a8 ff
[ 1699.242913] EIP: [<c15d11d0>] inet6_sk_rx_dst_set+0x40/0xa0 SS:ESP 0068:f540dce0
[ 1699.245945] CR2: 0000000000000016
[ 1699.280708] ---[ end trace 3fb05aeec95e7238 ]---
[ 1699.280806] Kernel panic - not syncing: Fatal exception in interrupt
[ 1699.284674] panic occurred, switching back to text console
After some debugging I found out that rt->rt6i_node in inet6_sk_rx_dst_set
is 0x02 when this happens.
I've been able to fix this with:
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4d63dff..a10a436 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1198,6 +1198,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
* v6 mapped
*/
+ inet_csk(sk)->icsk_af_ops = &ipv6_mapped;
newsk = tcp_v4_syn_recv_sock(sk, skb, req, dst);
if (newsk == NULL)
@@ -1218,7 +1219,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
newnp->rcv_saddr = newnp->saddr;
- inet_csk(newsk)->icsk_af_ops = &ipv6_mapped;
newsk->sk_backlog_rcv = tcp_v4_do_rcv;
#ifdef CONFIG_TCP_MD5SIG
newtp->af_specific = &tcp_sock_ipv6_mapped_specific;
But not sure if this is safe. Is it better to add some kind of
additional check to inet6_sk_rx_dst_set?
--
Kind regards,
Artem
^ permalink raw reply related
* [3.6-rc1 regression] Data stuck in Send-Q?
From: Andreas Schwab @ 2012-08-18 12:57 UTC (permalink / raw)
To: netdev
I'm seeing connections stall with data being stuck in the send queue.
Apparently that only happens when the connection is about to be closed,
after the payload has been received completely. Unfortunately this
doesn't happen reliably, so it would be a pain to bisect. Any idea how
to track down?
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply
* Re: [PATCH 00/19] netfilter: IPv6 NAT
From: Patrick McHardy @ 2012-08-18 12:46 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev
In-Reply-To: <20120817134238.GC23832@1984>
On Fri, 17 Aug 2012, Pablo Neira Ayuso wrote:
> On Thu, Aug 09, 2012 at 10:08:44PM +0200, kaber@trash.net wrote:
> [...]
>> - Patches 16-19 add some IPv6-capable ports of existing NAT helpers
>
> There was one for IRC also, did it get lost?
>
> I also made TFTP, it was more or less trivial, you can find it here:
>
> http://1984.lsi.us.es/git/nf-next/commit/?h=nf-nat4&id=ac2a06ab790386c8c8333dbf84584fc3f80fcdc5
I've already added your IRC and TFTP patches to my tree. Will send the
latest version later today.
^ permalink raw reply
* Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
From: Patrick McHardy @ 2012-08-18 12:43 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev
In-Reply-To: <20120817133608.GB23832@1984>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1283 bytes --]
On Fri, 17 Aug 2012, Pablo Neira Ayuso wrote:
> On Thu, Aug 09, 2012 at 10:08:49PM +0200, kaber@trash.net wrote:
>> +
>> + /* Conntrack helpers need the entire reassembled packet in the
>> + * POST_ROUTING hook.
>> + */
>> + ct = nf_ct_get(reasm, &ctinfo);
>> + if (ct != NULL && test_bit(IPS_HELPER_BIT, &ct->status)) {
>
> Two things regarding the line above:
>
> - I think this also need to check for !nf_ct_is_untracked(ct)
Fixed, thanks.
>
> - IPS_HELPER_BIT is only set if the CT target is used to attach
> helpers. I know, this behaviour may seem confusing, but I didn't
> find any better way to avoid that NAT removes the helper
> explicitly attached via CT.
>
> So basically now that status bit means: "this helper has been attached
> via CT".
>
> Setting it inconditionally in __nf_ct_try_assign_helper would break
> the magic auto-assign helper code.
>
> On the other hand, the automatic helper assignment is scheduled to
> be removed (well, it would still take at least one 1.5/2 years
> before we do so). At that time, we'll be able to say that all
> conntrack with IPS_HELPER really has one helper. But now I think that
> you'll have to use for nfct_help instead to check if that ct has a
> helper.
I see. Also fixed, thanks. New patch attached.
[-- Attachment #2: Type: TEXT/PLAIN, Size: 9573 bytes --]
commit f4266409e20dc0d2d22447aa7935c997f38914a1
Author: Patrick McHardy <kaber@trash.net>
Date: Tue Aug 14 15:27:55 2012 +0200
netfilter: nf_conntrack_ipv6: improve fragmentation handling
The IPv6 conntrack fragmentation currently has a couple of shortcomings.
Fragmentes are collected in PREROUTING/OUTPUT, are defragmented, the
defragmented packet is then passed to conntrack, the resulting conntrack
information is attached to each original fragment and the fragments then
continue their way through the stack.
Helper invocation occurs in the POSTROUTING hook, at which point only
the original fragments are available. The result of this is that
fragmented packets are never passed to helpers.
This patch improves the situation in the following way:
- If a reassembled packet belongs to a connection that has a helper
assigned, the reassembled packet is passed through the stack instead
of the original fragments.
- During defragmentation, the largest received fragment size is stored.
On output, the packet is refragmented if required. If the largest
received fragment size exceeds the outgoing MTU, a "packet too big"
message is generated, thus behaving as if the original fragments
were passed through the stack from an outside point of view.
- The ipv6_helper() hook function can't receive fragments anymore for
connections using a helper, so it is switched to use ipv6_skip_exthdr()
instead of the netfilter specific nf_ct_ipv6_skip_exthdr() and the
reassembled packets are passed to connection tracking helpers.
The result of this is that we can properly track fragmented packets, but
still generate ICMPv6 Packet too big messages if we would have before.
This patch is also required as a precondition for IPv6 NAT, where NAT
helpers might enlarge packets up to a point that they require
fragmentation. In that case we can't generate Packet too big messages
since the proper MTU can't be calculated in all cases (f.i. when
changing textual representation of a variable amount of addresses),
so the packet is transparently fragmented iff the original packet or
fragments would have fit the outgoing MTU.
Signed-off-by: Patrick McHardy <kaber@trash.net>
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 879db26..0b94e91 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -256,6 +256,7 @@ struct inet6_skb_parm {
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
__u16 dsthao;
#endif
+ __u16 frag_max_size;
#define IP6SKB_XFRM_TRANSFORMED 1
#define IP6SKB_FORWARDED 2
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 5b2d63e..a4f6263 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -493,7 +493,8 @@ int ip6_forward(struct sk_buff *skb)
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
- if (skb->len > mtu && !skb_is_gso(skb)) {
+ if ((!skb->local_df && skb->len > mtu && !skb_is_gso(skb)) ||
+ (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)) {
/* Again, force OUTPUT device used as source address */
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
@@ -636,7 +637,9 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
/* We must not fragment if the socket is set to force MTU discovery
* or if the skb it not generated by a local socket.
*/
- if (unlikely(!skb->local_df && skb->len > mtu)) {
+ if (unlikely(!skb->local_df && skb->len > mtu) ||
+ (IP6CB(skb)->frag_max_size &&
+ IP6CB(skb)->frag_max_size > mtu)) {
if (skb->sk && dst_allfrag(skb_dst(skb)))
sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 4794f96..9f36e38 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -153,10 +153,10 @@ static unsigned int ipv6_helper(unsigned int hooknum,
const struct nf_conn_help *help;
const struct nf_conntrack_helper *helper;
enum ip_conntrack_info ctinfo;
- unsigned int ret, protoff;
- unsigned int extoff = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
- unsigned char pnum = ipv6_hdr(skb)->nexthdr;
-
+ unsigned int ret;
+ __be16 frag_off;
+ int protoff;
+ u8 nexthdr;
/* This is where we call the helper: as the packet goes out. */
ct = nf_ct_get(skb, &ctinfo);
@@ -171,9 +171,10 @@ static unsigned int ipv6_helper(unsigned int hooknum,
if (!helper)
return NF_ACCEPT;
- protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum,
- skb->len - extoff);
- if (protoff > skb->len || pnum == NEXTHDR_FRAGMENT) {
+ nexthdr = ipv6_hdr(skb)->nexthdr;
+ protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr,
+ &frag_off);
+ if (protoff < 0 || (frag_off & ntohs(~0x7)) != 0) {
pr_debug("proto header not found\n");
return NF_ACCEPT;
}
@@ -199,9 +200,14 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
static unsigned int __ipv6_conntrack_in(struct net *net,
unsigned int hooknum,
struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct sk_buff *reasm = skb->nfct_reasm;
+ const struct nf_conn_help *help;
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
/* This packet is fragmented and has reassembled packet. */
if (reasm) {
@@ -213,6 +219,23 @@ static unsigned int __ipv6_conntrack_in(struct net *net,
if (ret != NF_ACCEPT)
return ret;
}
+
+ /* Conntrack helpers need the entire reassembled packet in the
+ * POST_ROUTING hook.
+ */
+ ct = nf_ct_get(reasm, &ctinfo);
+ if (ct != NULL && !nf_ct_is_untracked(ct)) {
+ help = nfct_help(ct);
+ if (help && help->helper) {
+ nf_conntrack_get_reasm(skb);
+ NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm,
+ (struct net_device *)in,
+ (struct net_device *)out,
+ okfn, NF_IP6_PRI_CONNTRACK + 1);
+ return NF_DROP_ERR(-ECANCELED);
+ }
+ }
+
nf_conntrack_get(reasm->nfct);
skb->nfct = reasm->nfct;
skb->nfctinfo = reasm->nfctinfo;
@@ -228,7 +251,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn);
+ return __ipv6_conntrack_in(dev_net(in), hooknum, skb, in, out, okfn);
}
static unsigned int ipv6_conntrack_local(unsigned int hooknum,
@@ -242,7 +265,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
net_notice_ratelimited("ipv6_conntrack_local: packet too short\n");
return NF_ACCEPT;
}
- return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn);
+ return __ipv6_conntrack_in(dev_net(out), hooknum, skb, in, out, okfn);
}
static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index c9c78c2..f94fb3a 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -190,6 +190,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
const struct frag_hdr *fhdr, int nhoff)
{
struct sk_buff *prev, *next;
+ unsigned int payload_len;
int offset, end;
if (fq->q.last_in & INET_FRAG_COMPLETE) {
@@ -197,8 +198,10 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
goto err;
}
+ payload_len = ntohs(ipv6_hdr(skb)->payload_len);
+
offset = ntohs(fhdr->frag_off) & ~0x7;
- end = offset + (ntohs(ipv6_hdr(skb)->payload_len) -
+ end = offset + (payload_len -
((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
if ((unsigned int)end > IPV6_MAXPLEN) {
@@ -307,6 +310,8 @@ found:
skb->dev = NULL;
fq->q.stamp = skb->tstamp;
fq->q.meat += skb->len;
+ if (payload_len > fq->q.max_size)
+ fq->q.max_size = payload_len;
atomic_add(skb->truesize, &nf_init_frags.mem);
/* The first fragment.
@@ -412,10 +417,12 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
}
atomic_sub(head->truesize, &nf_init_frags.mem);
+ head->local_df = 1;
head->next = NULL;
head->dev = dev;
head->tstamp = fq->q.stamp;
ipv6_hdr(head)->payload_len = htons(payload_len);
+ IP6CB(head)->frag_max_size = sizeof(struct ipv6hdr) + fq->q.max_size;
/* Yes, and fold redundant checksum back. 8) */
if (head->ip_summed == CHECKSUM_COMPLETE)
@@ -592,6 +599,7 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
int (*okfn)(struct sk_buff *))
{
struct sk_buff *s, *s2;
+ unsigned int ret = 0;
for (s = NFCT_FRAG6_CB(skb)->orig; s;) {
nf_conntrack_put_reasm(s->nfct_reasm);
@@ -601,8 +609,13 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
s2 = s->next;
s->next = NULL;
- NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s, in, out, okfn,
- NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
+ if (ret != -ECANCELED)
+ ret = NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s,
+ in, out, okfn,
+ NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
+ else
+ kfree_skb(s);
+
s = s2;
}
nf_conntrack_put_reasm(skb);
^ permalink raw reply related
* Re: [PATCH 13/19] netfilter: ip6tables: add MASQUERADE target
From: Patrick McHardy @ 2012-08-18 12:31 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev
In-Reply-To: <20120817131157.GA23832@1984>
On Fri, 17 Aug 2012, Pablo Neira Ayuso wrote:
> Hi Patrick,
>
> On Thu, Aug 09, 2012 at 10:08:57PM +0200, kaber@trash.net wrote:
>> From: Patrick McHardy <kaber@trash.net>
>>
> Please, add this chunk to this patch:
>
> diff --git a/include/net/netfilter/nf_nat.h
> b/include/net/netfilter/nf_nat.h
> index 1752f133..bd8eea7 100644
> --- a/include/net/netfilter/nf_nat.h
> +++ b/include/net/netfilter/nf_nat.h
> @@ -43,7 +43,9 @@ struct nf_conn_nat {
> struct nf_conn *ct;
> union nf_conntrack_nat_help help;
> #if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
> - defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
> + defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE) || \
> + defined(CONFIG_IP6_NF_TARGET_MASQUERADE) || \
> + defined(CONFIG_IP6_NF_TARGET_MASQUERADE_MODULE)
> int masq_index;
> #endif
> };
>
> Otherwise, compilation breaks with:
>
> * IPv4 NAT is disabled
> * IPv6 NAT enabled.
Fixed, thanks.
>
> And yes, that pile of ifdefs is really ugly, I wonder if they are
> worth for saving 4 bytes. I think most vendors usually include
> MASQUERADE support if NAT is enabled.
>
> It seems we have the tradition of keeping several similar compile time
> options in Netfilter to optimize memory in several situations (at the
> cost of polluting the code with ifdefs). Probably we can think of
> getting rid of them.
Well, vendors maybe, but what about embedded systems? I have some which
are *really* short on memory. They limit conntrack to very few entries
though, so it doesn't make that much of a difference.
^ permalink raw reply
* Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
From: Patrick McHardy @ 2012-08-18 12:26 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: netfilter-devel, netdev
In-Reply-To: <1345190795.3069.228.camel@localhost>
On Fri, 17 Aug 2012, Jesper Dangaard Brouer wrote:
> On Thu, 2012-08-09 at 22:08 +0200, kaber@trash.net wrote:
>> From: Patrick McHardy <kaber@trash.net>
>>
>> The IPv6 conntrack fragmentation currently has a couple of shortcomings.
>> Fragmentes are collected in PREROUTING/OUTPUT, are defragmented, the
>> defragmented packet is then passed to conntrack, the resulting conntrack
>> information is attached to each original fragment and the fragments then
>> continue their way through the stack.
>>
>> Helper invocation occurs in the POSTROUTING hook, at which point only
>> the original fragments are available. The result of this is that
>> fragmented packets are never passed to helpers.
>>
>> This patch improves the situation in the following way:
>>
>> - If a reassembled packet belongs to a connection that has a helper
>> assigned, the reassembled packet is passed through the stack instead
>> of the original fragments.
>
> I'm working on IPv6 fragment handling for IPVS, and are taking advantage
> of the "replay" by nf_ct_frag6_output() at hook prio -399
> (NF_IP6_PRI_CONNTRACK_DEFRAG + 1).
> By making a hook at NF_INET_PRE_ROUTING at prio -99 (NF_IP6_PRI_NAT_DST
> + 1).
>
> I can see that the code path can be changed (with this patch), if a
> helper is assigned. Then the "replay" starts at prio -199
> (NF_IP6_PRI_CONNTRACK + 1), I guess I'm safe as I run at -99.
>
> I have tested that your patchset works, with my ipvs patches, but would
> like the trigger the changed code path, to make sure.
>
> Could you provide an iptables command/rule, that trigger this code path?
The easiest way is a large ping with the NAT patches also applied,
in that case we also pass the first packet of a connection through
the stack reassembled.
>> @@ -199,9 +200,13 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
>> static unsigned int __ipv6_conntrack_in(struct net *net,
>> unsigned int hooknum,
>> struct sk_buff *skb,
>> + const struct net_device *in,
>> + const struct net_device *out,
>> int (*okfn)(struct sk_buff *))
>> {
>> struct sk_buff *reasm = skb->nfct_reasm;
>> + struct nf_conn *ct;
>> + enum ip_conntrack_info ctinfo;
>>
>> /* This packet is fragmented and has reassembled packet. */
>> if (reasm) {
>> @@ -213,6 +218,20 @@ static unsigned int __ipv6_conntrack_in(struct net *net,
>> if (ret != NF_ACCEPT)
>> return ret;
>> }
>> +
>> + /* Conntrack helpers need the entire reassembled packet in the
>> + * POST_ROUTING hook.
>> + */
>> + ct = nf_ct_get(reasm, &ctinfo);
>> + if (ct != NULL && test_bit(IPS_HELPER_BIT, &ct->status)) {
>> + nf_conntrack_get_reasm(skb);
>> + NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm,
>> + (struct net_device *)in,
>> + (struct net_device *)out,
>> + okfn, NF_IP6_PRI_CONNTRACK + 1);
>
> Hook prio change to NF_IP6_PRI_CONNTRACK + 1
I didn't get this part, you want to change to PRE_CONNTRACK + 1? What
about raw and SELinux?
^ permalink raw reply
* [PATCH] net/stmmac: fix issue of clk_get for Loongson1B.
From: Kelvin Cheung @ 2012-08-18 10:16 UTC (permalink / raw)
To: netdev, linux-kernel; +Cc: Giuseppe Cavallaro, David S. Miller, Kelvin Cheung
When getting clock, give a chance to the CPUs without DT support,
which use Common Clock Framework, such as Loongson1B.
Signed-off-by: Kelvin Cheung <keguang.zhang@gmail.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index fd8882f..c136162 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2077,7 +2077,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
goto error_netdev_register;
}
- priv->stmmac_clk = clk_get(priv->device, NULL);
+ priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME);
if (IS_ERR(priv->stmmac_clk)) {
pr_warning("%s: warning: cannot get CSR clock\n", __func__);
goto error_clk_get;
--
1.7.1
^ permalink raw reply related
* network packet corruption in v3.6.0-rc1 (and also in v3.5)
From: Andrew Worsley @ 2012-08-18 6:40 UTC (permalink / raw)
To: David S. Miller, Alexey Kuznetsov, James Morris; +Cc: netdev
Some times I get a burst of errors and dropped tcp connections with
this warning. I had a similar issue with v3.5 (in fact v3.5 was
unusable for https connections which would give bad MAC code messages
at the application level)..
The issue seems better under v3.6-rc1 where as it was very bad under
v3.5. Let me know if there is something I can do to avoid this
problem. I am using the USB r8712u wireless NIC if that is relevant as
I haven't been able to get the native wireless working under the MAC
book yet (requires proprietary firmware extraction which I am not
familiar with)
Much obliged if there is anything I can do to avoid it as it is rather
annoying. Doesn't happen at all with my Debian wheezy 3.2.0-2-amd64
kernel.
Andrew
Linux macbook 3.6.0-rc1+ #2 SMP Thu Aug 16 21:07:57 EST 2012 x86_64 GNU/Linux
[ 8280.095421] ------------[ cut here ]------------
[ 8280.095423] WARNING: at net/ipv4/tcp.c:1666 tcp_recvmsg+0x27b/0x98e()
[ 8280.095424] Hardware name: MacBookPro10,1
[ 8280.095425] recvmsg bug 2: copied 7A5E8B11 seq 7A5E8B11 rcvnxt 7A5E8B63 fl 0
[ 8280.095425] Modules linked in: r8712u(C) loop snd_hda_codec_hdmi
coretemp kvm_intel kvm snd_hda_codec_cirrus b43 nouveau snd_hda_intel
snd_hda_codec mac80211 crc32c_intel cfg80211 mxm_wmi snd_hwdep
ghash_clmulni_intel wmi ttm rfkill snd_pcm aesni_intel ssb aes_x86_64
rng_core pcmcia drm_kms_helper aes_generic snd_page_alloc ablk_helper
acpi_cpufreq lpc_ich applesmc drm cryptd snd_timer pcmcia_core
apple_gmux joydev evdev bcm5974 hid_generic snd microcode bcma
mfd_core mperf pcspkr input_polldev i2c_i801 i2c_algo_bit soundcore
i2c_core video battery button apple_bl ac processor thermal_sys
hid_apple ext4 crc16 jbd2 mbcache usbhid hid sd_mod crc_t10dif
ehci_hcd ahci libahci libata sdhci_pci scsi_mod xhci_hcd sdhci
mmc_core usbcore usb_common [last unloaded: r8712u]
[ 8280.095450] Pid: 2371, comm: firefox-bin Tainted: G WC 3.6.0-rc1+ #2
[ 8280.095451] Call Trace:
[ 8280.095453] [<ffffffff8103c850>] ? warn_slowpath_common+0x76/0x8a
[ 8280.095455] [<ffffffff8103c8fc>] ? warn_slowpath_fmt+0x45/0x4a
[ 8280.095457] [<ffffffff810602c7>] ? should_resched+0x5/0x23
[ 8280.095459] [<ffffffff812dc1ac>] ? tcp_recvmsg+0x27b/0x98e
[ 8280.095460] [<ffffffff812f6fed>] ? inet_recvmsg+0x5a/0x6e
[ 8280.095462] [<ffffffff81297488>] ? __sock_recvmsg_nosec+0x29/0x69
[ 8280.095464] [<ffffffff8129901c>] ? sock_recvmsg+0x5a/0x79
[ 8280.095467] [<ffffffff8107ad35>] ? get_futex_key+0x7d/0x206
[ 8280.095469] [<ffffffff8129a34b>] ? sys_recvfrom+0xc1/0x123
[ 8280.095471] [<ffffffff8107cc6f>] ? sys_futex+0x127/0x148
[ 8280.095473] [<ffffffff810ffa6f>] ? vfs_write+0xaf/0xf8
[ 8280.095475] [<ffffffff810ffc72>] ? sys_write+0x58/0x6d
[ 8280.095477] [<ffffffff8136d939>] ? system_call_fastpath+0x16/0x1b
[ 8280.095478] ---[ end trace 41af99a11f573306 ]---
[ 8280.095491] ------------[ cut here ]------------
..... repeatedly and also this one ....
[ 7278.076260] ------------[ cut here ]------------
[ 7278.076264] WARNING: at net/ipv4/tcp.c:1654 tcp_recvmsg+0x242/0x98e()
[ 7278.076265] Hardware name: MacBookPro10,1
[ 7278.076266] recvmsg bug: copied F9A0EDEF seq F9A0EE40 rcvnxt F9A0F017 fl 0
[ 7278.076267] Modules linked in: r8712u(C) loop snd_hda_codec_hdmi
coretemp kvm_intel kvm snd_hda_codec_cirrus b43 nouveau snd_hda_intel
snd_hda_codec mac80211 crc32c_intel cfg80211 mxm_wmi snd_hwdep
ghash_clmulni_intel wmi ttm rfkill snd_pcm aesni_intel ssb aes_x86_64
rng_core pcmcia drm_kms_helper aes_generic snd_page_alloc ablk_helper
acpi_cpufreq lpc_ich applesmc drm cryptd snd_timer pcmcia_core
apple_gmux joydev evdev bcm5974 hid_generic snd microcode bcma
mfd_core mperf pcspkr input_polldev i2c_i801 i2c_algo_bit soundcore
i2c_core video battery button apple_bl ac processor thermal_sys
hid_apple ext4 crc16 jbd2 mbcache usbhid hid sd_mod crc_t10dif
ehci_hcd ahci libahci libata sdhci_pci scsi_mod xhci_hcd sdhci
mmc_core usbcore usb_common [last unloaded: r8712u]
[ 7278.076304] Pid: 2371, comm: firefox-bin Tainted: G WC 3.6.0-rc1+ #2
[ 7278.076305] Call Trace:
[ 7278.076308] [<ffffffff8103c850>] ? warn_slowpath_common+0x76/0x8a
[ 7278.076311] [<ffffffff8103c8fc>] ? warn_slowpath_fmt+0x45/0x4a
[ 7278.076314] [<ffffffff810602c7>] ? should_resched+0x5/0x23
[ 7278.076317] [<ffffffff812dc173>] ? tcp_recvmsg+0x242/0x98e
[ 7278.076320] [<ffffffff812f6fed>] ? inet_recvmsg+0x5a/0x6e
[ 7278.076322] [<ffffffff81297488>] ? __sock_recvmsg_nosec+0x29/0x69
[ 7278.076325] [<ffffffff8129901c>] ? sock_recvmsg+0x5a/0x79
[ 7278.076329] [<ffffffff8107ad35>] ? get_futex_key+0x7d/0x206
[ 7278.076332] [<ffffffff8129a34b>] ? sys_recvfrom+0xc1/0x123
[ 7278.076335] [<ffffffff8107cc6f>] ? sys_futex+0x127/0x148
[ 7278.076339] [<ffffffff810ffa6f>] ? vfs_write+0xaf/0xf8
[ 7278.076341] [<ffffffff810ffc72>] ? sys_write+0x58/0x6d
[ 7278.076344] [<ffffffff8136d939>] ? system_call_fastpath+0x16/0x1b
[ 7278.076346] ---[ end trace 41af99a11f52c199 ]---
[ 7278.076371] ------------[ cut here ]------------
[ 7278.076374] WARNING: at net/ipv4/tcp.c:1654 tcp_recvmsg+0x242/0x98e()
[ 7278.076375] Hardware name: MacBookPro10,1
[ 7278.076377] recvmsg bug: copied F9A0EDEF seq F9A0EE40 rcvnxt F9A0F017 fl 0
[ 7278.076378] Modules linked in: r8712u(C) loop snd_hda_codec_hdmi
coretemp kvm_intel kvm snd_hda_codec_cirrus b43 nouveau snd_hda_intel
snd_hda_codec mac80211 crc32c_intel cfg80211 mxm_wmi snd_hwdep
ghash_clmulni_intel wmi ttm rfkill snd_pcm aesni_intel ssb aes_x86_64
rng_core pcmcia drm_kms_helper aes_generic snd_page_alloc ablk_helper
acpi_cpufreq lpc_ich applesmc drm cryptd snd_timer pcmcia_core
apple_gmux joydev evdev bcm5974 hid_generic snd microcode bcma
mfd_core mperf pcspkr input_polldev i2c_i801 i2c_algo_bit soundcore
i2c_core video battery button apple_bl ac processor thermal_sys
hid_apple ext4 crc16 jbd2 mbcache usbhid hid sd_mod crc_t10dif
ehci_hcd ahci libahci libata sdhci_pci scsi_mod xhci_hcd sdhci
mmc_core usbcore usb_common [last unloaded: r8712u]
[ 7278.076415] Pid: 2371, comm: firefox-bin Tainted: G WC 3.6.0-rc1+ #2
[ 7278.076416] Call Trace:
[ 7278.076419] [<ffffffff8103c850>] ? warn_slowpath_common+0x76/0x8a
[ 7278.076422] [<ffffffff8103c8fc>] ? warn_slowpath_fmt+0x45/0x4a
[ 7278.076425] [<ffffffff810602c7>] ? should_resched+0x5/0x23
[ 7278.076428] [<ffffffff812dc173>] ? tcp_recvmsg+0x242/0x98e
[ 7278.076430] [<ffffffff812f6fed>] ? inet_recvmsg+0x5a/0x6e
[ 7278.076433] [<ffffffff81297488>] ? __sock_recvmsg_nosec+0x29/0x69
[ 7278.076436] [<ffffffff8129901c>] ? sock_recvmsg+0x5a/0x79
[ 7278.076439] [<ffffffff8107ad35>] ? get_futex_key+0x7d/0x206
[ 7278.076443] [<ffffffff8129a34b>] ? sys_recvfrom+0xc1/0x123
[ 7278.076446] [<ffffffff8107cc6f>] ? sys_futex+0x127/0x148
[ 7278.076449] [<ffffffff810ffa6f>] ? vfs_write+0xaf/0xf8
[ 7278.076452] [<ffffffff810ffc72>] ? sys_write+0x58/0x6d
[ 7278.076455] [<ffffffff8136d939>] ? system_call_fastpath+0x16/0x1b
[ 7278.076456] ---[ end trace 41af99a11f52c19a ]---
[ 7278.076482] ------------[ cut here ]------------
[ 7278.076485] WARNING: at net/ipv4/tcp.c:1654 tcp_recvmsg+0x242/0x98e()
Under v3.5 kernel:
My firefox https sessions would constantly drop out with:
SSL received a record with an incorrect Message Authentication Code.
(Error code: ssl_error_bad_mac_read)
and this oops was repeated:
[ 6238.625211] ------------[ cut here ]------------
[ 6238.625212] WARNING: at net/ipv4/tcp.c:1610 tcp_recvmsg+0x27b/0x98e()
[ 6238.625213] Hardware name: MacBookPro10,1
[ 6238.625214] recvmsg bug 2: copied FBAA7A49 seq FBAA7A49 rcvnxt FBAA7A96 fl 0
[ 6238.625215] Modules linked in: loop snd_hda_codec_hdmi coretemp
kvm_intel snd_hda_codec_cirrus b43 kvm nouveau snd_hda_intel mac80211
snd_hda_codec cfg80211 crc32c_intel rfkill mxm_wmi ghash_clmulni_intel
wmi ssb acpi_cpufreq snd_hwdep aesni_intel rng_core mperf ttm snd_pcm
aes_x86_64 drm_kms_helper apple_gmux pcmcia snd_page_alloc aes_generic
drm cryptd lpc_ich snd_timer pcmcia_core input_polldev microcode
pcspkr i2c_i801 processor video bcma mfd_core snd i2c_algo_bit
soundcore ac battery apple_bl button thermal_sys joydev hid_apple
hid_generic usbhid hid bcm5974 usb_storage uas r8712u(C) evdev
uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_core videodev
media i2c_core ext4 crc16 jbd2 mbcache sd_mod crc_t10dif xhci_hcd ahci
libahci libata ehci_hcd scsi_mod sdhci_pci usbcore sdhci mmc_core
usb_common [last unloaded: scsi_wait_scan]
[ 6238.625261] Pid: 2705, comm: firefox-bin Tainted: G WC 3.5.0 #1
[ 6238.625262] Call Trace:
[ 6238.625264] [<ffffffff81039678>] ? warn_slowpath_common+0x76/0x8a
[ 6238.625265] [<ffffffff81039724>] ? warn_slowpath_fmt+0x45/0x4a
[ 6238.625267] [<ffffffff8105cbfc>] ? should_resched+0x5/0x23
[ 6238.625269] [<ffffffff812d9196>] ? tcp_recvmsg+0x27b/0x98e
[ 6238.625271] [<ffffffff812f3205>] ? inet_recvmsg+0x5a/0x6e
[ 6238.625272] [<ffffffff81293718>] ? __sock_recvmsg_nosec+0x29/0x69
[ 6238.625274] [<ffffffff81294b81>] ? sock_recvmsg+0xc8/0xe8
[ 6238.625276] [<ffffffff81077465>] ? get_futex_key+0x7d/0x206
[ 6238.625278] [<ffffffff81078bd9>] ? do_futex+0xd4/0x773
[ 6238.625280] [<ffffffff811011ca>] ? fget_light+0x63/0x74
[ 6238.625281] [<ffffffff81294d0d>] ? sockfd_lookup_light+0x17/0x4c
[ 6238.625283] [<ffffffff812966cd>] ? sys_recvfrom+0xc1/0x123
[ 6238.625285] [<ffffffff8107939f>] ? sys_futex+0x127/0x148
[ 6238.625287] [<ffffffff8110060c>] ? sys_write+0x58/0x6d
[ 6238.625289] [<ffffffff8136a4b9>] ? system_call_fastpath+0x16/0x1b
[ 6238.625290] ---[ end trace fc69f478338db70e ]---
[ 6238.625308] ------------[ cut here ]------------
^ 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