mm: preemptibility -v3
Subsystems (24)
cover mm: preemptibility -v3
This patch-set makes part of the mm a lot more preemptible. It converts i_mmap_lock and anon_vma->lock to mutexes and makes mmu_gather fully preemptible.
The main motivation was making mm_take_all_locks() preemptible, since it appears people are nesting hundreds of spinlocks there.
The side-effects are that can finally make mmu_gather preemptible, something which lots of people have wanted to do for a long time.
It also gets us anon_vma refcounting, which seems to result in a nice cleanup of the anon_vma lifetime rules wrt KSM and compaction.
This patch-set it build and boot-tested on x86_64 (a previous version was also tested on Dave's Niagra2 machines, and I suppose s390 did too when Martin provided the conversion patch for his arch).
There are no known architectures left unconverted, although some arch code never did see a compiler (superh and um come to mind).
Can we move this work forwards, or is there anything people would want to see done?
[ The series includes Rik's latest patches to the same area for convenience ]
PATCH 1/28 powerpc: Use call_rcu_sched() for pagetables
PowerPC relies on IRQ-disable to guard against RCU quiecent states, use the appropriate RCU call version.
--- arch/powerpc/mm/pgtable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/mm/pgtable.c +1 -1
@@ -93,7 +93,7 @@ static void pte_free_rcu_callback(structstatic void pte_free_submit (struct pte_freelist_batch *batch) {INIT_RCU_HEAD (&batch->rcu); -call_rcu (&batch->rcu, pte_free_rcu_callback); +call_rcu_sched (&batch->rcu, pte_free_rcu_callback); }void pgtable_free_tlb (struct mmu_gather *tlb,void *table,unsigned shift)
PATCH 2/28 mm: Improve page_lock_anon_vma() comment
In reply to Peter ZijlstraA slightly more verbose comment to go along with the trickery in page_lock_anon_vma().
LKML-Reference: <1271158226.4807.1107.camel@twins>
--- mm/rmap.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
mm/rmap.c +16 -2
@@ -286,8 +286,22 @@ void __init anon_vma_init(void) }/* -* Getting a lock on a stable anon_vma from a page off the LRU is -* tricky: page_lock_anon_vma rely on RCU to guard against the races. +* Getting a lock on a stable anon_vma from a page off the LRU is tricky! +* +* Since there is no serialization what so ever against page_remove_rmap() +* the best this function can do is return a locked anon_vma that might +* have been relevant to this page. +* +* The page might have been remapped to a different anon_vma or the anon_vma +* returned may already be freed (and even reused). +* +* All users of this function must be very careful when walking the anon_vma +* chain and verify that the page in question is indeed mapped in it +* [ something equivalent to page_mapped_in_vma() ]. +* +* Since anon_vma's slab is DESTROY_BY_RCU and we know from page_remove_rmap() +* that the anon_vma pointer from page->mapping is valid if there is a +* mapcount, we can dereference the anon_vma after observing those. */ struct anon_vma *page_lock_anon_vma (struct page *page) {
Re: [PATCH 02/28] mm: Improve page_lock_anon_vma() comment
Quoted 10 lines · Peter Zijlstra
A slightly more verbose comment to go along with the trickery in
page_lock_anon_vma().Reviewed-by KOSAKI Motohiro <[email protected]>Signed-off-by Peter Zijlstra <[email protected]>LKML-Reference: <1271158226.4807.1107.camel@twins>
--- mm/rmap.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
Quoted 1 line
<SNIP>
Signature · 3 lines
Mel Gorman Part-time Phd Student Linux Technology Center University of Limerick IBM Dublin Software Lab
PATCH 3/28 rename anon_vma_lock to vma_lock_anon_vma
In reply to Peter ZijlstraFrom: Rik van Riel <[email protected]>
Rename anon_vma_lock to vma_lock_anon_vma. This matches the naming style used in page_lock_anon_vma and will come in really handy further down in this patch series.
LKML-Reference: <[email protected]>
--- include/linux/rmap.h | 4 ++-- mm/mmap.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-)
include/linux/rmap.h +2 -2
@@ -99,14 +99,14 @@ static inline struct anon_vma *page_anonreturn page_rmapping (page); } -static inline void anon_vma_lock (struct vm_area_struct *vma) +static inline void vma_lock_anon_vma (struct vm_area_struct *vma) {struct anon_vma *anon_vma = vma->anon_vma;if (anon_vma)spin_lock (&anon_vma->lock); } -static inline void anon_vma_unlock (struct vm_area_struct *vma) +static inline void vma_unlock_anon_vma (struct vm_area_struct *vma) {struct anon_vma *anon_vma = vma->anon_vma;if (anon_vma)
mm/mmap.c +6 -6
@@ -452,12 +452,12 @@ static void vma_link(struct mm_struct *mspin_lock (&mapping->i_mmap_lock); vma->vm_truncate_count = mapping->truncate_count; } -anon_vma_lock (vma); +vma_lock_anon_vma (vma);__vma_link (mm, vma, prev, rb_link, rb_parent);__vma_link_file (vma); -anon_vma_unlock (vma); +vma_unlock_anon_vma (vma);if (mapping)spin_unlock (&mapping->i_mmap_lock);
@@ -1710,7 +1710,7 @@ int expand_upwards(struct vm_area_struct*/ if (unlikely (anon_vma_prepare (vma)))return -ENOMEM ; -anon_vma_lock (vma); +vma_lock_anon_vma (vma);/* * vma->vm_start/vm_end cannot change under us because the caller
@@ -1721,7 +1721,7 @@ int expand_upwards(struct vm_area_structif (address <PAGE_ALIGN (address+4 )) address =PAGE_ALIGN (address+4 );else { -anon_vma_unlock (vma); +vma_unlock_anon_vma (vma);return -ENOMEM ; } error =0 ;
@@ -1737,7 +1737,7 @@ int expand_upwards(struct vm_area_structif (!error) vma->vm_end = address; } -anon_vma_unlock (vma); +vma_unlock_anon_vma (vma);return error; }#endif /* CONFIG_STACK_GROWSUP || CONFIG_IA64 */
@@ -1762,7 +1762,7 @@ static int expand_downwards(struct vm_arif (error)return error; -anon_vma_lock (vma); +vma_lock_anon_vma (vma);/* * vma->vm_start/vm_end cannot change under us because the caller
Peter Zijlstra
maintainerRe: [PATCH 03/28] rename anon_vma_lock to vma_lock_anon_vma
Quoted 6 lines · Peter Zijlstra
From: Rik van Riel <[email protected]>
Rename
anon_vma_locktovma_lock_anon_vma. This matches the naming style used inpage_lock_anon_vmaand will come in really handy further down in this patch series.
Quoted 6 lines
Signed-off-by Rik van Riel <[email protected]>Acked-by Mel Gorman <[email protected]>Signed-off-by Peter Zijlstra <[email protected]>LKML-Reference: <[email protected]>
---
Missed a refresh... the below bit also wants in.
---
mm/mmap.c +1 -1
@@ -1783,7 +1783,7 @@ static int expand_downwards(struct vm_ar vma->vm_pgoff -= grow; } } -anon_vma_unlock (vma); +vma_unlock_anon_vma (vma);return error; }
Re: [PATCH 03/28] rename anon_vma_lock to vma_lock_anon_vma
In reply to Peter ZijlstraQuoted 11 lines · Peter Zijlstra
From: Rik van Riel <[email protected]>
Rename
anon_vma_locktovma_lock_anon_vma. This matches the naming style used inpage_lock_anon_vmaand will come in really handy further down in this patch series.Signed-off-by Rik van Riel <[email protected]>Acked-by Mel Gorman <[email protected]>Signed-off-by Peter Zijlstra <[email protected]>LKML-Reference: <[email protected]>
One rename was missed I think. With this patch applied, I get
mm/mmap.c: In function âexpand_downwardsâ:mm/mmap.c:1786: error: implicit declaration of function âanon_vma_unlockâ make[1]: *** [mm/mmap.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [mm] Error 2
Signature · 3 lines
Mel Gorman Part-time Phd Student Linux Technology Center University of Limerick IBM Dublin Software Lab
PATCH 4/28 change direct call of spin_lock(anon_vma->lock) to inline function
In reply to Peter ZijlstraFrom: Rik van Riel <[email protected]>
Subsitute a direct call of spin_lock(anon_vma->lock) with an inline function doing exactly the same.
This makes it easier to do the substitution to the root anon_vma lock in a following patch.
We will deal with the handful of special locks (nested, dec_and_lock, etc) separately.
LKML-Reference: <[email protected]>
--- include/linux/rmap.h | 10 ++++++++++ mm/ksm.c | 18 +++++++++--------- mm/migrate.c | 2 +- mm/mmap.c | 2 +- mm/rmap.c | 20 ++++++++++---------- 5 files changed, 31 insertions(+), 21 deletions(-)
include/linux/rmap.h +10 -0
@@ -113,6 +113,16 @@ static inline void vma_unlock_anon_vma(sspin_unlock (&anon_vma->lock); } +static inline void anon_vma_lock (struct anon_vma *anon_vma) +{ +spin_lock (&anon_vma->lock); +} + +static inline void anon_vma_unlock (struct anon_vma *anon_vma) +{ +spin_unlock (&anon_vma->lock); +} +/* * anon_vma helper functions. */
mm/ksm.c +9 -9
@@ -327,7 +327,7 @@ static void drop_anon_vma(struct rmap_itif (atomic_dec_and_lock (&anon_vma->external_refcount, &anon_vma->lock)) {int empty =list_empty (&anon_vma->head); -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma);if (empty)anon_vma_free (anon_vma); }
@@ -1566,7 +1566,7 @@ again:struct anon_vma_chain *vmac;struct vm_area_struct *vma; -spin_lock (&anon_vma->lock); +anon_vma_lock (anon_vma);list_for_each_entry (vmac, &anon_vma->head, same_anon_vma) { vma = vmac->vma; if (rmap_item->address < vma->vm_start ||
@@ -1589,7 +1589,7 @@ again:if (!search_new_forks || !mapcount)break ; } -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma);if (!mapcount) goto out; }
@@ -1619,7 +1619,7 @@ again:struct anon_vma_chain *vmac;struct vm_area_struct *vma; -spin_lock (&anon_vma->lock); +anon_vma_lock (anon_vma);list_for_each_entry (vmac, &anon_vma->head, same_anon_vma) { vma = vmac->vma; if (rmap_item->address < vma->vm_start ||
@@ -1637,11 +1637,11 @@ again: ret =try_to_unmap_one (page, vma, rmap_item->address, flags);if (ret !=SWAP_AGAIN || !page_mapped (page)) { -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma); goto out; } } -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma); }if (!search_new_forks++) goto again;
@@ -1671,7 +1671,7 @@ again:struct anon_vma_chain *vmac;struct vm_area_struct *vma; -spin_lock (&anon_vma->lock); +anon_vma_lock (anon_vma);list_for_each_entry (vmac, &anon_vma->head, same_anon_vma) { vma = vmac->vma; if (rmap_item->address < vma->vm_start ||
@@ -1688,11 +1688,11 @@ again: ret =rmap_one (page, vma, rmap_item->address, arg);if (ret !=SWAP_AGAIN ) { -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma); goto out; } } -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma); }if (!search_new_forks++) goto again;
mm/mmap.c +1 -1
@@ -2589,7 +2589,7 @@ static void vm_unlock_anon_vma(struct anif (!__test_and_clear_bit (0 , (unsigned long *) &anon_vma->head.next))BUG (); -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma); } }
mm/rmap.c +10 -10
@@ -134,7 +134,7 @@ int anon_vma_prepare(struct vm_area_stru allocated = anon_vma; } -spin_lock (&anon_vma->lock); +anon_vma_lock (anon_vma);/* page_table_lock to protect against threads */ spin_lock (&mm->page_table_lock);if (likely (!vma->anon_vma)) {
@@ -147,7 +147,7 @@ int anon_vma_prepare(struct vm_area_stru avc =NULL ; }spin_unlock (&mm->page_table_lock); -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma);if (unlikely (allocated))anon_vma_free (allocated);
@@ -170,9 +170,9 @@ static void anon_vma_chain_link(struct v avc->anon_vma = anon_vma;list_add (&avc->same_vma, &vma->anon_vma_chain); -spin_lock (&anon_vma->lock); +anon_vma_lock (anon_vma);list_add_tail (&avc->same_anon_vma, &anon_vma->head); -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma); }/*
@@ -246,12 +246,12 @@ static void anon_vma_unlink(struct anon_if (!anon_vma)return ; -spin_lock (&anon_vma->lock); +anon_vma_lock (anon_vma);list_del (&anon_vma_chain->same_anon_vma);/* We must garbage collect the anon_vma if it's empty */ empty =list_empty (&anon_vma->head) && !anonvma_external_refcount (anon_vma); -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma);if (empty)anon_vma_free (anon_vma);
@@ -302,7 +302,7 @@ struct anon_vma *page_lock_anon_vma(stru goto out; anon_vma = (struct anon_vma *) (anon_mapping -PAGE_MAPPING_ANON ); -spin_lock (&anon_vma->lock); +anon_vma_lock (anon_vma);return anon_vma; out:rcu_read_unlock ();
@@ -311,7 +311,7 @@ out:void page_unlock_anon_vma (struct anon_vma *anon_vma) { -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma);rcu_read_unlock (); }
@@ -1389,7 +1389,7 @@ static int rmap_walk_anon(struct page *p anon_vma =page_anon_vma (page);if (!anon_vma)return ret; -spin_lock (&anon_vma->lock); +anon_vma_lock (anon_vma);list_for_each_entry (avc, &anon_vma->head, same_anon_vma) {struct vm_area_struct *vma = avc->vma;unsigned long address =vma_address (page, vma);
@@ -1399,7 +1399,7 @@ static int rmap_walk_anon(struct page *pif (ret !=SWAP_AGAIN )break ; } -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma);return ret; }
mm/migrate.c +1 -1
@@ -684,7 +684,7 @@ rcu_unlock:/* Drop an anon_vma reference if we took one */ if (anon_vma &&atomic_dec_and_lock (&anon_vma->external_refcount, &anon_vma->lock)) {int empty =list_empty (&anon_vma->head); -spin_unlock (&anon_vma->lock); +anon_vma_unlock (anon_vma);if (empty)anon_vma_free (anon_vma); }
PATCH 5/28 track the root (oldest) anon_vma
In reply to Peter ZijlstraFrom: Rik van Riel <[email protected]>
Track the root (oldest) anon_vma in each anon_vma tree. Because we only
take the lock on the root anon_vma, we cannot use the lock on higher-up anon_vmas to lock anything. This makes it impossible to do an indirect lookup of the root anon_vma, since the data structures could go away from under us.
However, a direct pointer is safe because the root anon_vma is always the last one that gets freed on munmap or exit, by virtue of the same_vma list order and unlink_anon_vmas walking the list forward.
LKML-Reference: <[email protected]>
--- include/linux/rmap.h | 1 + mm/rmap.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-)
include/linux/rmap.h +1 -0
@@ -26,6 +26,7 @@*/ struct anon_vma {spinlock_t lock;/* Serialize access to vma list */ +struct anon_vma *root;/* Root of this anon_vma tree */ #if defined(CONFIG_KSM ) || defined(CONFIG_MIGRATION )/*
mm/rmap.c +16 -2
@@ -132,6 +132,11 @@ int anon_vma_prepare(struct vm_area_struif (unlikely (!anon_vma)) goto out_enomem_free_avc; allocated = anon_vma; +/* +* This VMA had no anon_vma yet. This anon_vma is +* the root of any anon_vma tree that might form. +*/ + anon_vma->root = anon_vma; }anon_vma_lock (anon_vma);
@@ -224,9 +229,15 @@ int anon_vma_fork(struct vm_area_struct avc =anon_vma_chain_alloc ();if (!avc) goto out_error_free_anon_vma; -anon_vma_chain_link (vma, avc, anon_vma); + +/* +* The root anon_vm's spinlock is the lock actually used when we +* lock any of the anon_vmas in this anon_vma tree. +*/ + anon_vma->root = pvma->anon_vma->root;/* Mark this anon_vma as the one where our new (COWed) pages go. */ vma->anon_vma = anon_vma; +anon_vma_chain_link (vma, avc, anon_vma);return 0 ;
@@ -261,7 +272,10 @@ void unlink_anon_vmas(struct vm_area_str {struct anon_vma_chain *avc, *next; -/* Unlink each anon_vma chained to the VMA. */ +/* +* Unlink each anon_vma chained to the VMA. This list is ordered +* from newest to oldest, ensuring the root anon_vma gets freed last. +*/ list_for_each_entry_safe (avc, next, &vma->anon_vma_chain, same_vma) {anon_vma_unlink (avc);list_del (&avc->same_vma);
PATCH 6/28 always lock the root (oldest) anon_vma
In reply to Peter ZijlstraFrom: Rik van Riel <[email protected]>
Always (and only) lock the root (oldest) anon_vma whenever we do something in an anon_vma. The recently introduced anon_vma scalability is due to the rmap code scanning only the VMAs that need to be scanned. Many common operations still took the anon_vma lock on the root anon_vma, so always taking that lock is not expected to introduce any scalability issues.
However, always taking the same lock does mean we only need to take one lock, which means rmap_walk on pages from any anon_vma in the vma is excluded from occurring during an munmap, expand_stack or other operation that needs to exclude rmap_walk and similar functions.
Also add the proper locking to vma_adjust.
LKML-Reference: <[email protected]>
---
v3:
- fix locking inversion in vma_adjust, spotted by Andrea
- mm_take_all locks needs to use the bitflag in the root anon_vma, since that is the one that gets locked (Andrea Arcangeli)
v2:
- conditionally take the anon_vma lock in vma_adjust, like introduced in 252c5f94d944487e9f50ece7942b0fbf659c5c31 (with a proper comment)
include/linux/rmap.h | 8 ++++---- mm/ksm.c | 2 +- mm/migrate.c | 2 +- mm/mmap.c | 30 ++++++++++++++++++++++-------- 4 files changed, 28 insertions(+), 14 deletions(-)
include/linux/rmap.h +4 -4
@@ -104,24 +104,24 @@ static inline void vma_lock_anon_vma(str {struct anon_vma *anon_vma = vma->anon_vma;if (anon_vma) -spin_lock (&anon_vma->lock); +spin_lock (&anon_vma->root->lock); }static inline void vma_unlock_anon_vma (struct vm_area_struct *vma) {struct anon_vma *anon_vma = vma->anon_vma;if (anon_vma) -spin_unlock (&anon_vma->lock); +spin_unlock (&anon_vma->root->lock); }static inline void anon_vma_lock (struct anon_vma *anon_vma) { -spin_lock (&anon_vma->lock); +spin_lock (&anon_vma->root->lock); }static inline void anon_vma_unlock (struct anon_vma *anon_vma) { -spin_unlock (&anon_vma->lock); +spin_unlock (&anon_vma->root->lock); }/*
mm/ksm.c +1 -1
@@ -325,7 +325,7 @@ static void drop_anon_vma(struct rmap_it {struct anon_vma *anon_vma = rmap_item->anon_vma; -if (atomic_dec_and_lock (&anon_vma->external_refcount, &anon_vma->lock)) { +if (atomic_dec_and_lock (&anon_vma->external_refcount, &anon_vma->root->lock)) {int empty =list_empty (&anon_vma->head);anon_vma_unlock (anon_vma);if (empty)
mm/mmap.c +22 -8
@@ -506,6 +506,7 @@ int vma_adjust(struct vm_area_struct *vmstruct vm_area_struct *importer =NULL ;struct address_space *mapping =NULL ;struct prio_tree_root *root =NULL ; +struct anon_vma *anon_vma =NULL ;struct file *file = vma->vm_file;long adjust_next =0 ;int remove_next =0 ;
@@ -578,6 +579,17 @@ again: remove_next = 1 + (end > next-> } } +/* +* When changing only vma->vm_end, we don't really need anon_vma +* lock. This is a fairly rare case by itself, but the anon_vma +* lock may be shared between many sibling processes. Skipping +* the lock for brk adjustments makes a difference sometimes. +*/ +if (vma->anon_vma && (insert || importer || start != vma->vm_start)) { + anon_vma = vma->anon_vma; +anon_vma_lock (anon_vma); + } +if (root) {flush_dcache_mmap_lock (mapping);vma_prio_tree_remove (vma, root);
@@ -617,6 +629,8 @@ again: remove_next = 1 + (end > next->__insert_vm_struct (mm, insert); } +if (anon_vma) +anon_vma_unlock (anon_vma);if (mapping)spin_unlock (&mapping->i_mmap_lock);
@@ -2466,23 +2480,23 @@ static DEFINE_MUTEX(mm_all_locks_mutex);static void vm_lock_anon_vma (struct mm_struct *mm,struct anon_vma *anon_vma) { -if (!test_bit (0 , (unsigned long *) &anon_vma->head.next)) { +if (!test_bit (0 , (unsigned long *) &anon_vma->root->head.next)) {/* * The LSB of head.next can't change from under us * because we hold the mm_all_locks_mutex. */ -spin_lock_nest_lock (&anon_vma->lock, &mm->mmap_sem); +spin_lock_nest_lock (&anon_vma->root->lock, &mm->mmap_sem);/* * We can safely modify head.next after taking the -* anon_vma->lock. If some other vma in this mm shares +* anon_vma->root->lock. If some other vma in this mm shares * the same anon_vma we won't take it again. * * No need of atomic instructions here, head.next * can't change from under us thanks to the -* anon_vma->lock. +* anon_vma->root->lock. */ if (__test_and_set_bit (0 , (unsigned long *) - &anon_vma->head.next)) + &anon_vma->root->head.next))BUG (); } }
@@ -2573,7 +2587,7 @@ out_unlock:static void vm_unlock_anon_vma (struct anon_vma *anon_vma) { -if (test_bit (0 , (unsigned long *) &anon_vma->head.next)) { +if (test_bit (0 , (unsigned long *) &anon_vma->root->head.next)) {/* * The LSB of head.next can't change to 0 from under * us because we hold the mm_all_locks_mutex.
@@ -2584,10 +2598,10 @@ static void vm_unlock_anon_vma(struct an* * No need of atomic instructions here, head.next * can't change from under us until we release the -* anon_vma->lock. +* anon_vma->root->lock. */ if (!__test_and_clear_bit (0 , (unsigned long *) - &anon_vma->head.next)) + &anon_vma->root->head.next))BUG ();anon_vma_unlock (anon_vma); }
mm/migrate.c +1 -1
@@ -682,7 +682,7 @@ skip_unmap: rcu_unlock:/* Drop an anon_vma reference if we took one */ -if (anon_vma &&atomic_dec_and_lock (&anon_vma->external_refcount, &anon_vma->lock)) { +if (anon_vma &&atomic_dec_and_lock (&anon_vma->external_refcount, &anon_vma->root->lock)) {int empty =list_empty (&anon_vma->head);anon_vma_unlock (anon_vma);if (empty)
PATCH 7/28 extend KSM refcounts to the anon_vma root
In reply to Peter ZijlstraFrom: Rik van Riel <[email protected]>
KSM reference counts can cause an anon_vma to exist after the processe it belongs to have already exited. Because the anon_vma lock now lives in the root anon_vma, we need to ensure that the root anon_vma stays around until after all the "child" anon_vmas have been freed.
The obvious way to do this is to have a "child" anon_vma take a reference to the root in anon_vma_fork. When the anon_vma is freed at munmap or process exit, we drop the refcount in anon_vma_unlink and possibly free the root anon_vma.
The KSM anon_vma reference count function also needs to be modified to deal with the possibility of freeing 2 levels of anon_vma. The easiest way to do this is to break out the KSM magic and make it generic.
When compiling without CONFIG_KSM, this code is compiled out.
LKML-Reference: <[email protected]>
---
v2:
- merge with -mm and the compaction code
- improve the anon_vma refcount comment in anon_vma_fork with the refcount lifetime
include/linux/rmap.h | 15 +++++++++++++++ mm/ksm.c | 17 ++++++----------- mm/migrate.c | 10 +++------- mm/rmap.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 19 deletions(-)
include/linux/rmap.h +15 -0
@@ -81,6 +81,13 @@ static inline int anonvma_external_refco {return atomic_read (&anon_vma->external_refcount); } + +static inline void get_anon_vma (struct anon_vma *anon_vma) +{ +atomic_inc (&anon_vma->external_refcount); +} + +void drop_anon_vma (struct anon_vma *);#else static inline void anonvma_external_refcount_init (struct anon_vma *anon_vma) {
@@ -90,6 +97,14 @@ static inline int anonvma_external_refco {return 0 ; } + +static inline void get_anon_vma (struct anon_vma *anon_vma) +{ +} + +static inline void drop_anon_vma (struct anon_vma *anon_vma) +{ +}#endif /* CONFIG_KSM */ static inline struct anon_vma *page_anon_vma (struct page *page)
mm/ksm.c +6 -11
@@ -318,19 +318,14 @@ static void hold_anon_vma(struct rmap_it struct anon_vma *anon_vma) { rmap_item->anon_vma = anon_vma; -atomic_inc (&anon_vma->external_refcount); +get_anon_vma (anon_vma); } -static void drop_anon_vma (struct rmap_item *rmap_item) +static void ksm_drop_anon_vma (struct rmap_item *rmap_item) {struct anon_vma *anon_vma = rmap_item->anon_vma; -if (atomic_dec_and_lock (&anon_vma->external_refcount, &anon_vma->root->lock)) { -int empty =list_empty (&anon_vma->head); -anon_vma_unlock (anon_vma); -if (empty) -anon_vma_free (anon_vma); - } +drop_anon_vma (anon_vma); }/*
@@ -415,7 +410,7 @@ static void break_cow(struct rmap_item ** It is not an accident that whenever we want to break COW * to undo, we also need to drop a reference to the anon_vma. */ -drop_anon_vma (rmap_item); +ksm_drop_anon_vma (rmap_item);down_read (&mm->mmap_sem);if (ksm_test_exit (mm))
@@ -470,7 +465,7 @@ static void remove_node_from_stable_tree ksm_pages_sharing--; else ksm_pages_shared--; -drop_anon_vma (rmap_item); +ksm_drop_anon_vma (rmap_item); rmap_item->address &=PAGE_MASK ;cond_resched (); }
@@ -558,7 +553,7 @@ static void remove_rmap_item_from_tree(selse ksm_pages_shared--; -drop_anon_vma (rmap_item); +ksm_drop_anon_vma (rmap_item); rmap_item->address &=PAGE_MASK ; }else if (rmap_item->address &UNSTABLE_FLAG ) {
mm/rmap.c +44 -1
64 lines not on this page · raw message
mm/migrate.c +3 -7
@@ -639,7 +639,7 @@ static int unmap_and_move(new_page_t get* exist when the page is remapped later */ anon_vma =page_anon_vma (page); -atomic_inc (&anon_vma->external_refcount); +get_anon_vma (anon_vma); } }
@@ -682,12 +682,8 @@ skip_unmap: rcu_unlock:/* Drop an anon_vma reference if we took one */ -if (anon_vma &&atomic_dec_and_lock (&anon_vma->external_refcount, &anon_vma->root->lock)) { -int empty =list_empty (&anon_vma->head); -anon_vma_unlock (anon_vma); -if (empty) -anon_vma_free (anon_vma); - } +if (anon_vma) +drop_anon_vma (anon_vma);if (rcu_locked)rcu_read_unlock ();
Re: [PATCH 07/28] extend KSM refcounts to the anon_vma root
Quoted 17 lines · Peter Zijlstra
From: Rik van Riel <[email protected]>
KSM reference counts can cause an
anon_vmato exist after the processe it belongs to have already exited. Because theanon_vmalock now lives in the rootanon_vma, we need to ensure that the rootanon_vmastays around until after all the "child"anon_vmashave been freed.The obvious way to do this is to have a "child"
anon_vmatake a reference to the root inanon_vma_fork. When theanon_vmais freed at munmap or process exit, we drop the refcount inanon_vma_unlinkand possibly free the rootanon_vma.The KSM
anon_vmareference count function also needs to be modified to deal with the possibility of freeing 2 levels ofanon_vma. The easiest way to do this is to break out the KSM magic and make it generic.
Quoted 5 lines
When compiling without
CONFIG_KSM, this code is compiled out.Signed-off-by Rik van Riel <[email protected]>Signed-off-by Peter Zijlstra <[email protected]>LKML-Reference: <[email protected]>
Quoted 1 line
<SNIP>
Signature · 3 lines
Mel Gorman Part-time Phd Student Linux Technology Center University of Limerick IBM Dublin Software Lab
PATCH 8/28 mm: Rename drop_anon_vma to put_anon_vma
In reply to Peter ZijlstraThe normal code pattern used in the kernel is: get/put.
--- include/linux/rmap.h | 4 ++-- mm/ksm.c | 10 +++++----- mm/migrate.c | 2 +- mm/rmap.c | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-)
include/linux/rmap.h +2 -2
@@ -87,7 +87,7 @@ static inline void get_anon_vma(struct a atomic_inc(&anon_vma->external_refcount); } -void drop_anon_vma (struct anon_vma *); +void put_anon_vma (struct anon_vma *);#else static inline void anonvma_external_refcount_init (struct anon_vma *anon_vma) {
@@ -102,7 +102,7 @@ static inline void get_anon_vma(struct a { } -static inline void drop_anon_vma (struct anon_vma *anon_vma) +static inline void put_anon_vma (struct anon_vma *anon_vma) { }#endif /* CONFIG_KSM */
mm/ksm.c +5 -5
@@ -321,11 +321,11 @@ static void hold_anon_vma(struct rmap_itget_anon_vma (anon_vma); } -static void ksm_drop_anon_vma (struct rmap_item *rmap_item) +static void ksm_put_anon_vma (struct rmap_item *rmap_item) {struct anon_vma *anon_vma = rmap_item->anon_vma; -drop_anon_vma (anon_vma); +put_anon_vma (anon_vma); }/*
@@ -410,7 +410,7 @@ static void break_cow(struct rmap_item ** It is not an accident that whenever we want to break COW * to undo, we also need to drop a reference to the anon_vma. */ -ksm_drop_anon_vma (rmap_item); +ksm_put_anon_vma (rmap_item);down_read (&mm->mmap_sem);if (ksm_test_exit (mm))
@@ -465,7 +465,7 @@ static void remove_node_from_stable_tree ksm_pages_sharing--; else ksm_pages_shared--; -ksm_drop_anon_vma (rmap_item); +ksm_put_anon_vma (rmap_item); rmap_item->address &=PAGE_MASK ;cond_resched (); }
@@ -553,7 +553,7 @@ static void remove_rmap_item_from_tree(selse ksm_pages_shared--; -ksm_drop_anon_vma (rmap_item); +ksm_put_anon_vma (rmap_item); rmap_item->address &=PAGE_MASK ; }else if (rmap_item->address &UNSTABLE_FLAG ) {
mm/migrate.c +1 -1
@@ -683,7 +683,7 @@ rcu_unlock:/* Drop an anon_vma reference if we took one */ if (anon_vma) -drop_anon_vma (anon_vma); +put_anon_vma (anon_vma);if (rcu_locked)rcu_read_unlock ();
mm/rmap.c +2 -2
@@ -272,7 +272,7 @@ static void anon_vma_unlink(struct anon_if (empty) {/* We no longer need the root anon_vma */ -drop_anon_vma (anon_vma->root); +put_anon_vma (anon_vma->root);anon_vma_free (anon_vma); } }
@@ -1398,7 +1398,7 @@ int try_to_munlock(struct page *page)* we know we are the last user, nobody else can get a reference and we * can do the freeing without the lock. */ -void drop_anon_vma (struct anon_vma *anon_vma) +void put_anon_vma (struct anon_vma *anon_vma) {if (atomic_dec_and_lock (&anon_vma->external_refcount, &anon_vma->root->lock)) {struct anon_vma *root = anon_vma->root;
PATCH 9/28 mm: Move anon_vma ref out from under CONFIG_KSM
In reply to Peter ZijlstraWe need an anon_vma refcount for preemptible anon_vma->lock.
--- include/linux/rmap.h | 40 ++++------------------------------------ mm/rmap.c | 10 ++++------ 2 files changed, 8 insertions(+), 42 deletions(-)
include/linux/rmap.h +4 -36
@@ -27,18 +27,15 @@struct anon_vma {spinlock_t lock;/* Serialize access to vma list */ struct anon_vma *root;/* Root of this anon_vma tree */ -#if defined(CONFIG_KSM ) || defined(CONFIG_MIGRATION ) -/* -* The external_refcount is taken by either KSM or page migration -* to take a reference to an anon_vma when there is no +* The refcount is taken on an anon_vma when there is no * guarantee that the vma of page tables will exist for * the duration of the operation. A caller that takes * the reference is responsible for clearing up the * anon_vma if they are the last user on release */ -atomic_t external_refcount; -#endif +atomic_t refcount; +/* * NOTE: the LSB of the head.next is set by * mm_take_all_locks() _after_ taking the above lock. So the
@@ -71,41 +68,12 @@ struct anon_vma_chain { };#ifdef CONFIG_MMU -#if defined(CONFIG_KSM ) || defined(CONFIG_MIGRATION ) -static inline void anonvma_external_refcount_init (struct anon_vma *anon_vma) -{ -atomic_set (&anon_vma->external_refcount,0 ); -} - -static inline int anonvma_external_refcount (struct anon_vma *anon_vma) -{ -return atomic_read (&anon_vma->external_refcount); -} -static inline void get_anon_vma (struct anon_vma *anon_vma) { -atomic_inc (&anon_vma->external_refcount); +atomic_inc (&anon_vma->refcount); }void put_anon_vma (struct anon_vma *); -#else -static inline void anonvma_external_refcount_init (struct anon_vma *anon_vma) -{ -} - -static inline int anonvma_external_refcount (struct anon_vma *anon_vma) -{ -return 0 ; -} - -static inline void get_anon_vma (struct anon_vma *anon_vma) -{ -} - -static inline void put_anon_vma (struct anon_vma *anon_vma) -{ -} -#endif /* CONFIG_KSM */ static inline struct anon_vma *page_anon_vma (struct page *page) {
mm/rmap.c +4 -6
@@ -267,7 +267,7 @@ static void anon_vma_unlink(struct anon_list_del (&anon_vma_chain->same_anon_vma);/* We must garbage collect the anon_vma if it's empty */ - empty =list_empty (&anon_vma->head) && !anonvma_external_refcount (anon_vma); + empty =list_empty (&anon_vma->head) && !atomic_read (&anon_vma->refcount);anon_vma_unlock (anon_vma);if (empty) {
@@ -297,7 +297,7 @@ static void anon_vma_ctor(void *data)struct anon_vma *anon_vma = data;spin_lock_init (&anon_vma->lock); -anonvma_external_refcount_init (anon_vma); +atomic_set (&anon_vma->refcount,0 );INIT_LIST_HEAD (&anon_vma->head); }
@@ -1391,7 +1391,6 @@ int try_to_munlock(struct page *page)return try_to_unmap_file (page,TTU_MUNLOCK ); } -#if defined(CONFIG_KSM ) || defined(CONFIG_MIGRATION )/* * Drop an anon_vma refcount, freeing the anon_vma and anon_vma->root * if necessary. Be careful to do all the tests under the lock. Once
@@ -1400,7 +1399,7 @@ int try_to_munlock(struct page *page)*/ void put_anon_vma (struct anon_vma *anon_vma) { -if (atomic_dec_and_lock (&anon_vma->external_refcount, &anon_vma->root->lock)) { +if (atomic_dec_and_lock (&anon_vma->refcount, &anon_vma->root->lock)) {struct anon_vma *root = anon_vma->root;int empty =list_empty (&anon_vma->head);int last_root_user =0 ;
@@ -1411,7 +1410,7 @@ void put_anon_vma(struct anon_vma *anon_* the refcount on the root and check if we need to free it. */ if (empty && anon_vma != root) { - last_root_user =atomic_dec_and_test (&root->external_refcount); + last_root_user =atomic_dec_and_test (&root->refcount); root_empty =list_empty (&root->head); }anon_vma_unlock (anon_vma);
@@ -1423,7 +1422,6 @@ void put_anon_vma(struct anon_vma *anon_ } } } -#endif #ifdef CONFIG_MIGRATION /*
Re: [PATCH 09/28] mm: Move anon_vma ref out from under CONFIG_KSM
Quoted 3 lines · Peter Zijlstra
We need an
anon_vmarefcount for preemptibleanon_vma->lock.Signed-off-by Peter Zijlstra <[email protected]>
Can't see any problems
Quoted 1 line
<SNIP>
Signature · 3 lines
Mel Gorman Part-time Phd Student Linux Technology Center University of Limerick IBM Dublin Software Lab
PATCH 10/28 mm: Make use of the anon_vma ref count
In reply to Peter ZijlstraThis patch changes the anon_vma refcount to be 0 when the object is free. It does this by adding 1 ref to being in use in the anon_vma structure (iow. the anon_vma->head list is not empty).
This allows a simpler release scheme without having to check both the refcount and the list as well as avoids taking a ref for each entry on the list.
We then convert page_lock_anon_vma() over to use refcounts. This is done for each of convertion of anon_vma from spinlock to mutex.
--- include/linux/rmap.h | 11 ++++- mm/ksm.c | 4 -- mm/rmap.c | 94 ++++++++++++++++++++++----------------------------- 3 files changed, 52 insertions(+), 57 deletions(-)
include/linux/rmap.h +9 -2
@@ -73,7 +73,13 @@ static inline void get_anon_vma(struct aatomic_inc (&anon_vma->refcount); } -void put_anon_vma (struct anon_vma *); +void __put_anon_vma (struct anon_vma *anon_vma); + +static inline void put_anon_vma (struct anon_vma *anon_vma) +{ +if (atomic_dec_and_test (&anon_vma->refcount)) +__put_anon_vma (anon_vma); +}static inline struct anon_vma *page_anon_vma (struct page *page) {
@@ -116,7 +122,6 @@ void unlink_anon_vmas(struct vm_area_strint anon_vma_clone (struct vm_area_struct *,struct vm_area_struct *);int anon_vma_fork (struct vm_area_struct *,struct vm_area_struct *);void __anon_vma_link (struct vm_area_struct *); -void anon_vma_free (struct anon_vma *);static inline void anon_vma_merge (struct vm_area_struct *vma,struct vm_area_struct *next)
@@ -125,6 +130,8 @@ static inline void anon_vma_merge(structunlink_anon_vmas (next); } +struct anon_vma *page_get_anon_vma (struct page *page); +/* * rmap interfaces called when adding or removing pte of page */
mm/ksm.c +1 -3
@@ -323,9 +323,7 @@ static void hold_anon_vma(struct rmap_itstatic void ksm_put_anon_vma (struct rmap_item *rmap_item) { -struct anon_vma *anon_vma = rmap_item->anon_vma; - -put_anon_vma (anon_vma); +put_anon_vma (rmap_item->anon_vma); }/*
mm/rmap.c +42 -52
156 lines not on this page · raw message
Re: [PATCH 10/28] mm: Make use of the anon_vma ref count
Quoted 8 lines · Peter Zijlstra
This patch changes the
anon_vmarefcount to be 0 when the object is free. It does this by adding 1 ref to being in use in theanon_vmastructure (iow. theanon_vma->headlist is not empty).This allows a simpler release scheme without having to check both the refcount and the list as well as avoids taking a ref for each entry on the list.
Nice touch. It makes it closer to page reference counting as well so should be familiar.
Quoted 71 lines
We then convert
page_lock_anon_vma()over to use refcounts. This is done for each of convertion ofanon_vmafrom spinlock to mutex.Signed-off-by Peter Zijlstra <[email protected]>--- include/linux/rmap.h | 11 ++++- mm/ksm.c | 4 -- mm/rmap.c | 94 ++++++++++++++++++++++----------------------------- 3 files changed, 52 insertions(+), 57 deletions(-)Index:
linux-2.6/include/linux/rmap.h
===================================================================include/linux/rmap.h +9
-2@@ -73,7 +73,13 @@ static inline void get_anon_vma(struct aatomic_inc (&anon_vma->refcount); } -void put_anon_vma (struct anon_vma *); +void __put_anon_vma (struct anon_vma *anon_vma); + +static inline void put_anon_vma (struct anon_vma *anon_vma) +{ +if (atomic_dec_and_test (&anon_vma->refcount)) +__put_anon_vma (anon_vma); +}static inline struct anon_vma *page_anon_vma (struct page *page) {@@ -116,7 +122,6 @@ void unlink_anon_vmas(struct vm_area_strint anon_vma_clone (struct vm_area_struct *,struct vm_area_struct *);int anon_vma_fork (struct vm_area_struct *,struct vm_area_struct *);void __anon_vma_link (struct vm_area_struct *); -void anon_vma_free (struct anon_vma *);static inline void anon_vma_merge (struct vm_area_struct *vma,struct vm_area_struct *next)@@ -125,6 +130,8 @@ static inline void anon_vma_merge(structunlink_anon_vmas (next); } +struct anon_vma *page_get_anon_vma (struct page *page); +/* * rmap interfaces called when adding or removing pte of page */ Index:
linux-2.6/mm/ksm.c
===================================================================mm/ksm.c +1
-3@@ -323,9 +323,7 @@ static void hold_anon_vma(struct rmap_itstatic void ksm_put_anon_vma (struct rmap_item *rmap_item) { -struct anon_vma *anon_vma = rmap_item->anon_vma; - -put_anon_vma (anon_vma); +put_anon_vma (rmap_item->anon_vma); }/* Index:
linux-2.6/mm/rmap.c
===================================================================mm/rmap.c +1
-1@@ -66,11 +66,24 @@ static struct kmem_cache *anon_vma_chainstatic inline struct anon_vma *anon_vma_alloc (void ) { -return kmem_cache_alloc (anon_vma_cachep,GFP_KERNEL ); +struct anon_vma *anon_vma;
mm/rmap.c static struct kmem_cache *anon_vma_chain · line 79
Quoted 10 lines
mm/rmap.c +10
-0+ + anon_vma =kmem_cache_alloc (anon_vma_cachep,GFP_KERNEL ); +if (anon_vma) { +atomic_set (&anon_vma->refcount,1 ); +/* +* This VMA had no anon_vma yet. This anon_vma is +* the root of any anon_vma tree that might form. +*/ + anon_vma->root = anon_vma; + }
This comment is no longer strictly correct. anon_vma_alloc() can also be called from anon_vma_fork where the root of the newly allocated anon_vma will be set to the same as the parents anon_vma. Maybe something like
/*
* Initialise the anon_vma root to point to itself. If called from
* fork, the root will be reset to the parents anon_vma */
Else, just leave the initialisation of the root where it was but only init the refcount here.
Quoted 42 lines
mm/rmap.c +6
-8+ +return anon_vma; } -void anon_vma_free (struct anon_vma *anon_vma) +static inline void anon_vma_free (struct anon_vma *anon_vma) { +VM_BUG_ON (atomic_read (&anon_vma->refcount));kmem_cache_free (anon_vma_cachep, anon_vma); }@@ -132,11 +145,6 @@ int anon_vma_prepare(struct vm_area_struif (unlikely (!anon_vma)) goto out_enomem_free_avc; allocated = anon_vma; -/* -* This VMA had no anon_vma yet. This anon_vma is -* the root of any anon_vma tree that might form. -*/ - anon_vma->root = anon_vma; }anon_vma_lock (anon_vma);@@ -155,7 +163,7 @@ int anon_vma_prepare(struct vm_area_struanon_vma_unlock (anon_vma);if (unlikely (allocated)) -anon_vma_free (allocated); +put_anon_vma (allocated);if (unlikely (avc))anon_vma_chain_free (avc); }@@ -248,7 +256,7 @@ int anon_vma_fork(struct vm_area_structreturn 0 ; out_error_free_anon_vma: -anon_vma_free (anon_vma); +put_anon_vma (anon_vma); out_error:unlink_anon_vmas (vma);return -ENOMEM ;
mm/rmap.c static void anon_vma_unlink(struct anon_ · line 276
Quoted 5 lines
mm/rmap.c +0
-1@@ -265,16 +273,12 @@ static void anon_vma_unlink(struct anon_anon_vma_lock (anon_vma);list_del (&anon_vma_chain->same_anon_vma); -/* We must garbage collect the anon_vma if it's empty */
Unnecessary whitespace change there.
Quoted 15 lines
mm/rmap.c +3
-6- empty =list_empty (&anon_vma->head) && !atomic_read (&anon_vma->refcount); + empty =list_empty (&anon_vma->head);anon_vma_unlock (anon_vma); -if (empty) { -/* We no longer need the root anon_vma */ -put_anon_vma (anon_vma->root); -anon_vma_free (anon_vma); - } +if (empty) +put_anon_vma (anon_vma); }void unlink_anon_vmas (struct vm_area_struct *vma)
mm/rmap.c void __init anon_vma_init(void) · line 337
Quoted 10 lines
mm/rmap.c +2
-2@@ -326,9 +330,9 @@ void __init anon_vma_init(void)* that the anon_vma pointer from page->mapping is valid if there is a * mapcount, we can dereference the anon_vma after observing those. */ -struct anon_vma *page_lock_anon_vma (struct page *page) +struct anon_vma *page_get_anon_vma (struct page *page) { -struct anon_vma *anon_vma; +struct anon_vma *anon_vma =NULL ;unsigned long anon_mapping;
It's not clear why you split page_get_anon_vma and page_lock_anon_vma at this point. Maybe you use it later in the series?
Quoted 67 lines
mm/rmap.c +15
-32rcu_read_lock ();@@ -339,17 +343,28 @@ struct anon_vma *page_lock_anon_vma(stru goto out; anon_vma = (struct anon_vma *) (anon_mapping -PAGE_MAPPING_ANON ); -anon_vma_lock (anon_vma); -return anon_vma; +if (!atomic_inc_not_zero (&anon_vma->refcount)) + anon_vma =NULL ; out:rcu_read_unlock (); -return NULL ; + +return anon_vma; +} + +struct anon_vma *page_lock_anon_vma (struct page *page) +{ +struct anon_vma *anon_vma =page_get_anon_vma (page); + +if (anon_vma) +anon_vma_lock (anon_vma); + +return anon_vma; }void page_unlock_anon_vma (struct anon_vma *anon_vma) {anon_vma_unlock (anon_vma); -rcu_read_unlock (); +put_anon_vma (anon_vma); }/* @@ -1405,36 +1420,11 @@ int try_to_munlock(struct page *page)return try_to_unmap_file (page,TTU_MUNLOCK ); } -/* -* Drop an anon_vma refcount, freeing the anon_vma and anon_vma->root -* if necessary. Be careful to do all the tests under the lock. Once -* we know we are the last user, nobody else can get a reference and we -* can do the freeing without the lock. -*/ -void put_anon_vma (struct anon_vma *anon_vma) -{ -if (atomic_dec_and_lock (&anon_vma->refcount, &anon_vma->root->lock)) { -struct anon_vma *root = anon_vma->root; -int empty =list_empty (&anon_vma->head); -int last_root_user =0 ; -int root_empty =0 ; - -/* -* The refcount on a non-root anon_vma got dropped. Drop -* the refcount on the root and check if we need to free it. -*/ -if (empty && anon_vma != root) { - last_root_user =atomic_dec_and_test (&root->refcount); - root_empty =list_empty (&root->head); - } -anon_vma_unlock (anon_vma); - -if (empty) { -anon_vma_free (anon_vma); -if (root_empty && last_root_user) -anon_vma_free (root);
mm/rmap.c int try_to_munlock(struct page *page) · line 1430
Quoted 10 lines
mm/rmap.c +5
-2- } - } +void __put_anon_vma (struct anon_vma *anon_vma) +{ +if (anon_vma->root != anon_vma) +put_anon_vma (anon_vma->root); +anon_vma_free (anon_vma); }#ifdef CONFIG_MIGRATION
In the first reading, nothing horrible jumped out at this point. I'm going to run a few tests on just the first 10 patches in this series and see what that looks like. For this patch in particular, I want to be sure we are not leaking anon_vma's.
Signature · 3 lines
Mel Gorman Part-time Phd Student Linux Technology Center University of Limerick IBM Dublin Software Lab
Peter Zijlstra
maintainerRe: [PATCH 10/28] mm: Make use of the anon_vma ref count
Quoted 8 lines · Mel Gorman
This comment is no longer strictly correct.
anon_vma_alloc()can also be called fromanon_vma_forkwhere the root of the newly allocatedanon_vmawill be set to the same as the parentsanon_vma. Maybe something like/*
* Initialise theanon_vmaroot to point to itself. If called from
* fork, the root will be reset to the parentsanon_vma*/
Sure, I'll change the comment.
Quoted 2 lines
Else, just leave the initialisation of the root where it was but only init the refcount here.
Ah, that would lead to problems. We use put_anon_vma() to free in the create error path, and __put_anon_vma() will also check the anon_vma->root, so by not setting it the error path will explode.
PATCH 11/28 mm: Preemptible mmu_gather
In reply to Peter ZijlstraMake mmu_gather preemptible by using a small on stack list and use an option allocation to speed things up.
Preemptible mmu_gather is desired in general and usable once i_mmap_lock becomes a mutex. Doing it before the mutex conversion saves us from having to rework the code by moving the mmu_gather bits inside the i_mmap_lock.
--- fs/exec.c | 10 ++++----- include/asm-generic/tlb.h | 51 +++++++++++++++++++++++++++++----------------- include/linux/mm.h | 2 - mm/memory.c | 27 +++++------------------- mm/mmap.c | 16 +++++++------- 5 files changed, 53 insertions(+), 53 deletions(-)
fs/exec.c +5 -5
@@ -503,7 +503,7 @@ static int shift_arg_pages(struct vm_areunsigned long length = old_end - old_start;unsigned long new_start = old_start - shift;unsigned long new_end = old_end - shift; -struct mmu_gather *tlb; +struct mmu_gather tlb;BUG_ON (new_start > new_end);
@@ -529,12 +529,12 @@ static int shift_arg_pages(struct vm_arereturn -ENOMEM ;lru_add_drain (); - tlb =tlb_gather_mmu (mm,0 ); +tlb_gather_mmu (&tlb, mm,0 );if (new_end > old_start) {/* * when the old and new regions overlap clear from new_end. */ -free_pgd_range (tlb, new_end, old_end, new_end, +free_pgd_range (&tlb, new_end, old_end, new_end, vma->vm_next ? vma->vm_next->vm_start :0 ); }else {/*
@@ -543,10 +543,10 @@ static int shift_arg_pages(struct vm_are* have constraints on va-space that make this illegal (IA64) - * for the others its just a little faster. */ -free_pgd_range (tlb, old_start, old_end, new_end, +free_pgd_range (&tlb, old_start, old_end, new_end, vma->vm_next ? vma->vm_next->vm_start :0 ); } -tlb_finish_mmu (tlb, new_end, old_end); +tlb_finish_mmu (&tlb, new_end, old_end);/* * Shrink the vma to just the new range. Always succeeds.
include/asm-generic/tlb.h +33 -18
97 lines not on this page · raw message
include/linux/mm.h +1 -1
@@ -760,7 +760,7 @@ int zap_vma_ptes(struct vm_area_struct * unsigned long size);unsigned long zap_page_range (struct vm_area_struct *vma,unsigned long address,unsigned long size,struct zap_details *); -unsigned long unmap_vmas (struct mmu_gather **tlb, +unsigned long unmap_vmas (struct mmu_gather *tlb,struct vm_area_struct *start_vma,unsigned long start_addr,unsigned long end_addr,unsigned long *nr_accounted,struct zap_details *);
mm/memory.c +6 -21
@@ -1095,17 +1095,14 @@ static unsigned long unmap_page_range(st* ensure that any thus-far unmapped pages are flushed before unmap_vmas() * drops the lock and schedules. */ -unsigned long unmap_vmas (struct mmu_gather **tlbp, +unsigned long unmap_vmas (struct mmu_gather *tlb,struct vm_area_struct *vma,unsigned long start_addr,unsigned long end_addr,unsigned long *nr_accounted,struct zap_details *details) {long zap_work =ZAP_BLOCK_SIZE ; -unsigned long tlb_start =0 ;/* For tlb_finish_mmu */ -int tlb_start_valid =0 ;unsigned long start = start_addr;spinlock_t *i_mmap_lock = details? details->i_mmap_lock:NULL ; -int fullmm = (*tlbp)->fullmm;struct mm_struct *mm = vma->vm_mm;mmu_notifier_invalidate_range_start (mm, start_addr, end_addr);
@@ -1126,11 +1123,6 @@ unsigned long unmap_vmas(struct mmu_gathuntrack_pfn_vma (vma,0 ,0 );while (start != end) { -if (!tlb_start_valid) { - tlb_start = start; - tlb_start_valid =1 ; - } -if (unlikely (is_vm_hugetlb_page (vma))) {/* * It is undesirable to test vma->vm_file as it
@@ -1151,7 +1143,7 @@ unsigned long unmap_vmas(struct mmu_gath start = end; }else - start =unmap_page_range (*tlbp, vma, + start =unmap_page_range (tlb, vma, start, end, &zap_work, details);if (zap_work >0 ) {
@@ -1159,19 +1151,13 @@ unsigned long unmap_vmas(struct mmu_gathbreak ; } -tlb_finish_mmu (*tlbp, tlb_start, start); -if (need_resched () || (i_mmap_lock &&spin_needbreak (i_mmap_lock))) { -if (i_mmap_lock) { - *tlbp =NULL ; +if (i_mmap_lock) goto out; - }cond_resched (); } - *tlbp =tlb_gather_mmu (vma->vm_mm, fullmm); - tlb_start_valid =0 ; zap_work =ZAP_BLOCK_SIZE ; } }
@@ -1191,16 +1177,15 @@ unsigned long zap_page_range(struct vm_a unsigned long size, struct zap_details *details) { struct mm_struct *mm = vma->vm_mm; -struct mmu_gather *tlb; +struct mmu_gather tlb;unsigned long end = address + size;unsigned long nr_accounted =0 ;lru_add_drain (); - tlb =tlb_gather_mmu (mm,0 ); +tlb_gather_mmu (&tlb, mm,0 );update_hiwater_rss (mm); end =unmap_vmas (&tlb, vma, address, end, &nr_accounted, details); -if (tlb) -tlb_finish_mmu (tlb, address, end); +tlb_finish_mmu (&tlb, address, end);return end; }
mm/mmap.c +8 -8
@@ -1844,17 +1844,17 @@ static void unmap_region(struct mm_struc unsigned long start, unsigned long end) {struct vm_area_struct *next = prev? prev->vm_next: mm->mmap; -struct mmu_gather *tlb; +struct mmu_gather tlb;unsigned long nr_accounted =0 ;lru_add_drain (); - tlb =tlb_gather_mmu (mm,0 ); +tlb_gather_mmu (&tlb, mm,0 );update_hiwater_rss (mm);unmap_vmas (&tlb, vma, start, end, &nr_accounted,NULL );vm_unacct_memory (nr_accounted); -free_pgtables (tlb, vma, prev? prev->vm_end:FIRST_USER_ADDRESS , +free_pgtables (&tlb, vma, prev? prev->vm_end:FIRST_USER_ADDRESS , next? next->vm_start:0 ); -tlb_finish_mmu (tlb, start, end); +tlb_finish_mmu (&tlb, start, end); }/*
@@ -2190,7 +2190,7 @@ EXPORT_SYMBOL(do_brk);/* Release all mmaps. */ void exit_mmap (struct mm_struct *mm) { -struct mmu_gather *tlb; +struct mmu_gather tlb;struct vm_area_struct *vma;unsigned long nr_accounted =0 ;unsigned long end;
@@ -2215,14 +2215,14 @@ void exit_mmap(struct mm_struct *mm)lru_add_drain ();flush_cache_mm (mm); - tlb =tlb_gather_mmu (mm,1 ); +tlb_gather_mmu (&tlb, mm,1 );/* update_hiwater_rss(mm) here? but nobody should be looking */ /* Use -1 here to ensure all VMAs in the mm are unmapped */ end =unmap_vmas (&tlb, vma,0 ,-1 , &nr_accounted,NULL );vm_unacct_memory (nr_accounted); -free_pgtables (tlb, vma,FIRST_USER_ADDRESS ,0 ); -tlb_finish_mmu (tlb,0 , end); +free_pgtables (&tlb, vma,FIRST_USER_ADDRESS ,0 ); +tlb_finish_mmu (&tlb,0 , end);/* * Walk the list again, actually closing and freeing it,
PATCH 12/28 powerpc: Preemptible mmu_gather
In reply to Peter ZijlstraFix up powerpc to the new mmu_gather stuffs.
PPC has an extra batching queue to RCU free the actual pagetable allocations, use the ARCH extentions for that for now.
For the ppc64_tlb_batch, which tracks the vaddrs to unhash from the hardware hash-table, keep using per-cpu arrays but flush on context switch and use a TLF bit to track the laxy_mmu state.
--- arch/powerpc/include/asm/pgalloc.h | 4 ++-- arch/powerpc/include/asm/thread_info.h | 2 ++ arch/powerpc/include/asm/tlb.h | 10 ++++++++++ arch/powerpc/kernel/process.c | 19 +++++++++++++++++++ arch/powerpc/mm/pgtable.c | 14 ++++---------- arch/powerpc/mm/tlb_hash32.c | 2 +- arch/powerpc/mm/tlb_hash64.c | 12 +++++++----- arch/powerpc/mm/tlb_nohash.c | 2 +- 8 files changed, 46 insertions(+), 19 deletions(-)
arch/powerpc/include/asm/tlb.h +10 -0
@@ -28,6 +28,16 @@#define tlb_start_vma (tlb, vma) do { } while (0)#define tlb_end_vma (tlb, vma) do { } while (0) +#define HAVE_ARCH_MMU_GATHER 1 + +struct pte_freelist_batch ; + +struct arch_mmu_gather { +struct pte_freelist_batch *batch; +}; + +#define ARCH_MMU_GATHER_INIT (struct arch_mmu_gather){ .batch = NULL, } +extern void tlb_flush (struct mmu_gather *tlb);/* Get the generic bits... */
arch/powerpc/kernel/process.c +19 -0
@@ -392,6 +392,9 @@ struct task_struct *__switch_to(struct tstruct thread_struct *new_thread, *old_thread;unsigned long flags;struct task_struct *last; +#ifdef CONFIG_PPC64 +struct ppc64_tlb_batch *batch; +#endif #ifdef CONFIG_SMP /* avoid complexity of lazy save/restore of fpu
@@ -482,6 +485,14 @@ struct task_struct *__switch_to(struct t old_thread->accum_tb += (current_tb - start_tb); new_thread->start_tb = current_tb; } + + batch = &__get_cpu_var (ppc64_tlb_batch); +if (batch->active) { +task_thread_info (prev)->local_flags |= _TLF_LAZY_MMU; +if (batch->index) +__flush_tlb_pending (batch); + batch->active =0 ; + }#endif local_irq_save (flags);
@@ -498,6 +509,14 @@ struct task_struct *__switch_to(struct thard_irq_disable (); last =_switch (old_thread, new_thread); +#ifdef CONFIG_PPC64 +if (task_thread_info (new)->local_flags & _TLF_LAZY_MMU) { +task_thread_info (new)->local_flags &= ~_TLF_LAZY_MMU; + batch = &__get_cpu_var (ppc64_tlb_batch); + batch->active =1 ; + } +#endif +local_irq_restore (flags);return last;
arch/powerpc/mm/pgtable.c +4 -10
@@ -33,8 +33,6 @@#include "mmu_decl.h" -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -#ifdef CONFIG_SMP /*
@@ -43,7 +41,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_ga* freeing a page table page that is being walked without locks */ -static DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);static unsigned long pte_freelist_forced_free;struct pte_freelist_batch
@@ -98,12 +95,10 @@ static void pte_free_submit(struct pte_fvoid pgtable_free_tlb (struct mmu_gather *tlb,void *table,unsigned shift) { -/* This is safe since tlb_gather_mmu has disabled preemption */ -struct pte_freelist_batch **batchp = &__get_cpu_var (pte_freelist_cur); +struct pte_freelist_batch **batchp = &tlb->arch.batch;unsigned long pgf; -if (atomic_read (&tlb->mm->mm_users) <2 || -cpumask_equal (mm_cpumask (tlb->mm),cpumask_of (smp_processor_id ()))){ +if (atomic_read (&tlb->mm->mm_users) <2 ) {pgtable_free (table, shift);return ; }
@@ -125,10 +120,9 @@ void pgtable_free_tlb(struct mmu_gather } } -void pte_free_finish (void ) +void pte_free_finish (struct mmu_gather *tlb) { -/* This is safe since tlb_gather_mmu has disabled preemption */ -struct pte_freelist_batch **batchp = &__get_cpu_var (pte_freelist_cur); +struct pte_freelist_batch **batchp = &tlb->arch.batch;if (*batchp ==NULL )return ;
arch/powerpc/mm/tlb_hash64.c +7 -5
@@ -38,13 +38,11 @@ DEFINE_PER_CPU(struct ppc64_tlb_batch, p* neesd to be flushed. This function will either perform the flush * immediately or will batch it up if the current CPU has an active * batch on it. -* -* Must be called from within some kind of spinlock/non-preempt region... */ void hpte_need_flush (struct mm_struct *mm,unsigned long addr,pte_t *ptep,unsigned long pte,int huge) { -struct ppc64_tlb_batch *batch = &__get_cpu_var (ppc64_tlb_batch); +struct ppc64_tlb_batch *batch = &get_cpu_var (ppc64_tlb_batch);unsigned long vsid, vaddr;unsigned int psize;int ssize;
@@ -99,6 +97,7 @@ void hpte_need_flush(struct mm_struct *m*/ if (!batch->active) {flush_hash_page (vaddr, rpte, psize, ssize,0 ); +put_cpu_var (ppc64_tlb_batch);return ; }
@@ -127,6 +126,7 @@ void hpte_need_flush(struct mm_struct *m batch->index = ++i;if (i >=PPC64_TLB_BATCH_NR )__flush_tlb_pending (batch); +put_cpu_var (ppc64_tlb_batch); }/*
@@ -155,7 +155,7 @@ void __flush_tlb_pending(struct ppc64_tlvoid tlb_flush (struct mmu_gather *tlb) { -struct ppc64_tlb_batch *tlbbatch = &__get_cpu_var (ppc64_tlb_batch); +struct ppc64_tlb_batch *tlbbatch = &get_cpu_var (ppc64_tlb_batch);/* If there's a TLB batch pending, then we must flush it because the * pages are going to be freed and we really don't want to have a CPU
@@ -164,8 +164,10 @@ void tlb_flush(struct mmu_gather *tlb)if (tlbbatch->index)__flush_tlb_pending (tlbbatch); +put_cpu_var (ppc64_tlb_batch); +/* Push out batch of freed page tables */ -pte_free_finish (); +pte_free_finish (tlb); }/**
arch/powerpc/include/asm/thread_info.h +2 -0
@@ -139,10 +139,12 @@ static inline struct thread_info *curren#define TLF_NAPPING 0/* idle thread enabled NAP mode */ #define TLF_SLEEPING 1/* suspend code enabled SLEEP mode */ #define TLF_RESTORE_SIGMASK 2/* Restore signal mask in do_signal */ +#define TLF_LAZY_MMU 3/* tlb_batch is active */ #define _TLF_NAPPING (1 << TLF_NAPPING)#define _TLF_SLEEPING (1 << TLF_SLEEPING)#define _TLF_RESTORE_SIGMASK (1 << TLF_RESTORE_SIGMASK) +#define _TLF_LAZY_MMU (1 << TLF_LAZY_MMU)#ifndef __ASSEMBLY__#define HAVE_SET_RESTORE_SIGMASK 1
arch/powerpc/include/asm/pgalloc.h +2 -2
@@ -32,13 +32,13 @@ static inline void pte_free(struct mm_st#ifdef CONFIG_SMP extern void pgtable_free_tlb (struct mmu_gather *tlb,void *table,unsigned shift); -extern void pte_free_finish (void ); +extern void pte_free_finish (struct mmu_gather *tlb);#else /* CONFIG_SMP */ static inline void pgtable_free_tlb (struct mmu_gather *tlb,void *table,unsigned shift) {pgtable_free (table, shift); } -static inline void pte_free_finish (void ) { } +static inline void pte_free_finish (struct mmu_gather *tlb) { }#endif /* !CONFIG_SMP */ static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage,
arch/powerpc/mm/tlb_hash32.c +1 -1
@@ -73,7 +73,7 @@ void tlb_flush(struct mmu_gather *tlb) }/* Push out batch of freed page tables */ -pte_free_finish (); +pte_free_finish (tlb); }/*
arch/powerpc/mm/tlb_nohash.c +1 -1
@@ -298,7 +298,7 @@ void tlb_flush(struct mmu_gather *tlb)flush_tlb_mm (tlb->mm);/* Push out batch of freed page tables */ -pte_free_finish (); +pte_free_finish (tlb); }/*
PATCH 13/28 sparc: Preemptible mmu_gather
In reply to Peter ZijlstraRework the sparc mmu_gather usage to conform to the new world order :-)
Sparc mmu_gather does two things:
- tracks vaddrs to unhash
- tracks pages to free
Split these two things like powerpc has done and keep the vaddrs in per-cpu data structures and flush them on context switch.
The remaining bits can then use the generic mmu_gather.
--- arch/sparc/include/asm/pgalloc_64.h | 3 + arch/sparc/include/asm/tlb_64.h | 91 ++--------------------------------- arch/sparc/include/asm/tlbflush_64.h | 12 +++- arch/sparc/mm/tlb.c | 42 +++++++++------- arch/sparc/mm/tsb.c | 15 +++-- 5 files changed, 51 insertions(+), 112 deletions(-)
arch/sparc/include/asm/pgalloc_64.h +3 -0
@@ -78,4 +78,7 @@ static inline void check_pgt_cache(void) quicklist_trim(0, NULL, 25, 16); } +#define __pte_free_tlb (tlb, pte, addr) pte_free((tlb)->mm, pte) +#define __pmd_free_tlb (tlb, pmd, addr) pmd_free((tlb)->mm, pmd) +#endif /* _SPARC64_PGALLOC_H */
arch/sparc/include/asm/tlb_64.h +6 -85
110 lines not on this page · raw message
arch/sparc/include/asm/tlbflush_64.h +10 -2
@@ -5,9 +5,17 @@#include <asm/mmu_context.h> /* TSB flush operations. */ -struct mmu_gather ; + +#define TLB_BATCH_NR 192 + +struct tlb_batch { +struct mm_struct *mm; +unsigned long tlb_nr; +unsigned long vaddrs[TLB_BATCH_NR ]; +}; +extern void flush_tsb_kernel_range (unsigned long start,unsigned long end); -extern void flush_tsb_user (struct mmu_gather *mp); +extern void flush_tsb_user (struct tlb_batch *tb);/* TLB flush operations. */
arch/sparc/mm/tlb.c +24 -18
78 lines not on this page · raw message
arch/sparc/mm/tsb.c +8 -7
@@ -47,12 +47,13 @@ void flush_tsb_kernel_range(unsigned lon } } -static void __flush_tsb_one (struct mmu_gather *mp,unsigned long hash_shift,unsigned long tsb,unsigned long nentries) +static void __flush_tsb_one (struct tlb_batch *tb,unsigned long hash_shift, +unsigned long tsb,unsigned long nentries) {unsigned long i; -for (i =0 ; i < mp->tlb_nr; i++) { -unsigned long v = mp->vaddrs[i]; +for (i =0 ; i < tb->tlb_nr; i++) { +unsigned long v = tb->vaddrs[i];unsigned long tag, ent, hash; v &= ~0x1UL ;
@@ -65,9 +66,9 @@ static void __flush_tsb_one(struct mmu_g } } -void flush_tsb_user (struct mmu_gather *mp) +void flush_tsb_user (struct tlb_batch *tb) { -struct mm_struct *mm = mp->mm; +struct mm_struct *mm = tb->mm;unsigned long nentries, base, flags;spin_lock_irqsave (&mm->context.lock, flags);
@@ -76,7 +77,7 @@ void flush_tsb_user(struct mmu_gather *m nentries = mm->context.tsb_block[MM_TSB_BASE ].tsb_nentries;if (tlb_type == cheetah_plus || tlb_type == hypervisor) base =__pa (base); -__flush_tsb_one (mp,PAGE_SHIFT , base, nentries); +__flush_tsb_one (tb,PAGE_SHIFT , base, nentries);#ifdef CONFIG_HUGETLB_PAGE if (mm->context.tsb_block[MM_TSB_HUGE ].tsb) {
@@ -84,7 +85,7 @@ void flush_tsb_user(struct mmu_gather *m nentries = mm->context.tsb_block[MM_TSB_HUGE ].tsb_nentries;if (tlb_type == cheetah_plus || tlb_type == hypervisor) base =__pa (base); - __flush_tsb_one(mp, HPAGE_SHIFT, base, nentries); + __flush_tsb_one(tb, HPAGE_SHIFT, base, nentries); }#endif spin_unlock_irqrestore (&mm->context.lock, flags);
PATCH 14/28 s390: preemptible mmu_gather
In reply to Peter ZijlstraFrom: Martin Schwidefsky <[email protected]>
Adapt the stand-alone s390 mmu_gather implementation to the new preemptible mmu_gather interface.
--- arch/s390/include/asm/tlb.h | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-)
arch/s390/include/asm/tlb.h +25 -18
@@ -28,45 +28,51 @@#include <asm/smp.h> #include <asm/tlbflush.h> -#ifndef CONFIG_SMP -#define TLB_NR_PTRS 1 -#else -#define TLB_NR_PTRS 508 -#endif -struct mmu_gather {struct mm_struct *mm;unsigned int fullmm;unsigned int nr_ptes;unsigned int nr_pxds; -void *array[TLB_NR_PTRS ]; +unsigned int max; +void **array; +void *local[8 ]; }; -DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); - -static inline struct mmu_gather *tlb_gather_mmu (struct mm_struct *mm, -unsigned int full_mm_flush) +static inline void __tlb_alloc_pages (struct mmu_gather *tlb) { -struct mmu_gather *tlb = &get_cpu_var (mmu_gathers); +unsigned long addr =__get_free_pages (GFP_ATOMIC ,0 ); + +if (addr) { + tlb->array = (void *) addr; + tlb->max =PAGE_SIZE /sizeof (void *); + } +} +static inline void tlb_gather_mmu (struct mmu_gather *tlb, +struct mm_struct *mm, +unsigned int full_mm_flush) +{ tlb->mm = mm; + tlb->max =ARRAY_SIZE (tlb->local); + tlb->array = tlb->local; tlb->fullmm = full_mm_flush || (num_online_cpus () ==1 ) || (atomic_read (&mm->mm_users) <=1 && mm == current->active_mm); - tlb->nr_ptes =0 ; - tlb->nr_pxds =TLB_NR_PTRS ;if (tlb->fullmm)__tlb_flush_mm (mm); -return tlb; +else +__tlb_alloc_pages (tlb); + tlb->nr_ptes =0 ; + tlb->nr_pxds = tlb->max; }static inline void tlb_flush_mmu (struct mmu_gather *tlb,unsigned long start,unsigned long end) { -if (!tlb->fullmm && (tlb->nr_ptes >0 || tlb->nr_pxds <TLB_NR_PTRS )) +if (!tlb->fullmm && (tlb->nr_ptes >0 || tlb->nr_pxds < tlb->max))__tlb_flush_mm (tlb->mm);while (tlb->nr_ptes >0 )pte_free (tlb->mm, tlb->array[--tlb->nr_ptes]); -while (tlb->nr_pxds <TLB_NR_PTRS ) +while (tlb->nr_pxds < tlb->max)/* pgd_free frees the pointer as region or segment table */ pgd_free (tlb->mm, tlb->array[tlb->nr_pxds++]); }
@@ -79,7 +85,8 @@ static inline void tlb_finish_mmu(struct/* keep the page table cache within bounds */ check_pgt_cache (); -put_cpu_var (mmu_gathers); +if (tlb->array != tlb->local) +free_pages ((unsigned long ) tlb->array,0 ); }/*
PATCH 15/28 arm: Preemptible mmu_gather
In reply to Peter ZijlstraFix up the arm mmu_gahter code to conform to the new API.
--- arch/arm/include/asm/tlb.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
arch/arm/include/asm/tlb.h +2 -10
@@ -40,17 +40,11 @@ struct mmu_gather {unsigned long range_end; }; -DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); - -static inline struct mmu_gather * -tlb_gather_mmu (struct mm_struct *mm,unsigned int full_mm_flush) +static inline void +tlb_gather_mmu (struct mmu_gather *tlb,struct mm_struct *mm,unsigned int full_mm_flush) { -struct mmu_gather *tlb = &get_cpu_var (mmu_gathers); - tlb->mm = mm; tlb->fullmm = full_mm_flush; - -return tlb; } static inline void
@@ -61,8 +55,6 @@ tlb_finish_mmu(struct mmu_gather *tlb, u/* keep the page table cache within bounds */ check_pgt_cache (); - -put_cpu_var (mmu_gathers); }/*
PATCH 16/28 sh: Preemptible mmu_gather
In reply to Peter ZijlstraFix up the arm mmu_gahter code to conform to the new API.
--- arch/sh/include/asm/tlb.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
arch/sh/include/asm/tlb.h +2 -10
@@ -23,8 +23,6 @@ struct mmu_gather {unsigned long start, end; }; -DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); -static inline void init_tlb_gather (struct mmu_gather *tlb) { tlb->start =TASK_SIZE ;
@@ -36,17 +34,13 @@ static inline void init_tlb_gather(struc } } -static inline struct mmu_gather * -tlb_gather_mmu (struct mm_struct *mm,unsigned int full_mm_flush) +static inline void +tlb_gather_mmu (struct mmu_gather *tlb,struct mm_struct *mm,unsigned int full_mm_flush) { -struct mmu_gather *tlb = &get_cpu_var (mmu_gathers); - tlb->mm = mm; tlb->fullmm = full_mm_flush;init_tlb_gather (tlb); - -return tlb; } static inline void
@@ -57,8 +51,6 @@ tlb_finish_mmu(struct mmu_gather *tlb, u/* keep the page table cache within bounds */ check_pgt_cache (); - -put_cpu_var (mmu_gathers); } static inline void
Peter Zijlstra
maintainerRe: [PATCH 16/28] sh: Preemptible mmu_gather
Quoted 2 lines · Peter Zijlstra
Fix up the arm
mmu_gahtercode to conform to the new API.
urhm,. copy/paste gone wild, clearly that's the SH code for this patch ;-)
PATCH 17/28 um: Preemptible mmu_gather
In reply to Peter ZijlstraFix up the um mmu_gather code to conform to the new API.
--- arch/um/include/asm/tlb.h | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-)
arch/um/include/asm/tlb.h +2 -14
@@ -22,9 +22,6 @@ struct mmu_gather {unsigned int fullmm;/* non-zero means full mm flush */ }; -/* Users of the generic TLB shootdown code must declare this storage space. */ -DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); -static inline void __tlb_remove_tlb_entry (struct mmu_gather *tlb,pte_t *ptep,unsigned long address) {
@@ -47,20 +44,13 @@ static inline void init_tlb_gather(struc } } -/* tlb_gather_mmu -* Return a pointer to an initialized struct mmu_gather. -*/ -static inline struct mmu_gather * -tlb_gather_mmu (struct mm_struct *mm,unsigned int full_mm_flush) +static inline void +tlb_gather_mmu (struct mmu_gather *tlb,struct mm_struct *mm,unsigned int full_mm_flush) { -struct mmu_gather *tlb = &get_cpu_var (mmu_gathers); - tlb->mm = mm; tlb->fullmm = full_mm_flush;init_tlb_gather (tlb); - -return tlb; } extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
@@ -87,8 +77,6 @@ tlb_finish_mmu(struct mmu_gather *tlb, u/* keep the page table cache within bounds */ check_pgt_cache (); - -put_cpu_var (mmu_gathers); }/* tlb_remove_page
PATCH 18/28 ia64: Preemptible mmu_gather
In reply to Peter ZijlstraFix up the ia64 mmu_gather code to conform to the new API.
--- arch/ia64/include/asm/tlb.h | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-)
arch/ia64/include/asm/tlb.h +25 -13
@@ -47,21 +47,21 @@#include <asm/machvec.h> #ifdef CONFIG_SMP -# define FREE_PTE_NR 2048# define tlb_fast_mode (tlb) ((tlb)->nr == ~0U)#else -# define FREE_PTE_NR 0# define tlb_fast_mode (tlb) (1)#endif struct mmu_gather {struct mm_struct *mm;unsigned int nr;/* == ~0U => fast mode */ +unsigned int max;unsigned char fullmm;/* non-zero means full mm flush */ unsigned char need_flush;/* really unmapped some PTEs? */ unsigned long start_addr;unsigned long end_addr; -struct page *pages[FREE_PTE_NR ]; +struct page **pages; +struct page *local[8 ]; };struct ia64_tr_entry {
@@ -90,9 +90,6 @@ extern struct ia64_tr_entry *ia64_idtrs[#define RR_RID_MASK 0x00000000ffffff00L#define RR_TO_RID (val) ((val >> 8) & 0xffffff) -/* Users of the generic TLB shootdown code must declare this storage space. */ -DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); -/* * Flush the TLB for address range START to END and, if not in fast mode, release the * freed pages that where gathered up to this point.
@@ -147,15 +144,25 @@ ia64_tlb_flush_mmu (struct mmu_gather *t } } -/* -* Return a pointer to an initialized struct mmu_gather. -*/ -static inline struct mmu_gather * -tlb_gather_mmu (struct mm_struct *mm,unsigned int full_mm_flush) +static inline void __tlb_alloc_pages (struct mmu_gather *tlb) +{ +unsigned long addr =__get_free_pages (GFP_ATOMIC ,0 ); + +if (addr) { + tlb->pages = (void *)addr; + tlb->max =PAGE_SIZE /sizeof (void *); + } +} + + +static inline void +tlb_gather_mmu (struct mmu_gather *tlb,struct mm_struct *mm,unsigned int full_mm_flush) {struct mmu_gather *tlb = &get_cpu_var (mmu_gathers); tlb->mm = mm; + tlb->max =ARRAY_SIZE (tlb->local); + tlb->pages = tlb->local;/* * Use fast mode if only 1 CPU is online. *
@@ -191,7 +198,8 @@ tlb_finish_mmu (struct mmu_gather *tlb,/* keep the page table cache within bounds */ check_pgt_cache (); -put_cpu_var (mmu_gathers); +if (tlb->pages != tlb->local) +free_pages ((unsigned long )tlb->pages,0 ); }/*
@@ -208,8 +216,12 @@ tlb_remove_page (struct mmu_gather *tlb,free_page_and_swap_cache (page);return ; } + +if (!tlb->nr && tlb->pages == tlb->local) +__tlb_alloc_pages (tlb); + tlb->pages[tlb->nr++] = page; -if (tlb->nr >=FREE_PTE_NR ) +if (tlb->nr >= tlb->max)ia64_tlb_flush_mmu (tlb, tlb->start_addr, tlb->end_addr); }
PATCH 19/28 mm, powerpc: Move the RCU page-table freeing into generic code
In reply to Peter ZijlstraIn case other architectures require RCU freed page-tables to implement gup_fast() and software filled hashes and similar things, provide the means to do so by moving the logic into generic code.
--- arch/powerpc/include/asm/pgalloc.h | 23 +++++++- arch/powerpc/include/asm/tlb.h | 10 --- arch/powerpc/mm/pgtable.c | 99 ------------------------------------- arch/powerpc/mm/tlb_hash32.c | 3 - arch/powerpc/mm/tlb_hash64.c | 3 - arch/powerpc/mm/tlb_nohash.c | 3 - include/asm-generic/tlb.h | 57 +++++++++++++++++++-- mm/memory.c | 81 ++++++++++++++++++++++++++++++ 8 files changed, 153 insertions(+), 126 deletions(-)
arch/powerpc/include/asm/pgalloc.h +20 -3
@@ -31,14 +31,31 @@ static inline void pte_free(struct mm_st#endif #ifdef CONFIG_SMP -extern void pgtable_free_tlb (struct mmu_gather *tlb,void *table,unsigned shift); -extern void pte_free_finish (struct mmu_gather *tlb); +#define HAVE_ARCH_RCU_TABLE_FREE + +struct mmu_gather ; +extern void tlb_remove_table (struct mmu_gather *,void *); + +static inline void pgtable_free_tlb (struct mmu_gather *tlb,void *table,int shift) +{ +unsigned long pgf = (unsigned long )table; +BUG_ON (shift >MAX_PGTABLE_INDEX_SIZE ); + pgf |= shift; +tlb_remove_table (tlb, (void *)pgf); +} + +static inline void __tlb_remove_table (void *_table) +{ +void *table = (void *)((unsigned long )_table & ~MAX_PGTABLE_INDEX_SIZE ); +unsigned shift = (unsigned long )_table &MAX_PGTABLE_INDEX_SIZE ; + +pgtable_free (table, shift); +}#else /* CONFIG_SMP */ static inline void pgtable_free_tlb (struct mmu_gather *tlb,void *table,unsigned shift) {pgtable_free (table, shift); } -static inline void pte_free_finish (struct mmu_gather *tlb) { }#endif /* !CONFIG_SMP */ static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage,
arch/powerpc/include/asm/tlb.h +0 -10
@@ -28,16 +28,6 @@#define tlb_start_vma (tlb, vma) do { } while (0)#define tlb_end_vma (tlb, vma) do { } while (0) -#define HAVE_ARCH_MMU_GATHER 1 - -struct pte_freelist_batch ; - -struct arch_mmu_gather { -struct pte_freelist_batch *batch; -}; - -#define ARCH_MMU_GATHER_INIT (struct arch_mmu_gather){ .batch = NULL, } -extern void tlb_flush (struct mmu_gather *tlb);/* Get the generic bits... */
arch/powerpc/mm/pgtable.c +0 -99
105 lines not on this page · raw message
arch/powerpc/mm/tlb_hash32.c +0 -3
@@ -71,9 +71,6 @@ void tlb_flush(struct mmu_gather *tlb)*/ _tlbia (); } - -/* Push out batch of freed page tables */ -pte_free_finish (tlb); }/*
arch/powerpc/mm/tlb_hash64.c +0 -3
@@ -165,9 +165,6 @@ void tlb_flush(struct mmu_gather *tlb)__flush_tlb_pending (tlbbatch);put_cpu_var (ppc64_tlb_batch); - -/* Push out batch of freed page tables */ -pte_free_finish (tlb); }/**
arch/powerpc/mm/tlb_nohash.c +0 -3
@@ -296,9 +296,6 @@ EXPORT_SYMBOL(flush_tlb_range);void tlb_flush (struct mmu_gather *tlb) {flush_tlb_mm (tlb->mm); - -/* Push out batch of freed page tables */ -pte_free_finish (tlb); }/*
include/asm-generic/tlb.h +52 -5
83 lines not on this page · raw message
mm/memory.c +78 -0
84 lines not on this page · raw message
PATCH 20/28 sparc64: Kill page table quicklists.
In reply to Peter ZijlstraFrom: David S. Miller <[email protected]>
They are pointless and make it harder to use RCU page table freeing and share code with other architectures.
BTW, this is the second time this has happened, see commit 3c936465249f863f322154ff1aaa628b84ee5750 ("[SPARC64]: Kill pgtable quicklists and use SLAB.")
:-)
LKML-Reference: <[email protected]>
--- arch/sparc/Kconfig | 4 ---- arch/sparc/include/asm/pgalloc_64.h | 32 +++++++++++++++----------------- arch/sparc/mm/tsb.c | 11 +++++++++++ 3 files changed, 26 insertions(+), 21 deletions(-)
arch/sparc/Kconfig +0 -4
@@ -82,10 +82,6 @@ config IOMMU_HELPER bool default y if SPARC64 -config QUICKLIST - bool - default y if SPARC64 - config STACKTRACE_SUPPORT bool default y if SPARC64
arch/sparc/include/asm/pgalloc_64.h +15 -17
@@ -5,7 +5,6 @@#include <linux/sched.h> #include <linux/mm.h> #include <linux/slab.h> -#include <linux/quicklist.h> #include <asm/spitfire.h> #include <asm/cpudata.h>
@@ -14,69 +13,68 @@/* Page table allocation/freeing. */ +extern struct kmem_cache *pgtable_cache; +static inline pgd_t *pgd_alloc (struct mm_struct *mm) { -return quicklist_alloc (0 ,GFP_KERNEL ,NULL ); +return kmem_cache_alloc (pgtable_cache,GFP_KERNEL ); }static inline void pgd_free (struct mm_struct *mm,pgd_t *pgd) { -quicklist_free (0 ,NULL , pgd); +kmem_cache_free (pgtable_cache, pgd); }#define pud_populate (MM ,PUD ,PMD ) pud_set(PUD, PMD)static inline pmd_t *pmd_alloc_one (struct mm_struct *mm,unsigned long addr) { -return quicklist_alloc (0 ,GFP_KERNEL ,NULL ); +return kmem_cache_alloc (pgtable_cache, +GFP_KERNEL |__GFP_REPEAT); }static inline void pmd_free (struct mm_struct *mm,pmd_t *pmd) { -quicklist_free (0 ,NULL , pmd); +kmem_cache_free (pgtable_cache, pmd); }static inline pte_t *pte_alloc_one_kernel (struct mm_struct *mm,unsigned long address) { -return quicklist_alloc (0 ,GFP_KERNEL ,NULL ); +return (pte_t *)__get_free_page (GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO); }static inline pgtable_t pte_alloc_one (struct mm_struct *mm,unsigned long address) {struct page *page; -void *pg; +pte_t *pte; - pg =quicklist_alloc (0 ,GFP_KERNEL ,NULL ); -if (!pg) + pte =pte_alloc_one_kernel (mm, address); +if (!pte)return NULL ; - page =virt_to_page (pg); + page =virt_to_page (pte);pgtable_page_ctor (page);return page; }static inline void pte_free_kernel (struct mm_struct *mm,pte_t *pte) { -quicklist_free (0 ,NULL , pte); +free_page ((unsigned long )pte); }static inline void pte_free (struct mm_struct *mm,pgtable_t ptepage) {pgtable_page_dtor (ptepage); -quicklist_free_page (0 ,NULL , ptepage); +__free_page (ptepage); } -#define pmd_populate_kernel (MM ,PMD ,PTE ) pmd_set(PMD, PTE)#define pmd_populate (MM ,PMD ,PTE_PAGE ) \ pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE))#define pmd_pgtable (pmd) pmd_page(pmd) -static inline void check_pgt_cache (void ) -{ -quicklist_trim (0 ,NULL ,25 ,16 ); -} +#define check_pgt_cache () do { } while (0)#define __pte_free_tlb (tlb, pte, addr) pte_free((tlb)->mm, pte)#define __pmd_free_tlb (tlb, pmd, addr) pmd_free((tlb)->mm, pmd)
arch/sparc/mm/tsb.c +11 -0
@@ -236,6 +236,8 @@ static void setup_tsb_params(struct mm_s } } +struct kmem_cache *pgtable_cache__read_mostly ; +static struct kmem_cache *tsb_caches[8 ]__read_mostly ;static const char *tsb_cache_names[8 ] = {
@@ -253,6 +255,15 @@ void __init pgtable_cache_init(void) {unsigned long i; + pgtable_cache =kmem_cache_create ("pgtable_cache" , +PAGE_SIZE ,PAGE_SIZE , +0 , + _clear_page); +if (!pgtable_cache) { +prom_printf ("pgtable_cache_init(): Could not create!\n" ); +prom_halt (); + } +for (i =0 ; i <8 ; i++) {unsigned long size =8192 << i;const char *name = tsb_cache_names[i];
PATCH 21/28 sparc64: Use RCU page table freeing.
In reply to Peter ZijlstraFrom: David S. Miller <[email protected]>
LKML-Reference: <[email protected]>
--- arch/sparc/include/asm/pgalloc_64.h | 49 ++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-)
arch/sparc/include/asm/pgalloc_64.h +47 -2
@@ -76,7 +76,52 @@ static inline void pte_free(struct mm_st#define check_pgt_cache () do { } while (0) -#define __pte_free_tlb (tlb, pte, addr) pte_free((tlb)->mm, pte) -#define __pmd_free_tlb (tlb, pmd, addr) pmd_free((tlb)->mm, pmd) +static inline void pgtable_free (void *table,bool is_page) +{ +if (is_page) +free_page ((unsigned long )table); +else +kmem_cache_free (pgtable_cache, table); +} + +#ifdef CONFIG_SMP +#define HAVE_ARCH_RCU_TABLE_FREE + +struct mmu_gather ; +extern void tlb_remove_table (struct mmu_gather *,void *); + +static inline void pgtable_free_tlb (struct mmu_gather *tlb,void *table,bool is_page) +{ +unsigned long pgf = (unsigned long )table; +if (is_page) + pgf |=0x1UL ; +tlb_remove_table (tlb, (void *)pgf); +} + +static inline void __tlb_remove_table (void *_table) +{ +void *table = (void *)((unsigned long )_table & ~0x1UL ); +bool is_page = false; + +if ((unsigned long )_table &0x1UL ) + is_page = true; +pgtable_free (table, is_page); +} +#else /* CONFIG_SMP */ +static inline void pgtable_free_tlb (struct mmu_gather *tlb,void *table,bool is_page) +{ +pgtable_free (table, is_page); +} +#endif /* !CONFIG_SMP */ + +static inline void __pte_free_tlb (struct mmu_gather *tlb,struct page *ptepage, +unsigned long address) +{ +pgtable_page_dtor (ptepage); +pgtable_free_tlb (tlb,page_address (ptepage), true); +} + +#define __pmd_free_tlb (tlb, pmd, addr) \ + pgtable_free_tlb(tlb, pmd, false)#endif /* _SPARC64_PGALLOC_H */
PATCH 22/28 sparc64: Add support for _PAGE_SPECIAL
In reply to Peter ZijlstraFrom: David S. Miller <[email protected]>
Luckily there are still a few software PTE bits remaining and they even match up in both the sun4u and sun4v pte layouts.
LKML-Reference: <[email protected]>
--- arch/sparc/include/asm/pgtable_64.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
arch/sparc/include/asm/pgtable_64.h +11 -4
@@ -95,6 +95,10 @@/* PTE bits which are the same in SUN4U and SUN4V format. */ #define _PAGE_VALID _AC(0x8000000000000000,UL)/* Valid TTE */ #define _PAGE_R _AC(0x8000000000000000,UL)/* Keep ref bit uptodate*/ +#define _PAGE_SPECIAL _AC(0x0200000000000000,UL)/* Special page */ + +/* Advertise support for _PAGE_SPECIAL */ +#define __HAVE_ARCH_PTE_SPECIAL/* SUN4U pte bits... */ #define _PAGE_SZ4MB_4U _AC(0x6000000000000000,UL)/* 4MB Page */
@@ -104,6 +108,7 @@#define _PAGE_NFO_4U _AC(0x1000000000000000,UL)/* No Fault Only */ #define _PAGE_IE_4U _AC(0x0800000000000000,UL)/* Invert Endianness */ #define _PAGE_SOFT2_4U _AC(0x07FC000000000000,UL)/* Software bits, set 2 */ +#define _PAGE_SPECIAL_4U _AC(0x0200000000000000,UL)/* Special page */ #define _PAGE_RES1_4U _AC(0x0002000000000000,UL)/* Reserved */ #define _PAGE_SZ32MB_4U _AC(0x0001000000000000,UL)/* (Panther) 32MB page */ #define _PAGE_SZ256MB_4U _AC(0x2001000000000000,UL)/* (Panther) 256MB page */
@@ -133,6 +138,7 @@#define _PAGE_ACCESSED_4V _AC(0x1000000000000000,UL)/* Accessed (ref'd) */ #define _PAGE_READ_4V _AC(0x0800000000000000,UL)/* Readable SW Bit */ #define _PAGE_WRITE_4V _AC(0x0400000000000000,UL)/* Writable SW Bit */ +#define _PAGE_SPECIAL_4V _AC(0x0200000000000000,UL)/* Special page */ #define _PAGE_PADDR_4V _AC(0x00FFFFFFFFFFE000,UL)/* paddr[55:13] */ #define _PAGE_IE_4V _AC(0x0000000000001000,UL)/* Invert Endianness */ #define _PAGE_E_4V _AC(0x0000000000000800,UL)/* side-Effect */
@@ -302,10 +308,10 @@ static inline pte_t pte_modify(pte_t pte : "=r" (mask), "=r" (tmp) : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U | - _PAGE_SZBITS_4U), + _PAGE_SZBITS_4U | _PAGE_SPECIAL),"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V | - _PAGE_SZBITS_4V)); + _PAGE_SZBITS_4V | _PAGE_SPECIAL));return __pte ((pte_val (pte) & mask) | (pgprot_val (prot) & ~mask)); }
@@ -502,6 +508,7 @@ static inline pte_t pte_mkyoung(pte_t ptstatic inline pte_t pte_mkspecial (pte_t pte) { +pte_val (pte) |= _PAGE_SPECIAL;return pte; }
@@ -607,9 +614,9 @@ static inline unsigned long pte_present(return val; } -static inline int pte_special (pte_t pte) +static inline unsigned long pte_special (pte_t pte) { -return 0 ; +return pte_val (pte) & _PAGE_SPECIAL; }#define pmd_set (pmdp, ptep) \
PATCH 23/28 sparc64: Implement get_user_pages_fast().
In reply to Peter ZijlstraFrom: David S. Miller <[email protected]>
LKML-Reference: <[email protected]>
--- arch/sparc/mm/Makefile | 2 arch/sparc/mm/gup.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 arch/sparc/mm/gup.c
arch/sparc/mm/Makefile +1 -1
@@ -4,7 +4,7 @@ asflags-y := -ansi ccflags-y := -Werror -obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o +obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o gup.o obj-y += fault_$(BITS).o obj-y += init_$(BITS).o obj-$(CONFIG_SPARC32) += loadmmu.o
arch/sparc/mm/gup.c new file +181 -0
181 lines not on this page · raw message
PATCH 24/28 lockdep, mutex: Provide mutex_lock_nest_lock
In reply to Peter ZijlstraProvide the mutex_lock_nest_lock() annotation.
--- include/linux/lockdep.h | 3 +++ include/linux/mutex.h | 9 +++++++++ kernel/mutex.c | 25 +++++++++++++++++-------- 3 files changed, 29 insertions(+), 8 deletions(-)
include/linux/lockdep.h +3 -0
@@ -484,12 +484,15 @@ static inline void print_irqtrace_events#ifdef CONFIG_DEBUG_LOCK_ALLOC # ifdef CONFIG_PROVE_LOCKING # define mutex_acquire (l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i) +# define mutex_acquire_nest (l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i)# else # define mutex_acquire (l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i) +# define mutex_acquire_nest (l, s, t, n, i) lock_acquire(l, s, t, 0, 1, n, i)# endif # define mutex_release (l, n, i) lock_release(l, n, i)#else # define mutex_acquire (l, s, t, i) do { } while (0) +# define mutex_acquire_nest (l, s, t, n, i) do { } while (0)# define mutex_release (l, n, i) do { } while (0)#endif
include/linux/mutex.h +9 -0
@@ -124,6 +124,7 @@ static inline int mutex_is_locked(struct*/ #ifdef CONFIG_DEBUG_LOCK_ALLOC extern void mutex_lock_nested (struct mutex *lock,unsigned int subclass); +extern void _mutex_lock_nest_lock (struct mutex *lock,struct lockdep_map *nest_lock);extern int __must_check mutex_lock_interruptible_nested (struct mutex *lock,unsigned int subclass); extern int __must_check mutex_lock_killable_nested(struct mutex *lock,
@@ -132,6 +133,13 @@ extern int __must_check mutex_lock_killa#define mutex_lock (lock) mutex_lock_nested(lock, 0)#define mutex_lock_interruptible (lock) mutex_lock_interruptible_nested(lock, 0)#define mutex_lock_killable (lock) mutex_lock_killable_nested(lock, 0) + +#define mutex_lock_nest_lock (lock, nest_lock) \ +do { \ + typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ + _mutex_lock_nest_lock(lock, &(nest_lock)->dep_map); \ +} while (0) +#else extern void mutex_lock (struct mutex *lock);extern int __must_check mutex_lock_interruptible (struct mutex *lock);
@@ -140,6 +148,7 @@ extern int __must_check mutex_lock_killa# define mutex_lock_nested (lock, subclass) mutex_lock(lock)# define mutex_lock_interruptible_nested (lock, subclass) mutex_lock_interruptible(lock)# define mutex_lock_killable_nested (lock, subclass) mutex_lock_killable(lock) +# define mutex_lock_nest_lock (lock, nest_lock) mutex_lock(lock)#endif /*
kernel/mutex.c +17 -8
@@ -140,14 +140,14 @@ EXPORT_SYMBOL(mutex_unlock);*/ static inline int __sched__mutex_lock_common (struct mutex *lock,long state,unsigned int subclass, -unsigned long ip) +struct lockdep_map *nest_lock,unsigned long ip) {struct task_struct *task = current;struct mutex_waiter waiter;unsigned long flags;preempt_disable (); -mutex_acquire (&lock->dep_map, subclass,0 , ip); +mutex_acquire_nest (&lock->dep_map, subclass,0 , nest_lock, ip);#ifdef CONFIG_MUTEX_SPIN_ON_OWNER /*
@@ -278,16 +278,25 @@ void __sched mutex_lock_nested(struct mutex *lock, unsigned int subclass) {might_sleep (); -__mutex_lock_common (lock,TASK_UNINTERRUPTIBLE , subclass, _RET_IP_); +__mutex_lock_common (lock,TASK_UNINTERRUPTIBLE , subclass,NULL , _RET_IP_); }EXPORT_SYMBOL_GPL (mutex_lock_nested); +void __sched +_mutex_lock_nest_lock (struct mutex *lock,struct lockdep_map *nest) +{ +might_sleep (); +__mutex_lock_common (lock,TASK_UNINTERRUPTIBLE ,0 , nest, _RET_IP_); +} + +EXPORT_SYMBOL_GPL (_mutex_lock_nest_lock); + int __schedmutex_lock_killable_nested (struct mutex *lock,unsigned int subclass) {might_sleep (); -return __mutex_lock_common (lock,TASK_KILLABLE , subclass, _RET_IP_); +return __mutex_lock_common (lock,TASK_KILLABLE , subclass,NULL , _RET_IP_); }EXPORT_SYMBOL_GPL (mutex_lock_killable_nested);
@@ -296,7 +305,7 @@ mutex_lock_interruptible_nested(struct m {might_sleep ();return __mutex_lock_common (lock,TASK_INTERRUPTIBLE , - subclass, _RET_IP_); + subclass,NULL , _RET_IP_); }EXPORT_SYMBOL_GPL (mutex_lock_interruptible_nested);
@@ -402,7 +411,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou { struct mutex *lock = container_of(lock_count, struct mutex, count); -__mutex_lock_common (lock,TASK_UNINTERRUPTIBLE ,0 , _RET_IP_); +__mutex_lock_common (lock,TASK_UNINTERRUPTIBLE ,0 ,NULL , _RET_IP_); } static noinline int __sched
@@ -410,7 +419,7 @@ __mutex_lock_killable_slowpath(atomic_t { struct mutex *lock = container_of(lock_count, struct mutex, count); -return __mutex_lock_common (lock,TASK_KILLABLE ,0 , _RET_IP_); +return __mutex_lock_common (lock,TASK_KILLABLE ,0 ,NULL , _RET_IP_); } static noinline int __sched
@@ -418,7 +427,7 @@ __mutex_lock_interruptible_slowpath(atom { struct mutex *lock = container_of(lock_count, struct mutex, count); -return __mutex_lock_common (lock,TASK_INTERRUPTIBLE ,0 , _RET_IP_); +return __mutex_lock_common (lock,TASK_INTERRUPTIBLE ,0 ,NULL , _RET_IP_); }#endif
PATCH 25/28 mutex: Provide mutex_is_contended
In reply to Peter ZijlstraUsable for lock-breaks and such.
--- include/linux/mutex.h | 5 +++++ 1 file changed, 5 insertions(+)
include/linux/mutex.h +5 -0
@@ -118,6 +118,11 @@ static inline int mutex_is_locked(structreturn atomic_read (&lock->count) !=1 ; } +static inline int mutex_is_contended (struct mutex *lock) +{ +return atomic_read (&lock->count) <0 ; +} +/* * See kernel/mutex.c for detailed documentation of these APIs. * Also see Documentation/mutex-design.txt.
PATCH 26/28 mm: Convert i_mmap_lock and anon_vma->lock to mutexes
In reply to Peter ZijlstraStraight fwd conversion of i_mmap_lock and anon_vma->lock to mutexes.
--- arch/x86/mm/hugetlbpage.c | 4 ++-- fs/gfs2/main.c | 2 +- fs/hugetlbfs/inode.c | 4 ++-- fs/inode.c | 2 +- fs/nilfs2/btnode.c | 2 +- include/linux/fs.h | 2 +- include/linux/mm.h | 2 +- include/linux/rmap.h | 12 ++++++------ kernel/fork.c | 4 ++-- mm/filemap_xip.c | 4 ++-- mm/fremap.c | 4 ++-- mm/hugetlb.c | 12 ++++++------ mm/memory-failure.c | 4 ++-- mm/memory.c | 14 +++++++------- mm/mmap.c | 18 +++++++++--------- mm/mremap.c | 4 ++-- mm/rmap.c | 22 +++++++++++----------- 17 files changed, 58 insertions(+), 58 deletions(-)
arch/x86/mm/hugetlbpage.c +2 -2
@@ -72,7 +72,7 @@ static void huge_pmd_share(struct mm_strif (!vma_shareable (vma, addr))return ; -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock); vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) {if (svma == vma)continue ;
@@ -97,7 +97,7 @@ static void huge_pmd_share(struct mm_strput_page (virt_to_page (spte));spin_unlock (&mm->page_table_lock); out: -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock); }/*
fs/hugetlbfs/inode.c +2 -2
@@ -429,10 +429,10 @@ static int hugetlb_vmtruncate(struct ino pgoff = offset >>PAGE_SHIFT ;i_size_write (inode, offset); -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock);if (!prio_tree_empty (&mapping->i_mmap))hugetlb_vmtruncate_list (&mapping->i_mmap, pgoff); -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock);truncate_hugepages (inode, offset);return 0 ; }
fs/inode.c +1 -1
@@ -258,7 +258,7 @@ void inode_init_once(struct inode *inodeINIT_LIST_HEAD (&inode->i_devices);INIT_RADIX_TREE (&inode->i_data.page_tree,GFP_ATOMIC );spin_lock_init (&inode->i_data.tree_lock); -spin_lock_init (&inode->i_data.i_mmap_lock); +mutex_init (&inode->i_data.i_mmap_lock);INIT_LIST_HEAD (&inode->i_data.private_list);spin_lock_init (&inode->i_data.private_lock);INIT_RAW_PRIO_TREE_ROOT (&inode->i_data.i_mmap);
include/linux/fs.h +1 -1
@@ -627,7 +627,7 @@ struct address_space {unsigned int i_mmap_writable;/* count VM_SHARED mappings */ struct prio_tree_root i_mmap;/* tree of private and shared mappings */ struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */ -spinlock_t i_mmap_lock;/* protect tree, count, list */ +struct mutex i_mmap_lock;/* protect tree, count, list */ unsigned int truncate_count;/* Cover race condition with truncate */ unsigned long nrpages;/* number of total pages */ pgoff_t writeback_index;/* writeback starts here */
include/linux/mm.h +1 -1
@@ -754,7 +754,7 @@ struct zap_details {struct address_space *check_mapping;/* Check page->mapping if set */ pgoff_t first_index;/* Lowest page->index to unmap */ pgoff_t last_index;/* Highest page->index to unmap */ -spinlock_t *i_mmap_lock;/* For unmap_mapping_range: */ +struct mutex *i_mmap_lock;/* For unmap_mapping_range: */ unsigned long truncate_count;/* Compare vm_truncate_count */ };
include/linux/rmap.h +6 -6
@@ -7,7 +7,7 @@#include <linux/list.h> #include <linux/slab.h> #include <linux/mm.h> -#include <linux/spinlock.h> +#include <linux/mutex.h> #include <linux/memcontrol.h> /*
@@ -25,7 +25,7 @@* pointing to this anon_vma once its vma list is empty. */ struct anon_vma { -spinlock_t lock;/* Serialize access to vma list */ +struct mutex lock;/* Serialize access to vma list */ struct anon_vma *root;/* Root of this anon_vma tree */ /* * The refcount is taken on an anon_vma when there is no
@@ -93,24 +93,24 @@ static inline void vma_lock_anon_vma(str {struct anon_vma *anon_vma = vma->anon_vma;if (anon_vma) -spin_lock (&anon_vma->root->lock); +mutex_lock (&anon_vma->root->lock); }static inline void vma_unlock_anon_vma (struct vm_area_struct *vma) {struct anon_vma *anon_vma = vma->anon_vma;if (anon_vma) -spin_unlock (&anon_vma->root->lock); +mutex_unlock (&anon_vma->root->lock); }static inline void anon_vma_lock (struct anon_vma *anon_vma) { -spin_lock (&anon_vma->root->lock); +mutex_lock (&anon_vma->root->lock); }static inline void anon_vma_unlock (struct anon_vma *anon_vma) { -spin_unlock (&anon_vma->root->lock); +mutex_unlock (&anon_vma->root->lock); }/*
kernel/fork.c +2 -2
@@ -368,7 +368,7 @@ static int dup_mmap(struct mm_struct *mmget_file (file);if (tmp->vm_flags &VM_DENYWRITE )atomic_dec (&inode->i_writecount); -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock);if (tmp->vm_flags &VM_SHARED ) mapping->i_mmap_writable++; tmp->vm_truncate_count = mpnt->vm_truncate_count;
@@ -376,7 +376,7 @@ static int dup_mmap(struct mm_struct *mm/* insert tmp into the share list, just after mpnt */ vma_prio_tree_add (tmp, mpnt);flush_dcache_mmap_unlock (mapping); -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock); }/*
mm/filemap_xip.c +2 -2
@@ -183,7 +183,7 @@ __xip_unmap (struct address_space * mappreturn ; retry: -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { mm = vma->vm_mm; address = vma->vm_start +
@@ -201,7 +201,7 @@ retry:page_cache_release (page); } } -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock);if (locked) {mutex_unlock (&xip_sparse_mutex);
mm/fremap.c +2 -2
@@ -208,13 +208,13 @@ SYSCALL_DEFINE5(remap_file_pages, unsign } goto out; } -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock);flush_dcache_mmap_lock (mapping); vma->vm_flags |=VM_NONLINEAR ;vma_prio_tree_remove (vma, &mapping->i_mmap);vma_nonlinear_insert (vma, &mapping->i_mmap_nonlinear);flush_dcache_mmap_unlock (mapping); -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock); }if (vma->vm_flags &VM_LOCKED ) {
mm/hugetlb.c +6 -6
@@ -2215,9 +2215,9 @@ void __unmap_hugepage_range(struct vm_arvoid unmap_hugepage_range (struct vm_area_struct *vma,unsigned long start,unsigned long end,struct page *ref_page) { -spin_lock (&vma->vm_file->f_mapping->i_mmap_lock); +mutex_lock (&vma->vm_file->f_mapping->i_mmap_lock);__unmap_hugepage_range (vma, start, end, ref_page); -spin_unlock (&vma->vm_file->f_mapping->i_mmap_lock); +mutex_unlock (&vma->vm_file->f_mapping->i_mmap_lock); }/*
@@ -2249,7 +2249,7 @@ static int unmap_ref_private(struct mm_s* this mapping should be shared between all the VMAs, * __unmap_hugepage_range() is called as the lock is already held */ -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock); vma_prio_tree_foreach(iter_vma, &iter, &mapping->i_mmap, pgoff, pgoff) {/* Do not unmap the current VMA */ if (iter_vma == vma)
@@ -2267,7 +2267,7 @@ static int unmap_ref_private(struct mm_s address, address +huge_page_size (h), page); } -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock);return 1 ; }
@@ -2685,7 +2685,7 @@ void hugetlb_change_protection(struct vmBUG_ON (address >= end);flush_cache_range (vma, address, end); -spin_lock (&vma->vm_file->f_mapping->i_mmap_lock); +mutex_lock (&vma->vm_file->f_mapping->i_mmap_lock);spin_lock (&mm->page_table_lock);for (; address < end; address +=huge_page_size (h)) { ptep =huge_pte_offset (mm, address);
@@ -2700,7 +2700,7 @@ void hugetlb_change_protection(struct vm } }spin_unlock (&mm->page_table_lock); -spin_unlock (&vma->vm_file->f_mapping->i_mmap_lock); +mutex_unlock (&vma->vm_file->f_mapping->i_mmap_lock);flush_tlb_range (vma, start, end); }
mm/memory-failure.c +2 -2
@@ -422,7 +422,7 @@ static void collect_procs_file(struct pa*/ read_lock (&tasklist_lock); -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock);for_each_process (tsk) {pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT -PAGE_SHIFT );
@@ -442,7 +442,7 @@ static void collect_procs_file(struct paadd_to_kill (tsk, page, vma, to_kill, tkc); } } -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock);read_unlock (&tasklist_lock); }
mm/memory.c +7 -7
@@ -1183,7 +1183,7 @@ unsigned long unmap_vmas(struct mmu_gath {long zap_work =ZAP_BLOCK_SIZE ;unsigned long start = start_addr; -spinlock_t *i_mmap_lock = details? details->i_mmap_lock:NULL ; +struct mutex *i_mmap_lock = details ? details->i_mmap_lock :NULL ;struct mm_struct *mm = vma->vm_mm;mmu_notifier_invalidate_range_start (mm, start_addr, end_addr);
@@ -1233,7 +1233,7 @@ unsigned long unmap_vmas(struct mmu_gath }if (need_resched () || - (i_mmap_lock &&spin_needbreak (i_mmap_lock))) { + (i_mmap_lock &&mutex_is_contended (i_mmap_lock))) {if (i_mmap_lock) goto out;cond_resched ();
@@ -2517,7 +2517,7 @@ again: restart_addr =zap_page_range (vma, start_addr, end_addr - start_addr, details); - need_break =need_resched () ||spin_needbreak (details->i_mmap_lock); + need_break =need_resched () ||mutex_is_contended (details->i_mmap_lock);if (restart_addr >= end_addr) {/* We have now completed this vma: mark it so */
@@ -2531,9 +2531,9 @@ again: goto again; } -spin_unlock (details->i_mmap_lock); +mutex_unlock (details->i_mmap_lock);cond_resched (); -spin_lock (details->i_mmap_lock); +mutex_lock (details->i_mmap_lock);return -EINTR ; }
@@ -2629,7 +2629,7 @@ void unmap_mapping_range(struct address_ details.last_index =ULONG_MAX ; details.i_mmap_lock = &mapping->i_mmap_lock; -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock);/* Protect against endless unmapping loops */ mapping->truncate_count++;
@@ -2644,7 +2644,7 @@ void unmap_mapping_range(struct address_unmap_mapping_range_tree (&mapping->i_mmap, &details);if (unlikely (!list_empty (&mapping->i_mmap_nonlinear)))unmap_mapping_range_list (&mapping->i_mmap_nonlinear, &details); -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock); }EXPORT_SYMBOL (unmap_mapping_range);
mm/mmap.c +9 -9
@@ -216,9 +216,9 @@ void unlink_file_vma(struct vm_area_struif (file) {struct address_space *mapping = file->f_mapping; -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock);__remove_shared_vm_struct (vma, file, mapping); -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock); } }
@@ -449,7 +449,7 @@ static void vma_link(struct mm_struct *m mapping = vma->vm_file->f_mapping;if (mapping) { -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock); vma->vm_truncate_count = mapping->truncate_count; }vma_lock_anon_vma (vma);
@@ -459,7 +459,7 @@ static void vma_link(struct mm_struct *mvma_unlock_anon_vma (vma);if (mapping) -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock); mm->map_count++;validate_mm (mm);
@@ -558,7 +558,7 @@ again: remove_next = 1 + (end > next-> mapping = file->f_mapping;if (!(vma->vm_flags &VM_NONLINEAR )) root = &mapping->i_mmap; -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock);if (importer && vma->vm_truncate_count != next->vm_truncate_count) {/*
@@ -632,7 +632,7 @@ again: remove_next = 1 + (end > next->if (anon_vma)anon_vma_unlock (anon_vma);if (mapping) -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock);if (remove_next) {if (file) {
@@ -2489,7 +2489,7 @@ static void vm_lock_anon_vma(struct mm_s* The LSB of head.next can't change from under us * because we hold the mm_all_locks_mutex. */ -spin_lock_nest_lock (&anon_vma->root->lock, &mm->mmap_sem); +mutex_lock_nest_lock (&anon_vma->root->lock, &mm->mmap_sem);/* * We can safely modify head.next after taking the * anon_vma->root->lock. If some other vma in this mm shares
@@ -2519,7 +2519,7 @@ static void vm_lock_mapping(struct mm_st*/ if (test_and_set_bit (AS_MM_ALL_LOCKS , &mapping->flags))BUG (); -spin_lock_nest_lock (&mapping->i_mmap_lock, &mm->mmap_sem); +mutex_lock_nest_lock (&mapping->i_mmap_lock, &mm->mmap_sem); } }
@@ -2618,7 +2618,7 @@ static void vm_unlock_mapping(struct add* AS_MM_ALL_LOCKS can't change to 0 from under us * because we hold the mm_all_locks_mutex. */ -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock);if (!test_and_clear_bit (AS_MM_ALL_LOCKS , &mapping->flags))BUG ();
mm/mremap.c +2 -2
@@ -90,7 +90,7 @@ static void move_ptes(struct vm_area_str* and we propagate stale pages into the dst afterward. */ mapping = vma->vm_file->f_mapping; -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock);if (new_vma->vm_truncate_count && new_vma->vm_truncate_count != vma->vm_truncate_count) new_vma->vm_truncate_count =0 ;
@@ -122,7 +122,7 @@ static void move_ptes(struct vm_area_strpte_unmap_nested (new_pte -1 );pte_unmap_unlock (old_pte -1 , old_ptl);if (mapping) -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock);mmu_notifier_invalidate_range_end (vma->vm_mm, old_start, old_end); }
mm/rmap.c +11 -11
@@ -300,7 +300,7 @@ static void anon_vma_ctor(void *data) {struct anon_vma *anon_vma = data; -spin_lock_init (&anon_vma->lock); +mutex_init (&anon_vma->lock);atomic_set (&anon_vma->refcount,0 );INIT_LIST_HEAD (&anon_vma->head); }
@@ -612,7 +612,7 @@ static int page_referenced_file(struct p*/ BUG_ON (!PageLocked (page)); -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock);/* * i_mmap_lock does not stabilize mapcount at all, but mapcount
@@ -637,7 +637,7 @@ static int page_referenced_file(struct pbreak ; } -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock);return referenced; }
@@ -724,7 +724,7 @@ static int page_mkclean_file(struct addrBUG_ON (PageAnon (page)); -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {if (vma->vm_flags &VM_SHARED ) {unsigned long address =vma_address (page, vma);
@@ -733,7 +733,7 @@ static int page_mkclean_file(struct addr ret +=page_mkclean_one (page, vma, address); } } -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock);return ret; }
@@ -1283,7 +1283,7 @@ static int try_to_unmap_file(struct pageunsigned long max_nl_size =0 ;unsigned int mapcount; -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {unsigned long address =vma_address (page, vma);if (address == -EFAULT )
@@ -1329,7 +1329,7 @@ static int try_to_unmap_file(struct page mapcount =page_mapcount (page);if (!mapcount) goto out; -cond_resched_lock (&mapping->i_mmap_lock); +cond_resched (); max_nl_size = (max_nl_size +CLUSTER_SIZE -1 ) &CLUSTER_MASK ;if (max_nl_cursor ==0 )
@@ -1351,7 +1351,7 @@ static int try_to_unmap_file(struct page } vma->vm_private_data = (void *) max_nl_cursor; } -cond_resched_lock (&mapping->i_mmap_lock); +cond_resched (); max_nl_cursor +=CLUSTER_SIZE ; }while (max_nl_cursor <= max_nl_size);
@@ -1363,7 +1363,7 @@ static int try_to_unmap_file(struct pagelist_for_each_entry (vma, &mapping->i_mmap_nonlinear, shared.vm_set.list) vma->vm_private_data =NULL ; out: -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock);return ret; }
@@ -1478,7 +1478,7 @@ static int rmap_walk_file(struct page *pif (!mapping)return ret; -spin_lock (&mapping->i_mmap_lock); +mutex_lock (&mapping->i_mmap_lock); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {unsigned long address =vma_address (page, vma);if (address == -EFAULT )
@@ -1492,7 +1492,7 @@ static int rmap_walk_file(struct page *p* never contain migration ptes. Decide what to do about this * limitation to linear when we need rmap_walk() on nonlinear. */ -spin_unlock (&mapping->i_mmap_lock); +mutex_unlock (&mapping->i_mmap_lock);return ret; }
fs/gfs2/main.c +1 -1
@@ -61,7 +61,7 @@ static void gfs2_init_gl_aspace_once(voimemset (mapping,0 ,sizeof (*mapping));INIT_RADIX_TREE (&mapping->page_tree,GFP_ATOMIC );spin_lock_init (&mapping->tree_lock); -spin_lock_init (&mapping->i_mmap_lock); +mutex_init (&mapping->i_mmap_lock);INIT_LIST_HEAD (&mapping->private_list);spin_lock_init (&mapping->private_lock);INIT_RAW_PRIO_TREE_ROOT (&mapping->i_mmap);
fs/nilfs2/btnode.c +1 -1
@@ -43,7 +43,7 @@ void nilfs_btnode_cache_init_once(structINIT_LIST_HEAD (&btnc->private_list);spin_lock_init (&btnc->private_lock); -spin_lock_init (&btnc->i_mmap_lock); +mutex_init (&btnc->i_mmap_lock);INIT_RAW_PRIO_TREE_ROOT (&btnc->i_mmap);INIT_LIST_HEAD (&btnc->i_mmap_nonlinear); }
PATCH 27/28 mm: Extended batches for generic mmu_gather
In reply to Peter ZijlstraInstead of using a single batch (the small on-stack, or an allocated page), try and extend the batch every time it runs out and only flush once either the extend fails or we're done.
--- include/asm-generic/tlb.h | 122 ++++++++++++++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 40 deletions(-)
include/asm-generic/tlb.h +82 -40
@@ -17,16 +17,6 @@#include <asm/pgalloc.h> #include <asm/tlbflush.h> -/* -* For UP we don't need to worry about TLB flush -* and page free order so much.. -*/ -#ifdef CONFIG_SMP -#define tlb_fast_mode (tlb) ((tlb)->nr == ~0U) -#else -#define tlb_fast_mode (tlb) 1 -#endif -#ifdef HAVE_ARCH_RCU_TABLE_FREE /* * Semi RCU freeing of the page directories.
@@ -70,31 +60,66 @@ extern void tlb_remove_table(struct mmu_#endif +struct mmu_gather_batch { +struct mmu_gather_batch *next; +unsigned int nr; +unsigned int max; +struct page *pages[0 ]; +}; + +#define MAX_GATHER_BATCH \ + ((PAGE_SIZE - sizeof(struct mmu_gather_batch)) / sizeof(void *)) +/* struct mmu_gather is an opaque type used by the mm code for passing around * any data needed by arch specific code for tlb_remove_page. */ struct mmu_gather {struct mm_struct *mm; -unsigned int nr;/* set to ~0U means fast mode */ -unsigned int max;/* nr < max */ -unsigned int need_flush;/* Really unmapped some ptes? */ -unsigned int fullmm;/* non-zero means full mm flush */ -struct page **pages; -struct page *local[8 ]; +unsigned int need_flush :1 ,/* Did free PTEs */ + fast_mode :1 ;/* No batching */ +unsigned int fullmm;/* Flush full mm */ + +struct mmu_gather_batch *active; +struct mmu_gather_batch local; +struct page *__pages[8 ];#ifdef HAVE_ARCH_RCU_TABLE_FREE struct mmu_table_batch *batch;#endif }; -static inline void __tlb_alloc_pages (struct mmu_gather *tlb) +/* +* For UP we don't need to worry about TLB flush +* and page free order so much.. +*/ +#ifdef CONFIG_SMP +#define tlb_fast_mode (tlb) (tlb->fast_mode) +#else +#define tlb_fast_mode (tlb) 1 +#endif + +static inline int tlb_next_batch (struct mmu_gather *tlb) { -unsigned long addr =__get_free_pages (GFP_ATOMIC ,0 ); +struct mmu_gather_batch *batch; -if (addr) { - tlb->pages = (void *)addr; - tlb->max =PAGE_SIZE /sizeof (struct page *); + batch = tlb->active; +if (batch->next) { + tlb->active = batch->next; +return 1 ; } + + batch = (void *)__get_free_pages (GFP_ATOMIC ,0 ); +if (!batch) +return 0 ; + + batch->next =NULL ; + batch->nr =0 ; + batch->max =MAX_GATHER_BATCH ; + + tlb->active->next = batch; + tlb->active = batch; + +return 1 ; }/* tlb_gather_mmu
@@ -105,17 +130,16 @@ tlb_gather_mmu(struct mmu_gather *tlb, s { tlb->mm = mm; - tlb->max =ARRAY_SIZE (tlb->local); - tlb->pages = tlb->local; - -if (num_online_cpus () >1 ) { - tlb->nr =0 ; -__tlb_alloc_pages (tlb); - }else /* Use fast mode if only one CPU is online */ - tlb->nr = ~0U ; - + tlb->need_flush =0 ; +if (num_online_cpus () ==1 ) + tlb->fast_mode =1 ; tlb->fullmm = full_mm_flush; + tlb->local.next =NULL ; + tlb->local.nr =0 ; + tlb->local.max =ARRAY_SIZE (tlb->__pages); + tlb->active = &tlb->local; +#ifdef HAVE_ARCH_RCU_TABLE_FREE tlb->batch =NULL ;#endif
@@ -124,6 +148,8 @@ tlb_gather_mmu(struct mmu_gather *tlb, sstatic inline void tlb_flush_mmu (struct mmu_gather *tlb,unsigned long start,unsigned long end) { +struct mmu_gather_batch *batch; +if (!tlb->need_flush)return ; tlb->need_flush =0 ;
@@ -131,12 +157,14 @@ tlb_flush_mmu(struct mmu_gather *tlb, un#ifdef HAVE_ARCH_RCU_TABLE_FREE tlb_table_flush (tlb);#endif -if (!tlb_fast_mode (tlb)) { -free_pages_and_swap_cache (tlb->pages, tlb->nr); - tlb->nr =0 ; -if (tlb->pages == tlb->local) -__tlb_alloc_pages (tlb); +if (tlb_fast_mode (tlb)) +return ; + +for (batch = &tlb->local; batch; batch = batch->next) { +free_pages_and_swap_cache (batch->pages, batch->nr); + batch->nr =0 ; } + tlb->active = &tlb->local; }/* tlb_finish_mmu
@@ -146,13 +174,18 @@ tlb_flush_mmu(struct mmu_gather *tlb, unstatic inline void tlb_finish_mmu (struct mmu_gather *tlb,unsigned long start,unsigned long end) { +struct mmu_gather_batch *batch, *next; +tlb_flush_mmu (tlb, start, end);/* keep the page table cache within bounds */ check_pgt_cache (); -if (tlb->pages != tlb->local) -free_pages ((unsigned long )tlb->pages,0 ); +for (batch = tlb->local.next; batch; batch = next) { + next = batch->next; +free_pages ((unsigned long )batch,0 ); + } + tlb->local.next =NULL ; }/* tlb_remove_page
@@ -162,14 +195,23 @@ tlb_finish_mmu(struct mmu_gather *tlb, u*/ static inline void tlb_remove_page (struct mmu_gather *tlb,struct page *page) { +struct mmu_gather_batch *batch; + tlb->need_flush =1 ; +if (tlb_fast_mode (tlb)) {free_page_and_swap_cache (page);return ; } - tlb->pages[tlb->nr++] = page; -if (tlb->nr >= tlb->max) -tlb_flush_mmu (tlb,0 ,0 ); + + batch = tlb->active; +if (batch->nr == batch->max) { +if (!tlb_next_batch (tlb)) +tlb_flush_mmu (tlb,0 ,0 ); + batch = tlb->active; + } + + batch->pages[batch->nr++] = page; }/**
PATCH 28/28 mm: Optimize page_lock_anon_vma() fast-path
In reply to Peter ZijlstraOptimize the page_lock_anon_vma() fast path to be one LOCKed op, instead of two.
--- mm/rmap.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 4 deletions(-)
mm/rmap.c +61 -4
@@ -351,20 +351,69 @@ out:return anon_vma; } +/* +* Similar to page_get_anon_vma() except it locks the anon_vma. +* +* Its a little more complex as it tries to keep the fast path to a single +* atomic op -- the trylock. If we fail the trylock, we fall back to getting a +* reference like with page_get_anon_vma() and then block on the mutex. +*/ struct anon_vma *page_lock_anon_vma (struct page *page) { -struct anon_vma *anon_vma =page_get_anon_vma (page); +struct anon_vma *anon_vma =NULL ; +unsigned long anon_mapping; + +rcu_read_lock (); + anon_mapping = (unsigned long )ACCESS_ONCE (page->mapping); +if ((anon_mapping &PAGE_MAPPING_FLAGS ) !=PAGE_MAPPING_ANON ) + goto out; +if (!page_mapped (page)) + goto out; + + anon_vma = (struct anon_vma *) (anon_mapping -PAGE_MAPPING_ANON ); +if (mutex_trylock (&anon_vma->root->lock)) { +/* +* If we observe a !0 refcount, then holding the lock ensures +* the anon_vma will not go away, see __put_anon_vma(). +*/ +if (!atomic_read (&anon_vma->refcount)) { +anon_vma_unlock (anon_vma); + anon_vma =NULL ; + } + goto out; + } + +/* trylock failed, we got to sleep */ +if (!atomic_inc_not_zero (&anon_vma->refcount)) { + anon_vma =NULL ; + goto out; + } + +/* we pinned the anon_vma, its safe to sleep */ +rcu_read_unlock (); +anon_vma_lock (anon_vma); + +if (atomic_dec_and_test (&anon_vma->refcount)) { +/* +* Oops, we held the last refcount, release the lock +* and bail -- can't simply use put_anon_vma() because +* we'll deadlock on the anon_vma_lock() recursion. +*/ +anon_vma_unlock (anon_vma); +__put_anon_vma (anon_vma); + anon_vma =NULL ; + } -if (anon_vma) -anon_vma_lock (anon_vma); +return anon_vma; +out: +rcu_read_unlock ();return anon_vma; }void page_unlock_anon_vma (struct anon_vma *anon_vma) {anon_vma_unlock (anon_vma); -put_anon_vma (anon_vma); }/*
@@ -1422,6 +1471,14 @@ int try_to_munlock(struct page *page)void __put_anon_vma (struct anon_vma *anon_vma) { +/* +* Synchronize against page_lock_anon_vma() such that +* we can safely hold the lock without the anon_vma getting +* freed. +*/ +anon_vma_lock (anon_vma); +anon_vma_unlock (anon_vma); +if (anon_vma->root != anon_vma)put_anon_vma (anon_vma->root);anon_vma_free (anon_vma);
Quoted 3 lines
There are no known architectures left unconverted, although some arch code never did see a compiler (superh and um come to mind).
um is easy.
On your x86 box you just do "make ARCH=um"
Sam
Peter Zijlstra
maintainerQuoted 6 lines · Sam Ravnborg
Quoted 3 lines
There are no known architectures left unconverted, although some arch code never did see a compiler (superh and um come to mind).
um is easy.
On your x86 box you just do "make ARCH=um"
Right, seems to build.
Quoted 3 lines · Peter Zijlstra
This patch-set makes part of the mm a lot more preemptible. It converts
i_mmap_lockandanon_vma->lockto mutexes and makesmmu_gatherfully preemptible.
How about performance measurements? mutexes still behave quite
differently from spinlocks, especially under contention.
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only.
Peter Zijlstra
maintainerQuoted 8 lines · Andi Kleen
Quoted 3 lines · Peter Zijlstra
This patch-set makes part of the mm a lot more preemptible. It converts
i_mmap_lockandanon_vma->lockto mutexes and makesmmu_gatherfully preemptible.How about performance measurements? mutexes still behave quite
differently from spinlocks, especially under contention.
What's your favourite benchmark to stress i_mmap_mutex/anon_vma->lock?
a cache-hot kernel build didn't really show a difference..
Quoted 3 lines · Peter Zijlstra
This patch-set makes part of the mm a lot more preemptible. It converts
i_mmap_lockandanon_vma->lockto mutexes and makesmmu_gatherfully preemptible.
I applied it against 2.6.35-rc2 on x86_64 machine, but kernel booting panic.
Pid: 1, comm: init Not tainted 2.6.35-rc2-petermm #1 X7DW3/X7DW3
RIP: 0010:[<ffffffff8160e055>] [<ffffffff8160e055>] mutex_unlock +0x0/0x13 RSP: 0018:ffff88022fc61a78 EFLAGS: 00010206 RAX: 0000000000000000 RBX: ffff88022ebd5780 RCX: 0000000000000020 RDX: 0000000000000000 RSI: 0000000000100173 RDI: 8000000000000025 RBP: 0000000000000020 R08: 00007fffffffe000 R09: 0000000000000001 R10: 0000000000000002 R11: ffffffff8128c275 R12: ffff88022e76b000 R13: 0000000000021000 R14: ffff88022fc68000 R15: 00007fff4c0e6000 FS: 0000000000000000(0000) GS:ffff8800021c0000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000000 CR3: 000000022e76c000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process init (pid: 1, threadinfo ffff88022fc60000, task ffff88022fc58000)
Stack: ffffffff810aabac 00000000ffffefff 0000000000000000 00007fff4c107000 <0> ffff88022e76b000 00007fffffffe000 00007ffffffff000 00007fff4c106000 <0> ffffffff810c5e5a ffff88022ebd5780 ffff88022ebd5780 ffff88022ebd5780 Call Trace: [<ffffffff810aabac>] ? expand_downwards+0x149/0x15a [<ffffffff810c5e5a>] ? setup_arg_pages+0x333/0x361 [<ffffffff810c8955>] ? inode_permission+0x76/0x95 [<ffffffff810f8a19>] ? load_elf_binary+0x0/0x16c9 [<ffffffff810f8e7e>] ? load_elf_binary+0x465/0x16c9 [<ffffffff810c488a>] ? get_arg_page+0x4b/0xa4 [<ffffffff810f8a19>] ? load_elf_binary+0x0/0x16c9 [<ffffffff810c4ce4>] ? search_binary_handler+0xd4/0x26f [<ffffffff810f7a1c>] ? load_script+0x0/0x1e4 [<ffffffff810f7bea>] ? load_script+0x1ce/0x1e4 [<ffffffff810c488a>] ? get_arg_page+0x4b/0xa4 [<ffffffff810c4ce4>] ? search_binary_handler+0xd4/0x26f [<ffffffff810c6228>] ? do_execve+0x1e5/0x2b6 [<ffffffff81008d60>] ? sys_execve+0x35/0x53 [<ffffffff81003648>] ? kernel_execve+0x68/0xd0 [<ffffffff81000342>] ? init_post+0x5a/0xd4 [<ffffffff81cdf97d>] ? kernel_init+0x1e5/0x1ec [<ffffffff810035d4>] ? kernel_thread_helper+0x4/0x10 [<ffffffff81cdf798>] ? kernel_init+0x0/0x1ec [<ffffffff810035d0>] ? kernel_thread_helper+0x0/0x10 Code: 1c 24 44 89 64 24 08 48 c7 44 24 20 07 fd 04 81 48 89 44 24 28 48
89 44 24 30 e8 26 ff ff ff 48 83 c4 48 5b 41 5c 41 5d 41 5e c3 <48> c7 47 18 00 00 00 00 f0 ff 07 7f 05 e8 01 00 00 00 c3 53 48 RIP [<ffffffff8160e055>] mutex_unlock+0x0/0x13
RSP <ffff88022fc61a78>
---[ end trace dc724d36e0cd4a32 ]---
Quoted 29 lines
The main motivation was making
mm_take_all_locks()preemptible, since it appears people are nesting hundreds of spinlocks there.The side-effects are that can finally make
mmu_gatherpreemptible, something which lots of people have wanted to do for a long time.It also gets us
anon_vmarefcounting, which seems to result in a nice cleanup of theanon_vmalifetime rules wrt KSM and compaction.This patch-set it build and boot-tested on
x86_64(a previous version was also tested on Dave's Niagra2 machines, and I suppose s390 did too when Martin provided the conversion patch for his arch).There are no known architectures left unconverted, although some arch code never did see a compiler (superh and um come to mind).
Can we move this work forwards, or is there anything people would want to see done?
[ The series includes Rik's latest patches to the same area for convenience ]
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Peter Zijlstra
maintainerQuoted 49 lines · Yanmin
Quoted 3 lines · Peter Zijlstra
This patch-set makes part of the mm a lot more preemptible. It converts
i_mmap_lockandanon_vma->lockto mutexes and makesmmu_gatherfully preemptible.I applied it against 2.6.35-rc2 on
x86_64machine, but kernel booting panic.Pid: 1, comm: init Not tainted 2.6.35-rc2-petermm #1 X7DW3/X7DW3
RIP: 0010:[<ffffffff8160e055>] [<ffffffff8160e055>] mutex_unlock +0x0/0x13 RSP: 0018:ffff88022fc61a78 EFLAGS: 00010206 RAX: 0000000000000000 RBX: ffff88022ebd5780 RCX: 0000000000000020 RDX: 0000000000000000 RSI: 0000000000100173 RDI: 8000000000000025 RBP: 0000000000000020 R08: 00007fffffffe000 R09: 0000000000000001 R10: 0000000000000002 R11: ffffffff8128c275 R12: ffff88022e76b000 R13: 0000000000021000 R14: ffff88022fc68000 R15: 00007fff4c0e6000 FS: 0000000000000000(0000) GS:ffff8800021c0000(0000)knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0:000000008005003b
CR2: 0000000000000000 CR3:000000022e76c000CR4:00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6:00000000ffff0ff0DR7: 0000000000000400 Process init (pid: 1, threadinfoffff88022fc60000, taskffff88022fc58000)Stack: ffffffff810aabac 00000000ffffefff 0000000000000000 00007fff4c107000 <0> ffff88022e76b000 00007fffffffe000 00007ffffffff000 00007fff4c106000 <0> ffffffff810c5e5a ffff88022ebd5780 ffff88022ebd5780 ffff88022ebd5780 Call Trace: [<ffffffff810aabac>] ? expand_downwards+0x149/0x15a [<ffffffff810c5e5a>] ? setup_arg_pages+0x333/0x361 [<ffffffff810c8955>] ? inode_permission+0x76/0x95 [<ffffffff810f8a19>] ? load_elf_binary+0x0/0x16c9 [<ffffffff810f8e7e>] ? load_elf_binary+0x465/0x16c9 [<ffffffff810c488a>] ? get_arg_page+0x4b/0xa4 [<ffffffff810f8a19>] ? load_elf_binary+0x0/0x16c9 [<ffffffff810c4ce4>] ? search_binary_handler+0xd4/0x26f [<ffffffff810f7a1c>] ? load_script+0x0/0x1e4 [<ffffffff810f7bea>] ? load_script+0x1ce/0x1e4 [<ffffffff810c488a>] ? get_arg_page+0x4b/0xa4 [<ffffffff810c4ce4>] ? search_binary_handler+0xd4/0x26f [<ffffffff810c6228>] ? do_execve+0x1e5/0x2b6 [<ffffffff81008d60>] ? sys_execve+0x35/0x53 [<ffffffff81003648>] ? kernel_execve+0x68/0xd0 [<ffffffff81000342>] ? init_post+0x5a/0xd4 [<ffffffff81cdf97d>] ? kernel_init+0x1e5/0x1ec [<ffffffff810035d4>] ? kernel_thread_helper+0x4/0x10 [<ffffffff81cdf798>] ? kernel_init+0x0/0x1ec [<ffffffff810035d0>] ? kernel_thread_helper+0x0/0x10 Code: 1c 24 44 89 64 24 08 48 c7 44 24 20 07 fd 04 81 48 89 44 24 28 48
Quoted 5 lines
89 44 24 30 e8 26 ff ff ff 48 83 c4 48 5b 41 5c 41 5d 41 5e c3 <48> c7 47 18 00 00 00 00 f0 ff 07 7f 05 e8 01 00 00 00 c3 53 48 RIP [<
ffffffff8160e055>]mutex_unlock+0x0/0x13
RSP <ffff88022fc61a78>---[ end trace dc724d36e0cd4a32 ]---
Oi, that's no good. Happen to have your .config handy, I didn't actually see my machine do that.
Quoted 56 lines · Peter Zijlstra
Quoted 49 lines · Yanmin
Quoted 3 lines · Peter Zijlstra
This patch-set makes part of the mm a lot more preemptible. It converts
i_mmap_lockandanon_vma->lockto mutexes and makesmmu_gatherfully preemptible.I applied it against 2.6.35-rc2 on
x86_64machine, but kernel booting panic.Pid: 1, comm: init Not tainted 2.6.35-rc2-petermm #1 X7DW3/X7DW3
RIP: 0010:[<ffffffff8160e055>] [<ffffffff8160e055>] mutex_unlock +0x0/0x13 RSP: 0018:ffff88022fc61a78 EFLAGS: 00010206 RAX: 0000000000000000 RBX: ffff88022ebd5780 RCX: 0000000000000020 RDX: 0000000000000000 RSI: 0000000000100173 RDI: 8000000000000025 RBP: 0000000000000020 R08: 00007fffffffe000 R09: 0000000000000001 R10: 0000000000000002 R11: ffffffff8128c275 R12: ffff88022e76b000 R13: 0000000000021000 R14: ffff88022fc68000 R15: 00007fff4c0e6000 FS: 0000000000000000(0000) GS:ffff8800021c0000(0000)knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0:000000008005003b
CR2: 0000000000000000 CR3:000000022e76c000CR4:00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6:00000000ffff0ff0DR7: 0000000000000400 Process init (pid: 1, threadinfoffff88022fc60000, taskffff88022fc58000)Stack: ffffffff810aabac 00000000ffffefff 0000000000000000 00007fff4c107000 <0> ffff88022e76b000 00007fffffffe000 00007ffffffff000 00007fff4c106000 <0> ffffffff810c5e5a ffff88022ebd5780 ffff88022ebd5780 ffff88022ebd5780 Call Trace: [<ffffffff810aabac>] ? expand_downwards+0x149/0x15a [<ffffffff810c5e5a>] ? setup_arg_pages+0x333/0x361 [<ffffffff810c8955>] ? inode_permission+0x76/0x95 [<ffffffff810f8a19>] ? load_elf_binary+0x0/0x16c9 [<ffffffff810f8e7e>] ? load_elf_binary+0x465/0x16c9 [<ffffffff810c488a>] ? get_arg_page+0x4b/0xa4 [<ffffffff810f8a19>] ? load_elf_binary+0x0/0x16c9 [<ffffffff810c4ce4>] ? search_binary_handler+0xd4/0x26f [<ffffffff810f7a1c>] ? load_script+0x0/0x1e4 [<ffffffff810f7bea>] ? load_script+0x1ce/0x1e4 [<ffffffff810c488a>] ? get_arg_page+0x4b/0xa4 [<ffffffff810c4ce4>] ? search_binary_handler+0xd4/0x26f [<ffffffff810c6228>] ? do_execve+0x1e5/0x2b6 [<ffffffff81008d60>] ? sys_execve+0x35/0x53 [<ffffffff81003648>] ? kernel_execve+0x68/0xd0 [<ffffffff81000342>] ? init_post+0x5a/0xd4 [<ffffffff81cdf97d>] ? kernel_init+0x1e5/0x1ec [<ffffffff810035d4>] ? kernel_thread_helper+0x4/0x10 [<ffffffff81cdf798>] ? kernel_init+0x0/0x1ec [<ffffffff810035d0>] ? kernel_thread_helper+0x0/0x10 Code: 1c 24 44 89 64 24 08 48 c7 44 24 20 07 fd 04 81 48 89 44 24 28 48Quoted 5 lines
89 44 24 30 e8 26 ff ff ff 48 83 c4 48 5b 41 5c 41 5d 41 5e c3 <48> c7 47 18 00 00 00 00 f0 ff 07 7f 05 e8 01 00 00 00 c3 53 48 RIP [<
ffffffff8160e055>]mutex_unlock+0x0/0x13
RSP <ffff88022fc61a78>---[ end trace dc724d36e0cd4a32 ]---
Quoted 2 lines
Oi, that's no good. Happen to have your .config handy, I didn't actually see my machine do that.
See the attachment.
Yanmin
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.35-rc2
# Thu Jun 10 02:21:26 2010
#CONFIG_64BIT=y
# CONFIG_X86_32 is not setCONFIG_X86_64=yCONFIG_X86=yCONFIG_INSTRUCTION_DECODER=yCONFIG_OUTPUT_FORMAT="elf64-x86-64"CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"CONFIG_GENERIC_TIME=yCONFIG_GENERIC_CMOS_UPDATE=yCONFIG_CLOCKSOURCE_WATCHDOG=yCONFIG_GENERIC_CLOCKEVENTS=yCONFIG_GENERIC_CLOCKEVENTS_BROADCAST=yCONFIG_LOCKDEP_SUPPORT=yCONFIG_STACKTRACE_SUPPORT=yCONFIG_HAVE_LATENCYTOP_SUPPORT=yCONFIG_MMU=yCONFIG_ZONE_DMA=yCONFIG_NEED_DMA_MAP_STATE=yCONFIG_NEED_SG_DMA_LENGTH=yCONFIG_GENERIC_ISA_DMA=yCONFIG_GENERIC_IOMAP=yCONFIG_GENERIC_BUG=yCONFIG_GENERIC_BUG_RELATIVE_POINTERS=yCONFIG_GENERIC_HWEIGHT=yCONFIG_ARCH_MAY_HAVE_PC_FDC=y
# CONFIG_RWSEM_GENERIC_SPINLOCK is not setCONFIG_RWSEM_XCHGADD_ALGORITHM=yCONFIG_ARCH_HAS_CPU_IDLE_WAIT=yCONFIG_GENERIC_CALIBRATE_DELAY=yCONFIG_GENERIC_TIME_VSYSCALL=yCONFIG_ARCH_HAS_CPU_RELAX=yCONFIG_ARCH_HAS_DEFAULT_IDLE=yCONFIG_ARCH_HAS_CACHE_LINE_SIZE=yCONFIG_HAVE_SETUP_PER_CPU_AREA=yCONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=yCONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=yCONFIG_HAVE_CPUMASK_OF_CPU_MAP=yCONFIG_ARCH_HIBERNATION_POSSIBLE=yCONFIG_ARCH_SUSPEND_POSSIBLE=yCONFIG_ZONE_DMA32=yCONFIG_ARCH_POPULATES_NODE_MAP=yCONFIG_AUDIT_ARCH=yCONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=yCONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=yCONFIG_HAVE_EARLY_RES=yCONFIG_GENERIC_HARDIRQS=yCONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=yCONFIG_GENERIC_IRQ_PROBE=yCONFIG_GENERIC_PENDING_IRQ=yCONFIG_USE_GENERIC_SMP_HELPERS=yCONFIG_X86_64_SMP=yCONFIG_X86_HT=yCONFIG_X86_TRAMPOLINE=yCONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" # CONFIG_KTIME_SCALAR is not setCONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"CONFIG_CONSTRUCTORS=y
#
# General setup
#CONFIG_EXPERIMENTAL=yCONFIG_LOCK_KERNEL=yCONFIG_INIT_ENV_ARG_LIMIT=32CONFIG_CROSS_COMPILE=""CONFIG_LOCALVERSION="-petermm"
# CONFIG_LOCALVERSION_AUTO is not setCONFIG_HAVE_KERNEL_GZIP=yCONFIG_HAVE_KERNEL_BZIP2=yCONFIG_HAVE_KERNEL_LZMA=yCONFIG_HAVE_KERNEL_LZO=yCONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_LZO is not setCONFIG_SWAP=yCONFIG_SYSVIPC=yCONFIG_SYSVIPC_SYSCTL=yCONFIG_POSIX_MQUEUE=yCONFIG_POSIX_MQUEUE_SYSCTL=yCONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not setCONFIG_TASKSTATS=yCONFIG_TASK_DELAY_ACCT=y
# CONFIG_TASK_XACCT is not set
# CONFIG_AUDIT is not set
#
# RCU Subsystem
#CONFIG_TREE_RCU=y
# CONFIG_TREE_PREEMPT_RCU is not set
# CONFIG_TINY_RCU is not set
# CONFIG_RCU_TRACE is not setCONFIG_RCU_FANOUT=64
# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_RCU_FAST_NO_HZ is not set
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not setCONFIG_LOG_BUF_SHIFT=17CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=yCONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not setCONFIG_CGROUP_NS=y
# CONFIG_CGROUP_FREEZER is not set
# CONFIG_CGROUP_DEVICE is not setCONFIG_CPUSETS=yCONFIG_PROC_PID_CPUSET=yCONFIG_CGROUP_CPUACCT=yCONFIG_RESOURCE_COUNTERS=y
# CONFIG_CGROUP_MEM_RES_CTLR is not setCONFIG_CGROUP_SCHED=yCONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
# CONFIG_BLK_CGROUP is not setCONFIG_SYSFS_DEPRECATED=yCONFIG_SYSFS_DEPRECATED_V2=yCONFIG_RELAY=yCONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
# CONFIG_NET_NS is not setCONFIG_BLK_DEV_INITRD=yCONFIG_INITRAMFS_SOURCE=""CONFIG_RD_GZIP=yCONFIG_RD_BZIP2=yCONFIG_RD_LZMA=yCONFIG_RD_LZO=yCONFIG_CC_OPTIMIZE_FOR_SIZE=yCONFIG_SYSCTL=yCONFIG_ANON_INODES=y
# CONFIG_EMBEDDED is not setCONFIG_UID16=yCONFIG_SYSCTL_SYSCALL=yCONFIG_KALLSYMS=yCONFIG_KALLSYMS_ALL=yCONFIG_KALLSYMS_EXTRA_PASS=yCONFIG_HOTPLUG=yCONFIG_PRINTK=yCONFIG_BUG=yCONFIG_ELF_CORE=yCONFIG_PCSPKR_PLATFORM=yCONFIG_BASE_FULL=yCONFIG_FUTEX=yCONFIG_EPOLL=yCONFIG_SIGNALFD=yCONFIG_TIMERFD=yCONFIG_EVENTFD=yCONFIG_SHMEM=yCONFIG_AIO=yCONFIG_HAVE_PERF_EVENTS=y
#
# Kernel Performance Events And Counters
#CONFIG_PERF_EVENTS=y
# CONFIG_PERF_COUNTERS is not set
# CONFIG_DEBUG_PERF_USE_VMALLOC is not setCONFIG_VM_EVENT_COUNTERS=yCONFIG_PCI_QUIRKS=yCONFIG_SLUB_DEBUG=yCONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not setCONFIG_SLUB=y
# CONFIG_SLOB is not setCONFIG_PROFILING=yCONFIG_TRACEPOINTS=yCONFIG_OPROFILE=y
# CONFIG_OPROFILE_EVENT_MULTIPLEX is not setCONFIG_HAVE_OPROFILE=yCONFIG_KPROBES=yCONFIG_OPTPROBES=yCONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=yCONFIG_KRETPROBES=yCONFIG_HAVE_IOREMAP_PROT=yCONFIG_HAVE_KPROBES=yCONFIG_HAVE_KRETPROBES=yCONFIG_HAVE_OPTPROBES=yCONFIG_HAVE_ARCH_TRACEHOOK=yCONFIG_HAVE_DMA_ATTRS=yCONFIG_HAVE_REGS_AND_STACK_ACCESS_API=yCONFIG_HAVE_DMA_API_DEBUG=yCONFIG_HAVE_HW_BREAKPOINT=yCONFIG_HAVE_MIXED_BREAKPOINTS_REGS=yCONFIG_HAVE_USER_RETURN_NOTIFIER=y
#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not setCONFIG_SLOW_WORK=y
# CONFIG_SLOW_WORK_DEBUG is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not setCONFIG_SLABINFO=yCONFIG_RT_MUTEXES=yCONFIG_BASE_SMALL=0CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not setCONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not setCONFIG_MODVERSIONS=yCONFIG_MODULE_SRCVERSION_ALL=yCONFIG_STOP_MACHINE=yCONFIG_BLOCK=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not setCONFIG_BLOCK_COMPAT=y
#
# IO Schedulers
#CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_INLINE_SPIN_TRYLOCK is not set
# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set # CONFIG_INLINE_SPIN_LOCK is not set
# CONFIG_INLINE_SPIN_LOCK_BH is not set
# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set CONFIG_INLINE_SPIN_UNLOCK=y
# CONFIG_INLINE_SPIN_UNLOCK_BH is not set CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set # CONFIG_INLINE_READ_TRYLOCK is not set
# CONFIG_INLINE_READ_LOCK is not set
# CONFIG_INLINE_READ_LOCK_BH is not set
# CONFIG_INLINE_READ_LOCK_IRQ is not set
# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set CONFIG_INLINE_READ_UNLOCK=y
# CONFIG_INLINE_READ_UNLOCK_BH is not set CONFIG_INLINE_READ_UNLOCK_IRQ=y
# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set # CONFIG_INLINE_WRITE_TRYLOCK is not set
# CONFIG_INLINE_WRITE_LOCK is not set
# CONFIG_INLINE_WRITE_LOCK_BH is not set
# CONFIG_INLINE_WRITE_LOCK_IRQ is not set # CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set CONFIG_INLINE_WRITE_UNLOCK=y
# CONFIG_INLINE_WRITE_UNLOCK_BH is not set CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_FREEZER=y
#
# Processor type and features
#CONFIG_TICK_ONESHOT=yCONFIG_NO_HZ=yCONFIG_HIGH_RES_TIMERS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_SMP=y
# CONFIG_SPARSE_IRQ is not set CONFIG_X86_MPPARSE=y CONFIG_X86_EXTENDED_PLATFORM=y
# CONFIG_X86_VSMP is not set CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y CONFIG_SCHED_OMIT_FRAME_POINTER=y
# CONFIG_PARAVIRT_GUEST is not set CONFIG_NO_BOOTMEM=y
# CONFIG_MEMTEST is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
# CONFIG_MATOM is not set CONFIG_GENERIC_CPU=yCONFIG_X86_CPU=y CONFIG_X86_INTERNODE_CACHE_SHIFT=6 CONFIG_X86_CMPXCHG=y CONFIG_X86_L1_CACHE_SHIFT=6 CONFIG_X86_XADD=yCONFIG_X86_WP_WORKS_OK=yCONFIG_X86_TSC=yCONFIG_X86_CMPXCHG64=yCONFIG_X86_CMOV=y CONFIG_X86_MINIMUM_CPU_FAMILY=64 CONFIG_X86_DEBUGCTLMSR=y CONFIG_CPU_SUP_INTEL=yCONFIG_CPU_SUP_AMD=y CONFIG_CPU_SUP_CENTAUR=yCONFIG_HPET_TIMER=yCONFIG_DMI=yCONFIG_GART_IOMMU=y
# CONFIG_CALGARY_IOMMU is not set
# CONFIG_AMD_IOMMU is not set CONFIG_SWIOTLB=yCONFIG_IOMMU_HELPER=y
# CONFIG_IOMMU_API is not set
# CONFIG_MAXSMP is not setCONFIG_NR_CPUS=32CONFIG_SCHED_SMT=yCONFIG_SCHED_MC=y
# CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=yCONFIG_X86_IO_APIC=y
# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set CONFIG_X86_MCE=yCONFIG_X86_MCE_INTEL=yCONFIG_X86_MCE_AMD=y CONFIG_X86_MCE_THRESHOLD=y
# CONFIG_X86_MCE_INJECT is not set CONFIG_X86_THERMAL_VECTOR=y
# CONFIG_I8K is not set
# CONFIG_MICROCODE is not set
# CONFIG_X86_MSR is not set
# CONFIG_X86_CPUID is not set CONFIG_ARCH_PHYS_ADDR_T_64BIT=y CONFIG_DIRECT_GBPAGES=y
# CONFIG_NUMA is not set CONFIG_ARCH_PROC_KCORE_TEXT=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
# CONFIG_DISCONTIGMEM_MANUAL is not set CONFIG_SPARSEMEM_MANUAL=yCONFIG_SPARSEMEM=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y CONFIG_SPARSEMEM_VMEMMAP=y
# CONFIG_MEMORY_HOTPLUG is not set CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_COMPACTION is not set CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=1CONFIG_BOUNCE=yCONFIG_VIRT_TO_BUS=y
# CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
# CONFIG_MEMORY_FAILURE is not set
# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set CONFIG_X86_RESERVE_LOW_64K=yCONFIG_MTRR=y
# CONFIG_MTRR_SANITIZER is not set CONFIG_X86_PAT=y CONFIG_ARCH_USES_PG_UNCACHED=y
# CONFIG_EFI is not set
# CONFIG_SECCOMP is not set
# CONFIG_CC_STACKPROTECTOR is not set
# CONFIG_HZ_100 is not setCONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not setCONFIG_HZ=250CONFIG_SCHED_HRTICK=yCONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x1000000 CONFIG_RELOCATABLE=y CONFIG_PHYSICAL_ALIGN=0x1000000 CONFIG_HOTPLUG_CPU=yCONFIG_COMPAT_VDSO=y
# CONFIG_CMDLINE_BOOL is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
#
# Power management and ACPI options
#CONFIG_PM=y
# CONFIG_PM_DEBUG is not setCONFIG_PM_SLEEP_SMP=yCONFIG_PM_SLEEP=yCONFIG_SUSPEND=yCONFIG_SUSPEND_FREEZER=y
# CONFIG_HIBERNATION is not set
# CONFIG_PM_RUNTIME is not setCONFIG_PM_OPS=yCONFIG_ACPI=yCONFIG_ACPI_SLEEP=yCONFIG_ACPI_PROCFS=yCONFIG_ACPI_PROCFS_POWER=yCONFIG_ACPI_SYSFS_POWER=yCONFIG_ACPI_PROC_EVENT=yCONFIG_ACPI_AC=yCONFIG_ACPI_BATTERY=yCONFIG_ACPI_BUTTON=yCONFIG_ACPI_VIDEO=mCONFIG_ACPI_FAN=yCONFIG_ACPI_DOCK=yCONFIG_ACPI_PROCESSOR=yCONFIG_ACPI_HOTPLUG_CPU=y
# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not setCONFIG_ACPI_THERMAL=y
# CONFIG_ACPI_CUSTOM_DSDT is not setCONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
# CONFIG_ACPI_PCI_SLOT is not setCONFIG_X86_PM_TIMER=yCONFIG_ACPI_CONTAINER=y
# CONFIG_ACPI_SBS is not set
# CONFIG_ACPI_HED is not set
# CONFIG_ACPI_APEI is not set
# CONFIG_SFI is not set
#
# CPU Frequency scaling
#CONFIG_CPU_FREQ=yCONFIG_CPU_FREQ_TABLE=y CONFIG_CPU_FREQ_DEBUG=y CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_STAT_DETAILS=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
#
# CPUFreq processor drivers
#
# CONFIG_X86_PCC_CPUFREQ is not setCONFIG_X86_ACPI_CPUFREQ=yCONFIG_X86_POWERNOW_K8=yCONFIG_X86_SPEEDSTEP_CENTRINO=y
# CONFIG_X86_P4_CLOCKMOD is not set
#
# shared options # # CONFIG_X86_SPEEDSTEP_LIB is not set CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y # CONFIG_INTEL_IDLE is not set
#
# Memory power savings
#
# CONFIG_I7300_IDLE is not set
#
# Bus options (PCI etc.)
#CONFIG_PCI=yCONFIG_PCI_DIRECT=yCONFIG_PCI_MMCONFIG=yCONFIG_PCI_DOMAINS=y
# CONFIG_PCI_CNB20LE_QUIRK is not set
# CONFIG_DMAR is not set
# CONFIG_INTR_REMAP is not setCONFIG_PCIEPORTBUS=yCONFIG_HOTPLUG_PCI_PCIE=yCONFIG_PCIEAER=y
# CONFIG_PCIE_ECRC is not set
# CONFIG_PCIEAER_INJECT is not set
# CONFIG_PCIEASPM is not setCONFIG_ARCH_SUPPORTS_MSI=yCONFIG_PCI_MSI=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not setCONFIG_HT_IRQ=y
# CONFIG_PCI_IOV is not setCONFIG_PCI_IOAPIC=yCONFIG_ISA_DMA_API=yCONFIG_K8_NB=yCONFIG_PCCARD=yCONFIG_PCMCIA=yCONFIG_PCMCIA_LOAD_CIS=yCONFIG_CARDBUS=y
#
# PC-card bridges
#CONFIG_YENTA=yCONFIG_YENTA_O2=yCONFIG_YENTA_RICOH=yCONFIG_YENTA_TI=yCONFIG_YENTA_ENE_TUNE=yCONFIG_YENTA_TOSHIBA=y
# CONFIG_PD6729 is not set
# CONFIG_I82092 is not setCONFIG_PCCARD_NONSTATIC=yCONFIG_HOTPLUG_PCI=y
# CONFIG_HOTPLUG_PCI_FAKE is not setCONFIG_HOTPLUG_PCI_ACPI=y
# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
# CONFIG_HOTPLUG_PCI_CPCI is not set
# CONFIG_HOTPLUG_PCI_SHPC is not set
#
# Executable file formats / Emulations
#CONFIG_BINFMT_ELF=yCONFIG_COMPAT_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not setCONFIG_BINFMT_MISC=yCONFIG_IA32_EMULATION=yCONFIG_IA32_AOUT=yCONFIG_COMPAT=yCONFIG_COMPAT_FOR_U64_ALIGNMENT=yCONFIG_SYSVIPC_COMPAT=yCONFIG_NET=y
#
# Networking options
#CONFIG_PACKET=yCONFIG_UNIX=yCONFIG_XFRM=yCONFIG_XFRM_USER=y
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
# CONFIG_XFRM_STATISTICS is not set
# CONFIG_NET_KEY is not setCONFIG_INET=yCONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_ASK_IP_FIB_HASH=y
# CONFIG_IP_FIB_TRIE is not set CONFIG_IP_FIB_HASH=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set CONFIG_IP_MROUTE=y
# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set CONFIG_IP_PIMSM_V1=yCONFIG_IP_PIMSM_V2=y
# CONFIG_ARPD is not setCONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set CONFIG_INET_TUNNEL=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set CONFIG_INET_XFRM_MODE_BEET=y
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set CONFIG_TCP_CONG_ADVANCED=y CONFIG_TCP_CONG_BIC=y
# CONFIG_TCP_CONG_CUBIC is not set
# CONFIG_TCP_CONG_WESTWOOD is not set
# CONFIG_TCP_CONG_HTCP is not set
# CONFIG_TCP_CONG_HSTCP is not set
# CONFIG_TCP_CONG_HYBLA is not set
# CONFIG_TCP_CONG_VEGAS is not set
# CONFIG_TCP_CONG_SCALABLE is not set
# CONFIG_TCP_CONG_LP is not set
# CONFIG_TCP_CONG_VENO is not set
# CONFIG_TCP_CONG_YEAH is not set
# CONFIG_TCP_CONG_ILLINOIS is not set CONFIG_DEFAULT_BIC=y
# CONFIG_DEFAULT_CUBIC is not set
# CONFIG_DEFAULT_HTCP is not set
# CONFIG_DEFAULT_HYBLA is not set
# CONFIG_DEFAULT_VEGAS is not set
# CONFIG_DEFAULT_VENO is not set
# CONFIG_DEFAULT_WESTWOOD is not set
# CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="bic"
# CONFIG_TCP_MD5SIG is not setCONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_IPV6_ROUTER_PREF is not set
# CONFIG_IPV6_OPTIMISTIC_DAD is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set CONFIG_INET6_XFRM_MODE_TRANSPORT=y CONFIG_INET6_XFRM_MODE_TUNNEL=y CONFIG_INET6_XFRM_MODE_BEET=y
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=y
# CONFIG_IPV6_SIT_6RD is not set CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_IPV6_MROUTE is not set
# CONFIG_NETLABEL is not set CONFIG_NETWORK_SECMARK=y
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not setCONFIG_IP_SCTP=y
# CONFIG_NET_SCTPPROBE is not set
# CONFIG_SCTP_DBG_MSG is not set
# CONFIG_SCTP_DBG_OBJCNT is not set
# CONFIG_SCTP_HMAC_NONE is not set
# CONFIG_SCTP_HMAC_SHA1 is not set CONFIG_SCTP_HMAC_MD5=y
# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_L2TP is not set
# CONFIG_BRIDGE is not set
# CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=y
# CONFIG_VLAN_8021Q_GVRP is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not setCONFIG_RPS=y
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_NET_TCPPROBE is not set
# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not setCONFIG_FIB_RULES=yCONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_LIB80211 is not set
#
# CFG80211 needs to be enabled for MAC80211
#
#
# Some wireless drivers require a rate control algorithm #
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
# CONFIG_CAIF is not set
#
# Device Drivers
#
#
# Generic Driver Options
#CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_DEVTMPFS is not setCONFIG_STANDALONE=yCONFIG_PREVENT_FIRMWARE_BUILD=yCONFIG_FW_LOADER=yCONFIG_FIRMWARE_IN_KERNEL=yCONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not setCONFIG_CONNECTOR=yCONFIG_PROC_EVENTS=y
# CONFIG_MTD is not set
# CONFIG_PARPORT is not setCONFIG_PNP=yCONFIG_PNP_DEBUG_MESSAGES=y
#
# Protocols
#CONFIG_PNPACPI=yCONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not setCONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_DRBD is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not setCONFIG_BLK_DEV_RAM=yCONFIG_BLK_DEV_RAM_COUNT=16CONFIG_BLK_DEV_RAM_SIZE=16384
# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not setCONFIG_MISC_DEVICES=y
# CONFIG_AD525X_DPOT is not set
# CONFIG_IBM_ASM is not set
# CONFIG_PHANTOM is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_CS5535_MFGPT is not set
# CONFIG_HP_ILO is not set
# CONFIG_ISL29003 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_DS1682 is not set
# CONFIG_VMWARE_BALLOON is not set
# CONFIG_C2PORT is not set
#
# EEPROM support
#
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_LEGACY is not set
# CONFIG_EEPROM_MAX6875 is not set
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_CB710_CORE is not setCONFIG_HAVE_IDE=yCONFIG_IDE=y
#
# Please see Documentation/ide/ide.txt for help/info on IDE drives #CONFIG_IDE_XFER_MODE=yCONFIG_IDE_TIMINGS=yCONFIG_IDE_ATAPI=y
# CONFIG_BLK_DEV_IDE_SATA is not setCONFIG_IDE_GD=yCONFIG_IDE_GD_ATA=y
# CONFIG_IDE_GD_ATAPI is not set
# CONFIG_BLK_DEV_IDECS is not set
# CONFIG_BLK_DEV_DELKIN is not set CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEACPI is not set CONFIG_IDE_TASK_IOCTL=yCONFIG_IDE_PROC_FS=y
#
# IDE chipset support/bugfixes
#CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_PLATFORM is not setCONFIG_BLK_DEV_CMD640=yCONFIG_BLK_DEV_CMD640_ENHANCED=yCONFIG_BLK_DEV_IDEPNP=yCONFIG_BLK_DEV_IDEDMA_SFF=y
#
# PCI IDE chipsets support
#CONFIG_BLK_DEV_IDEPCI=yCONFIG_IDEPCI_PCIBUS_ORDER=y
# CONFIG_BLK_DEV_OFFBOARD is not setCONFIG_BLK_DEV_GENERIC=y
# CONFIG_BLK_DEV_OPTI621 is not setCONFIG_BLK_DEV_RZ1000=yCONFIG_BLK_DEV_IDEDMA_PCI=yCONFIG_BLK_DEV_AEC62XX=yCONFIG_BLK_DEV_ALI15X3=yCONFIG_BLK_DEV_AMD74XX=yCONFIG_BLK_DEV_ATIIXP=yCONFIG_BLK_DEV_CMD64X=yCONFIG_BLK_DEV_TRIFLEX=yCONFIG_BLK_DEV_CS5520=yCONFIG_BLK_DEV_CS5530=yCONFIG_BLK_DEV_HPT366=y
# CONFIG_BLK_DEV_JMICRON is not set
# CONFIG_BLK_DEV_SC1200 is not setCONFIG_BLK_DEV_PIIX=y
# CONFIG_BLK_DEV_IT8172 is not set
# CONFIG_BLK_DEV_IT8213 is not setCONFIG_BLK_DEV_IT821X=y
# CONFIG_BLK_DEV_NS87415 is not setCONFIG_BLK_DEV_PDC202XX_OLD=yCONFIG_BLK_DEV_PDC202XX_NEW=yCONFIG_BLK_DEV_SVWKS=yCONFIG_BLK_DEV_SIIMAGE=yCONFIG_BLK_DEV_SIS5513=y
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not setCONFIG_BLK_DEV_VIA82CXXX=y
# CONFIG_BLK_DEV_TC86C001 is not setCONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#CONFIG_SCSI_MOD=yCONFIG_RAID_ATTRS=yCONFIG_SCSI=yCONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not setCONFIG_SCSI_NETLINK=yCONFIG_SCSI_PROC_FS=y
#
# SCSI support type (disk, tape, CD-ROM)
#CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not setCONFIG_BLK_DEV_SR=yCONFIG_BLK_DEV_SR_VENDOR=yCONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not setCONFIG_SCSI_MULTI_LUN=yCONFIG_SCSI_CONSTANTS=yCONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SCAN_ASYNC is not setCONFIG_SCSI_WAIT_SCAN=m
#
# SCSI Transports
#CONFIG_SCSI_SPI_ATTRS=yCONFIG_SCSI_FC_ATTRS=yCONFIG_SCSI_ISCSI_ATTRS=yCONFIG_SCSI_SAS_ATTRS=yCONFIG_SCSI_SAS_LIBSAS=y
# CONFIG_SCSI_SAS_ATA is not setCONFIG_SCSI_SAS_HOST_SMP=y
# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
# CONFIG_SCSI_SRP_ATTRS is not setCONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_HPSA is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_3W_SAS is not setCONFIG_SCSI_ACARD=yCONFIG_SCSI_AACRAID=yCONFIG_SCSI_AIC7XXX=yCONFIG_AIC7XXX_CMDS_PER_DEVICE=4CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_DEBUG_ENABLE is not setCONFIG_AIC7XXX_DEBUG_MASK=0
# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not setCONFIG_SCSI_AIC7XXX_OLD=mCONFIG_SCSI_AIC79XX=mCONFIG_AIC79XX_CMDS_PER_DEVICE=4CONFIG_AIC79XX_RESET_DELAY_MS=15000
# CONFIG_AIC79XX_DEBUG_ENABLE is not setCONFIG_AIC79XX_DEBUG_MASK=0
# CONFIG_AIC79XX_REG_PRETTY_PRINT is not setCONFIG_SCSI_AIC94XX=y
# CONFIG_AIC94XX_DEBUG is not set
# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_ARCMSR is not setCONFIG_MEGARAID_NEWGEN=yCONFIG_MEGARAID_MM=yCONFIG_MEGARAID_MAILBOX=yCONFIG_MEGARAID_LEGACY=yCONFIG_MEGARAID_SAS=y
# CONFIG_SCSI_MPT2SAS is not setCONFIG_SCSI_HPTIOP=yCONFIG_SCSI_BUSLOGIC=y
# CONFIG_VMWARE_PVSCSI is not set
# CONFIG_LIBFC is not set
# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_FCOE_FNIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not setCONFIG_SCSI_GDTH=y
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not setCONFIG_SCSI_QLOGIC_1280=mCONFIG_SCSI_QLA_FC=mCONFIG_SCSI_QLA_ISCSI=m
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_PM8001 is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not setCONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not setCONFIG_ATA_VERBOSE_ERROR=yCONFIG_ATA_ACPI=yCONFIG_SATA_PMP=y
#
# Controllers with non-SFF native interface
#CONFIG_SATA_AHCI=y
# CONFIG_SATA_AHCI_PLATFORM is not set
# CONFIG_SATA_INIC162X is not set
# CONFIG_SATA_SIL24 is not setCONFIG_ATA_SFF=y
#
# SFF controllers with custom DMA interface
#
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_SX4 is not setCONFIG_ATA_BMDMA=y
#
# SATA SFF controllers with BMDMA
#CONFIG_ATA_PIIX=y
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_SIL is not set
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_SVW is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set
#
# PATA SFF controllers with BMDMA
#
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_MARVELL is not set
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NINJA32 is not set
# CONFIG_PATA_NS87415 is not set
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RDC is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SCH is not set
# CONFIG_PATA_SERVERWORKS is not set
# CONFIG_PATA_SIL680 is not set
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_TOSHIBA is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set
#
# PIO-only SFF controllers
#
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_MPIIX is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_PCMCIA is not set
# CONFIG_PATA_RZ1000 is not set
#
# Generic fallback / legacy drivers
#
# CONFIG_PATA_ACPI is not set
# CONFIG_ATA_GENERIC is not set
# CONFIG_PATA_LEGACY is not setCONFIG_MD=yCONFIG_BLK_DEV_MD=yCONFIG_MD_AUTODETECT=yCONFIG_MD_LINEAR=yCONFIG_MD_RAID0=yCONFIG_MD_RAID1=yCONFIG_MD_RAID10=yCONFIG_MD_RAID456=y
# CONFIG_MULTICORE_RAID456 is not setCONFIG_MD_RAID6_PQ=y
# CONFIG_ASYNC_RAID6_TEST is not setCONFIG_MD_MULTIPATH=yCONFIG_MD_FAULTY=yCONFIG_BLK_DEV_DM=y
# CONFIG_DM_DEBUG is not setCONFIG_DM_CRYPT=yCONFIG_DM_SNAPSHOT=yCONFIG_DM_MIRROR=y
# CONFIG_DM_LOG_USERSPACE is not setCONFIG_DM_ZERO=yCONFIG_DM_MULTIPATH=y
# CONFIG_DM_MULTIPATH_QL is not set
# CONFIG_DM_MULTIPATH_ST is not set
# CONFIG_DM_DELAY is not set
# CONFIG_DM_UEVENT is not setCONFIG_FUSION=yCONFIG_FUSION_SPI=yCONFIG_FUSION_FC=yCONFIG_FUSION_SAS=yCONFIG_FUSION_MAX_SGE=40CONFIG_FUSION_CTL=y
# CONFIG_FUSION_LOGGING is not set
#
# IEEE 1394 (FireWire) support
#
#
# You can enable one or both FireWire driver stacks. #
#
# The newer stack is recommended.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
# CONFIG_MACINTOSH_DRIVERS is not setCONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
# CONFIG_NET_SB1000 is not set
# CONFIG_ARCNET is not setCONFIG_PHYLIB=y
#
# MII PHY device drivers
#
# CONFIG_MARVELL_PHY is not set
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
# CONFIG_LXT_PHY is not set
# CONFIG_CICADA_PHY is not set
# CONFIG_VITESSE_PHY is not set
# CONFIG_SMSC_PHY is not set
# CONFIG_BROADCOM_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_REALTEK_PHY is not set
# CONFIG_NATIONAL_PHY is not set
# CONFIG_STE10XP is not set
# CONFIG_LSI_ET1011C_PHY is not set
# CONFIG_MICREL_PHY is not set
# CONFIG_FIXED_PHY is not set
# CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=yCONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_ETHOC is not set
# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_KSZ884X_PCI is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set CONFIG_E100=y
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
# CONFIG_8139TOO is not set
# CONFIG_R6040 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SMSC9420 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_KS8842 is not set
# CONFIG_KS8851_MLL is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not setCONFIG_E1000=yCONFIG_E1000E=y
# CONFIG_IP1000 is not setCONFIG_IGB=y
# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
# CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=yCONFIG_BNX2=y
# CONFIG_CNIC is not set
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
# CONFIG_ATL1C is not set
# CONFIG_JME is not set CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_CHELSIO_T3 is not set CONFIG_CHELSIO_T4_DEPENDS=y
# CONFIG_CHELSIO_T4 is not set
# CONFIG_ENIC is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGBEVF is not setCONFIG_IXGB=y
# CONFIG_S2IO is not set
# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
# CONFIG_MLX4_EN is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
# CONFIG_BNX2X is not set
# CONFIG_QLCNIC is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not setCONFIG_WLAN=y
# CONFIG_PCMCIA_RAYCS is not set
# CONFIG_AIRO is not set
# CONFIG_ATMEL is not set
# CONFIG_AIRO_CS is not set
# CONFIG_PCMCIA_WL3501 is not set
# CONFIG_PRISM54 is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_HOSTAP is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers #
#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
# CONFIG_USB_IPHETH is not set
# CONFIG_NET_PCMCIA is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_FC is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_VMXNET3 is not set
# CONFIG_ISDN is not set
# CONFIG_PHONE is not set
#
# Input device support
#CONFIG_INPUT=yCONFIG_INPUT_FF_MEMLESS=y
# CONFIG_INPUT_POLLDEV is not set
# CONFIG_INPUT_SPARSEKMAP is not set
#
# Userland interfaces
#CONFIG_INPUT_MOUSEDEV=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not setCONFIG_INPUT_MOUSEDEV_SCREEN_X=1024CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not setCONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
# Input Device Drivers
#CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_ADP5588 is not setCONFIG_KEYBOARD_ATKBD=y
# CONFIG_QT2160 is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_TCA6416 is not set
# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not setCONFIG_INPUT_MOUSE=yCONFIG_MOUSE_PS2=yCONFIG_MOUSE_PS2_ALPS=yCONFIG_MOUSE_PS2_LOGIPS2PP=yCONFIG_MOUSE_PS2_SYNAPTICS=yCONFIG_MOUSE_PS2_LIFEBOOK=yCONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_ELANTECH is not set
# CONFIG_MOUSE_PS2_SENTELIC is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not setCONFIG_MOUSE_SERIAL=y
# CONFIG_MOUSE_APPLETOUCH is not set
# CONFIG_MOUSE_BCM5974 is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_MOUSE_SYNAPTICS_I2C is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not setCONFIG_INPUT_MISC=y
# CONFIG_INPUT_AD714X is not set
# CONFIG_INPUT_PCSPKR is not set
# CONFIG_INPUT_ATLAS_BTNS is not set
# CONFIG_INPUT_ATI_REMOTE is not set
# CONFIG_INPUT_ATI_REMOTE2 is not set
# CONFIG_INPUT_KEYSPAN_REMOTE is not set
# CONFIG_INPUT_POWERMATE is not set
# CONFIG_INPUT_YEALINK is not set
# CONFIG_INPUT_CM109 is not set
# CONFIG_INPUT_UINPUT is not set
# CONFIG_INPUT_WINBOND_CIR is not set
# CONFIG_INPUT_PCF8574 is not set
#
# Hardware I/O ports
#CONFIG_SERIO=yCONFIG_SERIO_I8042=yCONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not setCONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_SERIO_ALTERA_PS2 is not set
# CONFIG_GAMEPORT is not set
#
# Character devices
#CONFIG_VT=yCONFIG_CONSOLE_TRANSLATIONS=yCONFIG_VT_CONSOLE=yCONFIG_HW_CONSOLE=yCONFIG_VT_HW_CONSOLE_BINDING=yCONFIG_DEVKMEM=yCONFIG_SERIAL_NONSTANDARD=y
# CONFIG_COMPUTONE is not set
# CONFIG_ROCKETPORT is not set
# CONFIG_CYCLADES is not set
# CONFIG_DIGIEPCA is not set
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_ISI is not set
# CONFIG_SYNCLINK is not set
# CONFIG_SYNCLINKMP is not set
# CONFIG_SYNCLINK_GT is not set
# CONFIG_N_HDLC is not set
# CONFIG_N_GSM is not set
# CONFIG_RISCOM8 is not set
# CONFIG_SPECIALIX is not set
# CONFIG_STALDRV is not set
# CONFIG_NOZOMI is not set
#
# Serial drivers
#CONFIG_SERIAL_8250=yCONFIG_SERIAL_8250_CONSOLE=yCONFIG_FIX_EARLYCON_MEM=yCONFIG_SERIAL_8250_PCI=yCONFIG_SERIAL_8250_PNP=y
# CONFIG_SERIAL_8250_CS is not setCONFIG_SERIAL_8250_NR_UARTS=32CONFIG_SERIAL_8250_RUNTIME_UARTS=4CONFIG_SERIAL_8250_EXTENDED=yCONFIG_SERIAL_8250_MANY_PORTS=yCONFIG_SERIAL_8250_SHARE_IRQ=yCONFIG_SERIAL_8250_DETECT_IRQ=yCONFIG_SERIAL_8250_RSA=y
#
# Non-8250 serial port support
#CONFIG_SERIAL_CORE=yCONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not setCONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not setCONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_TIMERIOMEM is not setCONFIG_HW_RANDOM_INTEL=yCONFIG_HW_RANDOM_AMD=yCONFIG_HW_RANDOM_VIA=yCONFIG_NVRAM=y
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
#
# PCMCIA character devices
#
# CONFIG_SYNCLINK_CS is not set
# CONFIG_CARDMAN_4000 is not set
# CONFIG_CARDMAN_4040 is not set
# CONFIG_IPWIRELESS is not set
# CONFIG_MWAVE is not set
# CONFIG_PC8736x_GPIO is not set
# CONFIG_RAW_DRIVER is not setCONFIG_HPET=y
# CONFIG_HPET_MMAP is not set
# CONFIG_HANGCHECK_TIMER is not set
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not setCONFIG_DEVPORT=y
# CONFIG_RAMOOPS is not setCONFIG_I2C=yCONFIG_I2C_BOARDINFO=yCONFIG_I2C_COMPAT=y
# CONFIG_I2C_CHARDEV is not setCONFIG_I2C_HELPER_AUTO=yCONFIG_I2C_ALGOBIT=y
#
# I2C Hardware Bus support
#
#
# PC SMBus host controller drivers
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
#
# ACPI drivers
#
# CONFIG_I2C_SCMI is not set
#
# I2C system bus drivers (mostly embedded / system-on-chip) #
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
#
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_TINY_USB is not set
#
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_STUB is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_SPI is not set
#
# PPS support
#
# CONFIG_PPS is not setCONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not setCONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
# CONFIG_PDA_POWER is not set
# CONFIG_TEST_POWER is not set
# CONFIG_BATTERY_DS2760 is not set
# CONFIG_BATTERY_DS2782 is not set
# CONFIG_BATTERY_BQ27x00 is not set
# CONFIG_BATTERY_MAX17040 is not set
# CONFIG_HWMON is not setCONFIG_THERMAL=yCONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
#
# Watchdog Device Drivers
#CONFIG_SOFT_WATCHDOG=y
# CONFIG_ACQUIRE_WDT is not set
# CONFIG_ADVANTECH_WDT is not set
# CONFIG_ALIM1535_WDT is not set
# CONFIG_ALIM7101_WDT is not set
# CONFIG_SC520_WDT is not set
# CONFIG_SBC_FITPC2_WATCHDOG is not set
# CONFIG_EUROTECH_WDT is not set
# CONFIG_IB700_WDT is not set
# CONFIG_IBMASR is not set
# CONFIG_WAFER_WDT is not set
# CONFIG_I6300ESB_WDT is not set
# CONFIG_ITCO_WDT is not set
# CONFIG_IT8712F_WDT is not set
# CONFIG_IT87_WDT is not set
# CONFIG_HP_WATCHDOG is not set
# CONFIG_SC1200_WDT is not set
# CONFIG_PC87413_WDT is not set
# CONFIG_60XX_WDT is not set
# CONFIG_SBC8360_WDT is not set
# CONFIG_CPU5_WDT is not set
# CONFIG_SMSC_SCH311X_WDT is not set
# CONFIG_SMSC37B787_WDT is not set
# CONFIG_W83627HF_WDT is not set
# CONFIG_W83697HF_WDT is not set
# CONFIG_W83697UG_WDT is not set
# CONFIG_W83877F_WDT is not set
# CONFIG_W83977F_WDT is not set
# CONFIG_MACHZ_WDT is not set
# CONFIG_SBC_EPX_C3_WATCHDOG is not set
#
# PCI-based Watchdog Cards
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set
#
# USB-based Watchdog Cards
#
# CONFIG_USBPCWATCHDOG is not setCONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
# CONFIG_SSB is not setCONFIG_MFD_SUPPORT=y
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_88PM860X is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_TPS6507X is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TC35892 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_MAX8925 is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_WM8994 is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_ABX500_CORE is not set
# CONFIG_LPC_SCH is not set
# CONFIG_MFD_RDC321X is not set
# CONFIG_MFD_JANZ_CMODIO is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#CONFIG_AGP=yCONFIG_AGP_AMD64=yCONFIG_AGP_INTEL=yCONFIG_AGP_SIS=yCONFIG_AGP_VIA=yCONFIG_VGA_ARB=yCONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_VGA_SWITCHEROO is not setCONFIG_DRM=y
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
# CONFIG_DRM_RADEON is not set
# CONFIG_DRM_I810 is not set
# CONFIG_DRM_I830 is not set
# CONFIG_DRM_I915 is not set
# CONFIG_DRM_MGA is not set
# CONFIG_DRM_SIS is not set
# CONFIG_DRM_VIA is not set
# CONFIG_DRM_SAVAGE is not setCONFIG_VGASTATE=yCONFIG_VIDEO_OUTPUT_CONTROL=mCONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not setCONFIG_FB_BOOT_VESA_SUPPORT=yCONFIG_FB_CFB_FILLRECT=yCONFIG_FB_CFB_COPYAREA=yCONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
# CONFIG_FB_SYS_FILLRECT is not set
# CONFIG_FB_SYS_COPYAREA is not set
# CONFIG_FB_SYS_IMAGEBLIT is not set
# CONFIG_FB_FOREIGN_ENDIAN is not set
# CONFIG_FB_SYS_FOPS is not set
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not setCONFIG_FB_MODE_HELPERS=yCONFIG_FB_TILEBLITTING=y
#
# Frame buffer hardware drivers
#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ARC is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not setCONFIG_FB_VGA16=y
# CONFIG_FB_UVESA is not setCONFIG_FB_VESA=y
# CONFIG_FB_N411 is not set
# CONFIG_FB_HGA is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_LE80578 is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_VIA is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_ARK is not set
# CONFIG_FB_PM3 is not set
# CONFIG_FB_CARMINE is not set
# CONFIG_FB_GEODE is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not setCONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not setCONFIG_BACKLIGHT_CLASS_DEVICE=yCONFIG_BACKLIGHT_GENERIC=y
# CONFIG_BACKLIGHT_PROGEAR is not set
# CONFIG_BACKLIGHT_MBP_NVIDIA is not set
# CONFIG_BACKLIGHT_SAHARA is not set
# CONFIG_BACKLIGHT_ADP8860 is not set
#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
#
# Console display driver support
#CONFIG_VGA_CONSOLE=y CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64 CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=yCONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y
# CONFIG_SOUND is not set CONFIG_HID_SUPPORT=yCONFIG_HID=y
# CONFIG_HIDRAW is not set
#
# USB Input Devices
#CONFIG_USB_HID=yCONFIG_HID_PID=yCONFIG_USB_HIDDEV=y
#
# Special HID drivers
#
# CONFIG_HID_3M_PCT is not setCONFIG_HID_A4TECH=yCONFIG_HID_APPLE=yCONFIG_HID_BELKIN=y
# CONFIG_HID_CANDO is not setCONFIG_HID_CHERRY=yCONFIG_HID_CHICONY=yCONFIG_HID_CYPRESS=yCONFIG_HID_DRAGONRISE=y
# CONFIG_DRAGONRISE_FF is not set
# CONFIG_HID_EGALAX is not setCONFIG_HID_EZKEY=yCONFIG_HID_KYE=yCONFIG_HID_GYRATION=yCONFIG_HID_TWINHAN=yCONFIG_HID_KENSINGTON=yCONFIG_HID_LOGITECH=yCONFIG_LOGITECH_FF=y
# CONFIG_LOGIRUMBLEPAD2_FF is not set
# CONFIG_LOGIG940_FF is not setCONFIG_HID_MICROSOFT=y
# CONFIG_HID_MOSART is not setCONFIG_HID_MONTEREY=yCONFIG_HID_NTRIG=yCONFIG_HID_ORTEK=yCONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not setCONFIG_HID_PETALYNX=y
# CONFIG_HID_PICOLCD is not set
# CONFIG_HID_QUANTA is not set
# CONFIG_HID_ROCCAT is not set
# CONFIG_HID_ROCCAT_KONE is not setCONFIG_HID_SAMSUNG=yCONFIG_HID_SONY=y
# CONFIG_HID_STANTUM is not setCONFIG_HID_SUNPLUS=yCONFIG_HID_GREENASIA=y
# CONFIG_GREENASIA_FF is not setCONFIG_HID_SMARTJOYPLUS=y
# CONFIG_SMARTJOYPLUS_FF is not setCONFIG_HID_TOPSEED=yCONFIG_HID_THRUSTMASTER=yCONFIG_THRUSTMASTER_FF=yCONFIG_HID_ZEROPLUS=y
# CONFIG_ZEROPLUS_FF is not set
# CONFIG_HID_ZYDACRON is not setCONFIG_USB_SUPPORT=yCONFIG_USB_ARCH_HAS_HCD=yCONFIG_USB_ARCH_HAS_OHCI=yCONFIG_USB_ARCH_HAS_EHCI=yCONFIG_USB=y
# CONFIG_USB_DEBUG is not set
# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
#
# Miscellaneous USB options
#
# CONFIG_USB_DEVICEFS is not setCONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not setCONFIG_USB_MON=y
# CONFIG_USB_WUSB is not set
# CONFIG_USB_WUSB_CBAF is not set
#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_XHCI_HCD is not setCONFIG_USB_EHCI_HCD=yCONFIG_USB_EHCI_ROOT_HUB_TT=yCONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_ISP1362_HCD is not setCONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not setCONFIG_USB_OHCI_LITTLE_ENDIAN=yCONFIG_USB_UHCI_HCD=y
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_WHCI_HCD is not set
# CONFIG_USB_HWA_HCD is not set
#
# USB Device Class drivers
#
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
# CONFIG_USB_WDM is not set
# CONFIG_USB_TMC is not set
#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may #
#
# also be needed; see USB_STORAGE Help for more info # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set CONFIG_USB_STORAGE_DATAFAB=y CONFIG_USB_STORAGE_FREECOM=y CONFIG_USB_STORAGE_ISD200=y CONFIG_USB_STORAGE_USBAT=y CONFIG_USB_STORAGE_SDDR09=y CONFIG_USB_STORAGE_SDDR55=y CONFIG_USB_STORAGE_JUMPSHOT=y CONFIG_USB_STORAGE_ALAUDA=y # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set CONFIG_USB_LIBUSUAL=y
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
#
# USB port drivers
#
# CONFIG_USB_SERIAL is not set
#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_GADGET is not set
#
# OTG and related infrastructure
#
# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not setCONFIG_EDAC=y
#
# Reporting subsystems
#
# CONFIG_EDAC_DEBUG is not setCONFIG_EDAC_DECODE_MCE=yCONFIG_EDAC_MM_EDAC=y
# CONFIG_EDAC_AMD64 is not setCONFIG_EDAC_E752X=y
# CONFIG_EDAC_I82975X is not set
# CONFIG_EDAC_I3000 is not set
# CONFIG_EDAC_I3200 is not set
# CONFIG_EDAC_X38 is not set
# CONFIG_EDAC_I5400 is not set
# CONFIG_EDAC_I7CORE is not set
# CONFIG_EDAC_I5000 is not set
# CONFIG_EDAC_I5100 is not setCONFIG_RTC_LIB=yCONFIG_RTC_CLASS=yCONFIG_RTC_HCTOSYS=yCONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set
#
# RTC interfaces
#CONFIG_RTC_INTF_SYSFS=yCONFIG_RTC_INTF_PROC=yCONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
# CONFIG_RTC_DRV_TEST is not set
#
# I2C RTC drivers
#
# CONFIG_RTC_DRV_DS1307 is not set
# CONFIG_RTC_DRV_DS1374 is not set
# CONFIG_RTC_DRV_DS1672 is not set
# CONFIG_RTC_DRV_MAX6900 is not set
# CONFIG_RTC_DRV_RS5C372 is not set
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_BQ32K is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
# CONFIG_RTC_DRV_RX8025 is not set
#
# SPI RTC drivers
#
#
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_MSM6242 is not set
# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_RP5C01 is not set
# CONFIG_RTC_DRV_V3020 is not set
#
# on-CPU RTC drivers
#
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not setCONFIG_X86_PLATFORM_DEVICES=y
# CONFIG_ASUS_LAPTOP is not set
# CONFIG_DELL_LAPTOP is not set
# CONFIG_FUJITSU_LAPTOP is not set
# CONFIG_PANASONIC_LAPTOP is not set
# CONFIG_THINKPAD_ACPI is not set
# CONFIG_INTEL_MENLOW is not set
# CONFIG_EEEPC_LAPTOP is not set
# CONFIG_ACPI_WMI is not set
# CONFIG_ACPI_ASUS is not set
# CONFIG_TOPSTAR_LAPTOP is not set
# CONFIG_ACPI_TOSHIBA is not set
# CONFIG_TOSHIBA_BT_RFKILL is not set
# CONFIG_ACPI_CMPC is not set
#
# Firmware Drivers
#CONFIG_EDD=y
# CONFIG_EDD_OFF is not setCONFIG_FIRMWARE_MEMMAP=yCONFIG_DELL_RBU=yCONFIG_DCDBAS=yCONFIG_DMIID=y
# CONFIG_ISCSI_IBFT_FIND is not set
#
# File systems
#CONFIG_EXT2_FS=yCONFIG_EXT2_FS_XATTR=yCONFIG_EXT2_FS_POSIX_ACL=yCONFIG_EXT2_FS_SECURITY=yCONFIG_EXT2_FS_XIP=yCONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not setCONFIG_EXT3_FS_XATTR=yCONFIG_EXT3_FS_POSIX_ACL=yCONFIG_EXT3_FS_SECURITY=yCONFIG_EXT4_FS=yCONFIG_EXT4_FS_XATTR=yCONFIG_EXT4_FS_POSIX_ACL=y
# CONFIG_EXT4_FS_SECURITY is not set
# CONFIG_EXT4_DEBUG is not setCONFIG_FS_XIP=yCONFIG_JBD=y
# CONFIG_JBD_DEBUG is not setCONFIG_JBD2=y
# CONFIG_JBD2_DEBUG is not setCONFIG_FS_MBCACHE=yCONFIG_REISERFS_FS=y
# CONFIG_REISERFS_CHECK is not setCONFIG_REISERFS_PROC_INFO=yCONFIG_REISERFS_FS_XATTR=yCONFIG_REISERFS_FS_POSIX_ACL=yCONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not setCONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not setCONFIG_BTRFS_FS=yCONFIG_BTRFS_FS_POSIX_ACL=y
# CONFIG_NILFS2_FS is not setCONFIG_FILE_LOCKING=yCONFIG_FSNOTIFY=yCONFIG_DNOTIFY=yCONFIG_INOTIFY=yCONFIG_INOTIFY_USER=yCONFIG_QUOTA=y
# CONFIG_QUOTA_NETLINK_INTERFACE is not setCONFIG_PRINT_QUOTA_WARNING=y
# CONFIG_QUOTA_DEBUG is not setCONFIG_QUOTA_TREE=y
# CONFIG_QFMT_V1 is not setCONFIG_QFMT_V2=yCONFIG_QUOTACTL=yCONFIG_QUOTACTL_COMPAT=yCONFIG_AUTOFS_FS=yCONFIG_AUTOFS4_FS=yCONFIG_FUSE_FS=y
# CONFIG_CUSE is not set
#
# Caches
#
# CONFIG_FSCACHE is not set
#
# CD-ROM/DVD Filesystems
#CONFIG_ISO9660_FS=yCONFIG_JOLIET=yCONFIG_ZISOFS=yCONFIG_UDF_FS=yCONFIG_UDF_NLS=y
#
# DOS/FAT/NT Filesystems
#CONFIG_FAT_FS=yCONFIG_MSDOS_FS=yCONFIG_VFAT_FS=yCONFIG_FAT_DEFAULT_CODEPAGE=437CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#CONFIG_PROC_FS=yCONFIG_PROC_KCORE=yCONFIG_PROC_SYSCTL=yCONFIG_PROC_PAGE_MONITOR=yCONFIG_SYSFS=yCONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not setCONFIG_HUGETLBFS=yCONFIG_HUGETLB_PAGE=yCONFIG_CONFIGFS_FS=yCONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_LOGFS is not set
# CONFIG_CRAMFS is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not setCONFIG_ROMFS_FS=yCONFIG_ROMFS_BACKED_BY_BLOCK=y
# CONFIG_ROMFS_BACKED_BY_MTD is not set
# CONFIG_ROMFS_BACKED_BY_BOTH is not setCONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not setCONFIG_NETWORK_FILESYSTEMS=yCONFIG_NFS_FS=yCONFIG_NFS_V3=yCONFIG_NFS_V3_ACL=yCONFIG_NFS_V4=y
# CONFIG_NFS_V4_1 is not setCONFIG_NFSD=yCONFIG_NFSD_V2_ACL=yCONFIG_NFSD_V3=yCONFIG_NFSD_V3_ACL=yCONFIG_NFSD_V4=yCONFIG_LOCKD=yCONFIG_LOCKD_V4=yCONFIG_EXPORTFS=yCONFIG_NFS_ACL_SUPPORT=yCONFIG_NFS_COMMON=yCONFIG_SUNRPC=yCONFIG_SUNRPC_GSS=yCONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CEPH_FS is not setCONFIG_CIFS=y
# CONFIG_CIFS_STATS is not setCONFIG_CIFS_WEAK_PW_HASH=yCONFIG_CIFS_XATTR=yCONFIG_CIFS_POSIX=y
# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
#
# Partition Types
#CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not setCONFIG_OSF_PARTITION=yCONFIG_AMIGA_PARTITION=y
# CONFIG_ATARI_PARTITION is not setCONFIG_MAC_PARTITION=yCONFIG_MSDOS_PARTITION=yCONFIG_BSD_DISKLABEL=yCONFIG_MINIX_SUBPARTITION=yCONFIG_SOLARIS_X86_PARTITION=yCONFIG_UNIXWARE_DISKLABEL=y
# CONFIG_LDM_PARTITION is not setCONFIG_SGI_PARTITION=y
# CONFIG_ULTRIX_PARTITION is not setCONFIG_SUN_PARTITION=yCONFIG_KARMA_PARTITION=yCONFIG_EFI_PARTITION=y
# CONFIG_SYSV68_PARTITION is not setCONFIG_NLS=yCONFIG_NLS_DEFAULT="utf8"CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not setCONFIG_NLS_ASCII=yCONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not setCONFIG_NLS_UTF8=y
# CONFIG_DLM is not set
#
# Kernel hacking
#CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not setCONFIG_ENABLE_WARN_DEPRECATED=yCONFIG_ENABLE_MUST_CHECK=yCONFIG_FRAME_WARN=2048CONFIG_MAGIC_SYSRQ=y
# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not setCONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not setCONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not setCONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not setCONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0CONFIG_DETECT_HUNG_TASK=y
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not setCONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0CONFIG_SCHED_DEBUG=yCONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_LOCK_STAT is not setCONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not setCONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not setCONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_VIRTUAL is not set
# CONFIG_DEBUG_WRITECOUNT is not setCONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_DEBUG_CREDENTIALS is not setCONFIG_ARCH_WANT_FRAME_POINTERS=y
# CONFIG_FRAME_POINTER is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_LKDTM is not set
# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not setCONFIG_SYSCTL_SYSCALL_CHECK=y
# CONFIG_DEBUG_PAGEALLOC is not setCONFIG_USER_STACKTRACE_SUPPORT=yCONFIG_NOP_TRACER=yCONFIG_HAVE_FUNCTION_TRACER=yCONFIG_HAVE_FUNCTION_GRAPH_TRACER=yCONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=yCONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=yCONFIG_HAVE_DYNAMIC_FTRACE=yCONFIG_HAVE_FTRACE_MCOUNT_RECORD=yCONFIG_HAVE_SYSCALL_TRACEPOINTS=yCONFIG_RING_BUFFER=yCONFIG_EVENT_TRACING=yCONFIG_CONTEXT_SWITCH_TRACER=yCONFIG_RING_BUFFER_ALLOW_SWAP=yCONFIG_TRACING=yCONFIG_GENERIC_TRACER=yCONFIG_TRACING_SUPPORT=yCONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SYSPROF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_FTRACE_SYSCALLS is not set
# CONFIG_BOOT_TRACER is not setCONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_KSYM_TRACER is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not setCONFIG_BLK_DEV_IO_TRACE=yCONFIG_KPROBE_EVENT=y
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_MMIOTRACE is not set
# CONFIG_RING_BUFFER_BENCHMARK is not set
# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_DMA_API_DEBUG is not set
# CONFIG_ATOMIC64_SELFTEST is not set
# CONFIG_SAMPLES is not setCONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not setCONFIG_HAVE_ARCH_KMEMCHECK=y
# CONFIG_STRICT_DEVMEM is not setCONFIG_X86_VERBOSE_BOOTUP=yCONFIG_EARLY_PRINTK=y
# CONFIG_EARLY_PRINTK_DBGP is not setCONFIG_DEBUG_STACKOVERFLOW=yCONFIG_DEBUG_STACK_USAGE=y
# CONFIG_DEBUG_PER_CPU_MAPS is not set
# CONFIG_X86_PTDUMP is not setCONFIG_DEBUG_RODATA=y
# CONFIG_DEBUG_RODATA_TEST is not set
# CONFIG_DEBUG_NX_TEST is not set
# CONFIG_IOMMU_DEBUG is not set
# CONFIG_IOMMU_STRESS is not setCONFIG_HAVE_MMIOTRACE_SUPPORT=y
# CONFIG_X86_DECODER_SELFTEST is not setCONFIG_IO_DELAY_TYPE_0X80=0CONFIG_IO_DELAY_TYPE_0XED=1CONFIG_IO_DELAY_TYPE_UDELAY=2CONFIG_IO_DELAY_TYPE_NONE=3CONFIG_IO_DELAY_0X80=y
# CONFIG_IO_DELAY_0XED is not set
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not setCONFIG_DEFAULT_IO_DELAY_TYPE=0
# CONFIG_DEBUG_BOOT_PARAMS is not set
# CONFIG_CPA_DEBUG is not set
# CONFIG_OPTIMIZE_INLINING is not set
# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
#
# Security options
#
# CONFIG_KEYS is not setCONFIG_SECURITY=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_NETWORK is not set
# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_TOMOYO is not set
# CONFIG_IMA is not set
# CONFIG_DEFAULT_SECURITY_SELINUX is not set
# CONFIG_DEFAULT_SECURITY_SMACK is not set
# CONFIG_DEFAULT_SECURITY_TOMOYO is not setCONFIG_DEFAULT_SECURITY_DAC=yCONFIG_DEFAULT_SECURITY=""CONFIG_XOR_BLOCKS=yCONFIG_ASYNC_CORE=yCONFIG_ASYNC_MEMCPY=yCONFIG_ASYNC_XOR=yCONFIG_ASYNC_PQ=yCONFIG_ASYNC_RAID6_RECOV=yCONFIG_CRYPTO=y
#
# Crypto core or helper
#CONFIG_CRYPTO_ALGAPI=yCONFIG_CRYPTO_ALGAPI2=yCONFIG_CRYPTO_AEAD2=yCONFIG_CRYPTO_BLKCIPHER=yCONFIG_CRYPTO_BLKCIPHER2=yCONFIG_CRYPTO_HASH=yCONFIG_CRYPTO_HASH2=yCONFIG_CRYPTO_RNG2=yCONFIG_CRYPTO_PCOMP=yCONFIG_CRYPTO_MANAGER=yCONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_PCRYPT is not setCONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
# CONFIG_CRYPTO_SEQIV is not set
#
# Block modes
#CONFIG_CRYPTO_CBC=y
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
# CONFIG_CRYPTO_ECB is not set
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_PCBC is not set
# CONFIG_CRYPTO_XTS is not set
#
# Hash modes
#CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_CRC32C_INTEL is not set
# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not setCONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_RMD128 is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not setCONFIG_CRYPTO_SHA1=y
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set
#
# Ciphers
#
# CONFIG_CRYPTO_AES is not set
# CONFIG_CRYPTO_AES_X86_64 is not set
# CONFIG_CRYPTO_AES_NI_INTEL is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not setCONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_SALSA20_X86_64 is not set
# CONFIG_CRYPTO_SEED is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_TWOFISH_X86_64 is not set
#
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not setCONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_PADLOCK is not set
# CONFIG_CRYPTO_DEV_HIFN_795X is not setCONFIG_HAVE_KVM=yCONFIG_VIRTUALIZATION=y
# CONFIG_KVM is not set
# CONFIG_VHOST_NET is not set
# CONFIG_VIRTIO_PCI is not set
# CONFIG_VIRTIO_BALLOON is not setCONFIG_BINARY_PRINTF=y
#
# Library routines
#CONFIG_BITREVERSE=yCONFIG_GENERIC_FIND_FIRST_BIT=yCONFIG_GENERIC_FIND_NEXT_BIT=yCONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not setCONFIG_CRC16=y
# CONFIG_CRC_T10DIF is not setCONFIG_CRC_ITU_T=yCONFIG_CRC32=y
# CONFIG_CRC7 is not setCONFIG_LIBCRC32C=yCONFIG_ZLIB_INFLATE=yCONFIG_ZLIB_DEFLATE=yCONFIG_LZO_DECOMPRESS=yCONFIG_DECOMPRESS_GZIP=yCONFIG_DECOMPRESS_BZIP2=yCONFIG_DECOMPRESS_LZMA=yCONFIG_DECOMPRESS_LZO=yCONFIG_HAS_IOMEM=yCONFIG_HAS_IOPORT=yCONFIG_HAS_DMA=yCONFIG_NLATTR=y
Peter Zijlstra
maintainerQuoted 1 line · Yanmin
Quoted 1 line
Quoted 1 line
I applied it against 2.6.35-rc2 on
x86_64machine, but kernel booting panic.
<snip panic>
Quoted 4 lines
Quoted 2 lines
Oi, that's no good. Happen to have your .config handy, I didn't actually see my machine do that.
See the attachment.
That .config build and booted on my x86_64 machine, no funnies there.
I pushed a git tree out to kernel.org but somehow its refusing to show up on git.kernel.org..
Peter Zijlstra
maintainerQuoted 9 lines · Peter Zijlstra
Quoted 1 line · Yanmin
Quoted 1 line
Quoted 1 line
I applied it against 2.6.35-rc2 on
x86_64machine, but kernel booting panic.<snip panic>
Quoted 2 lines
Quoted 2 lines
Oi, that's no good. Happen to have your .config handy, I didn't actually see my machine do that.
Quoted 6 lines
Quoted 1 line
See the attachment.
That .config build and booted on my
x86_64machine, no funnies there.I pushed a git tree out to kernel.org but somehow its refusing to show up on git.kernel.org..
git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-mmu_preempt.git mmu_preempt
Quoted 10 lines · Peter Zijlstra
Quoted 9 lines · Peter Zijlstra
Quoted 1 line · Yanmin
Quoted 1 line
Quoted 1 line
I applied it against 2.6.35-rc2 on
x86_64machine, but kernel booting panic.<snip panic>
Quoted 2 lines
Quoted 2 lines
Oi, that's no good. Happen to have your .config handy, I didn't actually see my machine do that.
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
See the attachment.
That .config build and booted on my
x86_64machine, no funnies there.I pushed a git tree out to kernel.org but somehow its refusing to show up on git.kernel.org..
git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-mmu_preempt.gitmmu_preempt
We tested the tree on many machines with many benchmarks. Comparing with pure kernel 2.6.35-rc3, there is no clear performance regression/improvement. We didn't run into panic again.
Yanmin
Peter Zijlstra
maintainerQuoted 6 lines · Yanmin
Quoted 1 line · Peter Zijlstra
git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-mmu_preempt.gitmmu_preemptWe tested the tree on many machines with many benchmarks. Comparing with pure kernel 2.6.35-rc3, there is no clear performance regression/improvement. We didn't run into panic again.
Most awesome, thanks!