aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLi Zhong <zhong@linux.vnet.ibm.com>2013-04-15 12:53:20 -0400
committerMichael Ellerman <michael@ellerman.id.au>2013-04-18 02:00:00 -0400
commit016af59f0f8cd10f27773df8f0034b5f3b46a138 (patch)
treed381f144bdb6d09a7f2bf6cfb8a8feb7082be1db
parentb170bd3de6a7f6fbfba331e300751450f55d8822 (diff)
powerpc: Try to insert the hptes repeatedly in kernel_map_linear_page()
This patch fixes the following oops, which could be trigged by build the kernel with many concurrent threads, under CONFIG_DEBUG_PAGEALLOC. hpte_insert() might return -1, indicating that the bucket (primary here) is full. We are not necessarily reporting a BUG in this case. Instead, we could try repeatedly (try secondary, remove and try again) until we find a slot. [ 543.075675] ------------[ cut here ]------------ [ 543.075701] kernel BUG at arch/powerpc/mm/hash_utils_64.c:1239! [ 543.075714] Oops: Exception in kernel mode, sig: 5 [#1] [ 543.075722] PREEMPT SMP NR_CPUS=16 DEBUG_PAGEALLOC NUMA pSeries [ 543.075741] Modules linked in: binfmt_misc ehea [ 543.075759] NIP: c000000000036eb0 LR: c000000000036ea4 CTR: c00000000005a594 [ 543.075771] REGS: c0000000a90832c0 TRAP: 0700 Not tainted (3.8.0-next-20130222) [ 543.075781] MSR: 8000000000029032 <SF,EE,ME,IR,DR,RI> CR: 22224482 XER: 00000000 [ 543.075816] SOFTE: 0 [ 543.075823] CFAR: c00000000004c200 [ 543.075830] TASK = c0000000e506b750[23934] 'cc1' THREAD: c0000000a9080000 CPU: 1 GPR00: 0000000000000001 c0000000a9083540 c000000000c600a8 ffffffffffffffff GPR04: 0000000000000050 fffffffffffffffa c0000000a90834e0 00000000004ff594 GPR08: 0000000000000001 0000000000000000 000000009592d4d8 c000000000c86854 GPR12: 0000000000000002 c000000006ead300 0000000000a51000 0000000000000001 GPR16: f000000003354380 ffffffffffffffff ffffffffffffff80 0000000000000000 GPR20: 0000000000000001 c000000000c600a8 0000000000000001 0000000000000001 GPR24: 0000000003354380 c000000000000000 0000000000000000 c000000000b65950 GPR28: 0000002000000000 00000000000cd50e 0000000000bf50d9 c000000000c7c230 [ 543.076005] NIP [c000000000036eb0] .kernel_map_pages+0x1e0/0x3f8 [ 543.076016] LR [c000000000036ea4] .kernel_map_pages+0x1d4/0x3f8 [ 543.076025] Call Trace: [ 543.076033] [c0000000a9083540] [c000000000036ea4] .kernel_map_pages+0x1d4/0x3f8 (unreliable) [ 543.076053] [c0000000a9083640] [c000000000167638] .get_page_from_freelist+0x6cc/0x8dc [ 543.076067] [c0000000a9083800] [c000000000167a48] .__alloc_pages_nodemask+0x200/0x96c [ 543.076082] [c0000000a90839c0] [c0000000001ade44] .alloc_pages_vma+0x160/0x1e4 [ 543.076098] [c0000000a9083a80] [c00000000018ce04] .handle_pte_fault+0x1b0/0x7e8 [ 543.076113] [c0000000a9083b50] [c00000000018d5a8] .handle_mm_fault+0x16c/0x1a0 [ 543.076129] [c0000000a9083c00] [c0000000007bf1dc] .do_page_fault+0x4d0/0x7a4 [ 543.076144] [c0000000a9083e30] [c0000000000090e8] handle_page_fault+0x10/0x30 [ 543.076155] Instruction dump: [ 543.076163] 7c630038 78631d88 e80a0000 f8410028 7c0903a6 e91f01de e96a0010 e84a0008 [ 543.076192] 4e800421 e8410028 7c7107b4 7a200fe0 <0b000000> 7f63db78 48785781 60000000 [ 543.076224] ---[ end trace bd5807e8d6ae186b ]--- Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
-rw-r--r--arch/powerpc/mm/hash_utils_64.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index ead9fa84ffd9..1ed4419c533b 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -1268,21 +1268,22 @@ repeat:
1268#ifdef CONFIG_DEBUG_PAGEALLOC 1268#ifdef CONFIG_DEBUG_PAGEALLOC
1269static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) 1269static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi)
1270{ 1270{
1271 unsigned long hash, hpteg; 1271 unsigned long hash;
1272 unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize); 1272 unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize);
1273 unsigned long vpn = hpt_vpn(vaddr, vsid, mmu_kernel_ssize); 1273 unsigned long vpn = hpt_vpn(vaddr, vsid, mmu_kernel_ssize);
1274 unsigned long mode = htab_convert_pte_flags(PAGE_KERNEL); 1274 unsigned long mode = htab_convert_pte_flags(PAGE_KERNEL);
1275 int ret; 1275 long ret;
1276 1276
1277 hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize); 1277 hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize);
1278 hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
1279 1278
1280 /* Don't create HPTE entries for bad address */ 1279 /* Don't create HPTE entries for bad address */
1281 if (!vsid) 1280 if (!vsid)
1282 return; 1281 return;
1283 ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr), 1282
1284 mode, HPTE_V_BOLTED, 1283 ret = hpte_insert_repeating(hash, vpn, __pa(vaddr), mode,
1285 mmu_linear_psize, mmu_kernel_ssize); 1284 HPTE_V_BOLTED,
1285 mmu_linear_psize, mmu_kernel_ssize);
1286
1286 BUG_ON (ret < 0); 1287 BUG_ON (ret < 0);
1287 spin_lock(&linear_map_hash_lock); 1288 spin_lock(&linear_map_hash_lock);
1288 BUG_ON(linear_map_hash_slots[lmi] & 0x80); 1289 BUG_ON(linear_map_hash_slots[lmi] & 0x80);