Re: [PATCH RFC] m68k: skip kernel premption if interrupts were disabled

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Finn,

thanks - that should suffice.

Tests on the slower ARAnyM instance also passed OK. Leaves test on 030 - I'll see whether I can find an earlier kernel version with a smaller memory footprint to test these patches on.

Now none of this has got us any closer to a solution for the spinlock recursion bug...

Cheers,

	Michael

Am 27.03.2024 um 16:50 schrieb Finn Thain:

On Wed, 27 Mar 2024, Michael Schmitz wrote:

it might be easier for Geert to merge the two patches (or a single one)
on top of his preempt branch if they come in the usual git format.

I suppose that would be easier, assuming it doesn't need a lot of rework.
Anyway, here's the diff.

diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index c1761d309fc6..d0092a3127c0 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -15,6 +15,7 @@
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/kernel.h>
+#include <linux/preempt.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/init.h>
@@ -139,10 +140,14 @@ void __init init_pointer_table(void *table, int type)

 void *get_pointer_table(int type)
 {
-	ptable_desc *dp = ptable_list[type].next;
-	unsigned int mask = list_empty(&ptable_list[type]) ? 0 : PD_MARKBITS(dp);
+	ptable_desc *dp;
+	unsigned int mask;
 	unsigned int tmp, off;

+	preempt_disable();
+
+	dp = ptable_list[type].next;
+	mask = list_empty(&ptable_list[type]) ? 0 : PD_MARKBITS(dp);
 	/*
 	 * For a pointer table for a user process address space, a
 	 * table is taken from a page allocated for the purpose.  Each
@@ -153,9 +158,13 @@ void *get_pointer_table(int type)
 		void *page;
 		ptable_desc *new;

+		sched_preempt_enable_no_resched();
+
 		if (!(page = (void *)get_zeroed_page(GFP_KERNEL)))
 			return NULL;

+		preempt_disable();
+
 		if (type == TABLE_PTE) {
 			/*
 			 * m68k doesn't have SPLIT_PTE_PTLOCKS for not having
@@ -170,6 +179,7 @@ void *get_pointer_table(int type)
 		PD_MARKBITS(new) = ptable_mask(type) - 1;
 		list_add_tail(new, dp);

+		sched_preempt_enable_no_resched();
 		return (pmd_t *)page;
 	}

@@ -180,6 +190,7 @@ void *get_pointer_table(int type)
 		/* move to end of list */
 		list_move_tail(dp, &ptable_list[type]);
 	}
+	sched_preempt_enable_no_resched();
 	return page_address(PD_PAGE(dp)) + off;
 }

@@ -190,6 +201,8 @@ int free_pointer_table(void *table, int type)
 	unsigned long page = ptable & PAGE_MASK;
 	unsigned int mask = 1U << ((ptable - page)/ptable_size(type));

+	preempt_disable();
+
 	dp = PD_PTABLE(page);
 	if (PD_MARKBITS (dp) & mask)
 		panic ("table already free!");
@@ -203,6 +216,7 @@ int free_pointer_table(void *table, int type)
 		if (type == TABLE_PTE)
 			pagetable_pte_dtor(virt_to_ptdesc((void *)page));
 		free_page (page);
+		sched_preempt_enable_no_resched();
 		return 1;
 	} else if (ptable_list[type].next != dp) {
 		/*
@@ -211,6 +225,7 @@ int free_pointer_table(void *table, int type)
 		 */
 		list_move(dp, &ptable_list[type]);
 	}
+	sched_preempt_enable_no_resched();
 	return 0;
 }






[Index of Archives]     [Video for Linux]     [Yosemite News]     [Linux S/390]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux