aboutsummaryrefslogtreecommitdiffstats
path: root/mm/highmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/highmem.c')
-rw-r--r--mm/highmem.c29
1 files changed, 4 insertions, 25 deletions
diff --git a/mm/highmem.c b/mm/highmem.c
index 2da13a5c50e2..d999077431df 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -99,7 +99,7 @@ struct page *kmap_to_page(void *vaddr)
99 unsigned long addr = (unsigned long)vaddr; 99 unsigned long addr = (unsigned long)vaddr;
100 100
101 if (addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP)) { 101 if (addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP)) {
102 int i = (addr - PKMAP_ADDR(0)) >> PAGE_SHIFT; 102 int i = PKMAP_NR(addr);
103 return pte_page(pkmap_page_table[i]); 103 return pte_page(pkmap_page_table[i]);
104 } 104 }
105 105
@@ -137,8 +137,7 @@ static void flush_all_zero_pkmaps(void)
137 * So no dangers, even with speculative execution. 137 * So no dangers, even with speculative execution.
138 */ 138 */
139 page = pte_page(pkmap_page_table[i]); 139 page = pte_page(pkmap_page_table[i]);
140 pte_clear(&init_mm, (unsigned long)page_address(page), 140 pte_clear(&init_mm, PKMAP_ADDR(i), &pkmap_page_table[i]);
141 &pkmap_page_table[i]);
142 141
143 set_page_address(page, NULL); 142 set_page_address(page, NULL);
144 need_flush = 1; 143 need_flush = 1;
@@ -324,11 +323,7 @@ struct page_address_map {
324 struct list_head list; 323 struct list_head list;
325}; 324};
326 325
327/* 326static struct page_address_map page_address_maps[LAST_PKMAP];
328 * page_address_map freelist, allocated from page_address_maps.
329 */
330static struct list_head page_address_pool; /* freelist */
331static spinlock_t pool_lock; /* protects page_address_pool */
332 327
333/* 328/*
334 * Hash table bucket 329 * Hash table bucket
@@ -393,14 +388,7 @@ void set_page_address(struct page *page, void *virtual)
393 388
394 pas = page_slot(page); 389 pas = page_slot(page);
395 if (virtual) { /* Add */ 390 if (virtual) { /* Add */
396 BUG_ON(list_empty(&page_address_pool)); 391 pam = &page_address_maps[PKMAP_NR((unsigned long)virtual)];
397
398 spin_lock_irqsave(&pool_lock, flags);
399 pam = list_entry(page_address_pool.next,
400 struct page_address_map, list);
401 list_del(&pam->list);
402 spin_unlock_irqrestore(&pool_lock, flags);
403
404 pam->page = page; 392 pam->page = page;
405 pam->virtual = virtual; 393 pam->virtual = virtual;
406 394
@@ -413,9 +401,6 @@ void set_page_address(struct page *page, void *virtual)
413 if (pam->page == page) { 401 if (pam->page == page) {
414 list_del(&pam->list); 402 list_del(&pam->list);
415 spin_unlock_irqrestore(&pas->lock, flags); 403 spin_unlock_irqrestore(&pas->lock, flags);
416 spin_lock_irqsave(&pool_lock, flags);
417 list_add_tail(&pam->list, &page_address_pool);
418 spin_unlock_irqrestore(&pool_lock, flags);
419 goto done; 404 goto done;
420 } 405 }
421 } 406 }
@@ -425,20 +410,14 @@ done:
425 return; 410 return;
426} 411}
427 412
428static struct page_address_map page_address_maps[LAST_PKMAP];
429
430void __init page_address_init(void) 413void __init page_address_init(void)
431{ 414{
432 int i; 415 int i;
433 416
434 INIT_LIST_HEAD(&page_address_pool);
435 for (i = 0; i < ARRAY_SIZE(page_address_maps); i++)
436 list_add(&page_address_maps[i].list, &page_address_pool);
437 for (i = 0; i < ARRAY_SIZE(page_address_htable); i++) { 417 for (i = 0; i < ARRAY_SIZE(page_address_htable); i++) {
438 INIT_LIST_HEAD(&page_address_htable[i].lh); 418 INIT_LIST_HEAD(&page_address_htable[i].lh);
439 spin_lock_init(&page_address_htable[i].lock); 419 spin_lock_init(&page_address_htable[i].lock);
440 } 420 }
441 spin_lock_init(&pool_lock);
442} 421}
443 422
444#endif /* defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) */ 423#endif /* defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) */