Skip to contentSkip to conversation

PPC: Don't sleep in flush_dcache_icache_page()

PATCH In review Roland Dreier 3 participants 3 messages Aug 16, 2005 – Aug 18, 2005

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 PPC: Don't sleep in flush_dcache_icache_page()

flush_dcache_icache_page() will be called on an instruction page fault. We can't sleep in the fault handler, so use kmap_atomic() instead of just kmap() for the Book-E case.

arch/ppc/mm/init.c +10 -2
@@ -560,8 +560,16 @@ void flush_dcache_page(struct page *page
 void flush_dcache_icache_page(struct page *page)
 {
 #ifdef CONFIG_BOOKE
-	__flush_dcache_icache(kmap(page));
-	kunmap(page);
+	unsigned long flags;
+	void *start;
+
+	local_irq_save(flags);
+
+	start = kmap_atomic(page, KM_PPC_SYNC_PAGE);
+	__flush_dcache_icache(start);
+	kunmap_atomic(start, KM_PPC_SYNC_PAGE);
+
+	local_irq_restore(flags);
 #elif CONFIG_8xx
 	/* On 8xx there is no need to kmap since highmem is not supported */
 	__flush_dcache_icache(page_address(page)); 
#1 lore raw

Hi Roland,

Quoted 5 lines · Roland Dreier

flush_dcache_icache_page() will be called on an instruction page fault. We can't sleep in the fault handler, so use kmap_atomic() instead of just kmap() for the Book-E case.

Why do you need to disable interrupts during the kmap_atomic/flush_dcache_icache operation ?

I fail to see how an interrupt could have any reference to the data being dealt with here (the user page).

Quoted 22 lines
arch/ppc/mm/init.c +10 -2
@@ -560,8 +560,16 @@ void flush_dcache_page(struct page *page
 void flush_dcache_icache_page(struct page *page)
 {
 #ifdef CONFIG_BOOKE
-	__flush_dcache_icache(kmap(page));
-	kunmap(page);
+	unsigned long flags;
+	void *start;
+
+	local_irq_save(flags);
+
+	start = kmap_atomic(page, KM_PPC_SYNC_PAGE);
+	__flush_dcache_icache(start);
+	kunmap_atomic(start, KM_PPC_SYNC_PAGE);
+
+	local_irq_restore(flags);
 #elif CONFIG_8xx
 	/* On 8xx there is no need to kmap since highmem is not supported */
 	__flush_dcache_icache(page_address(page)); 
#2 lore raw
Quoted 8 lines · Marcelo Tosatti

Hi Roland,

Quoted 4 lines · Roland Dreier

flush_dcache_icache_page() will be called on an instruction page fault. We can't sleep in the fault handler, so use kmap_atomic() instead of just kmap() for the Book-E case.

Quoted 7 lines
Quoted 1 line

Why do you need to disable interrupts during the kmap_atomic/flush_dcache_icache operation ?

I fail to see how an interrupt could have any reference to the data being dealt with here (the user page).

We just took care of this offline. The original patch is sharing a kmap slot with another kmap_atomic user I put in before...the sync page user. If an interrupt came in causing the DMA API to be used, we would have a problem.

The clean solution was to use a different kmap slot.

-Matt