From: David Mosberger <davidm@napali.hpl.hp.com>
To: linux-ia64@vger.kernel.org
Subject: Re: Fw: [Bugme-new] [Bug 2885] New: realtime process can't preempt low priority process in kernel
Date: Tue, 29 Jun 2004 18:42:47 +0000 [thread overview]
Message-ID: <16609.47143.757854.874764@napali.hpl.hp.com> (raw)
In-Reply-To: <20040614002931.00b846a4.akpm@osdl.org>
Peter,
Can you confirm that this patch also works for you? It's your patch with
the following changes:
o Consolidate code into a single #ifdef CONFIG_PREEMPT.
o Replace unconditional "cmp.eq.unc" with "cmp.eq".
o Cleanup/correct comment.
o Sync up code in ia64_leave_kernel with ia64_leave_syscall.
Rest should be the same.
Two questions though: first, the code will call notify_resume_user
when returning to kernel-level execution if preempt_count is 0 and
current_thread_info()->need_resched() is 0. Is this really what you
had in mind?
Second, isn't preempt_count necessarily 0 when returning to
user-level? If so, it should be possible to simplify the
CONFIG_PREEMPT code a bit more.
Thanks,
--david
>>>>> On Tue, 22 Jun 2004 09:57:43 +1000, Peter Chubb <peterc@gelato.unsw.edu.au> said:
Peter> Here's a patch to fix OSDL BugMe 2885: IA64 preemption
Peter> support.
Peter> There is one small change in semantics: when returning from a
Peter> preemption, the preemption flag will *not* be rechecked.
Peter> Otherwise, I found that it was easy to get into a livelock
Peter> situation where no forward progress was made.
---------------------------------------------------------------------------
ia64: Fix OSDL BugMe report 2885: realtime process can't preempt low priority process in kernel
Rearranged code to make it work. There were two problems:
1. The preempt flag was being tested only if code was leaving for
user space (the logic should be: test for RESCHEDULE if we're
switching to a kernel thread, test everything if switching to a
user thread)
2. The check of the user space flags was being repeated even if the
work had been done.
There is one small change in semantics: when returning from a
preemption, the preemption flag will *not* be rechecked. Otherwise, I
found that it was easy to get into a livelock situation where no
forward progress was made.
=== arch/ia64/kernel/entry.S 1.60 vs edited ==--- 1.60/arch/ia64/kernel/entry.S Wed Jun 16 21:12:18 2004
+++ edited/arch/ia64/kernel/entry.S Tue Jun 29 11:17:02 2004
@@ -663,25 +663,31 @@
PT_REGS_UNWIND_INFO(0)
/*
* work.need_resched etc. mustn't get changed by this CPU before it returns to
- * user- or fsys-mode, hence we disable interrupts early on:
+ * user- or fsys-mode, hence we disable interrupts early on.
+ *
+ * p6 controls whether current_thread_info()->flags needs to be check for
+ * extra work. We always check for extra work when returning to user-level.
+ * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
+ * is 0. After extra work processing has been completed, execution
+ * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
+ * needs to be redone.
*/
#ifdef CONFIG_PREEMPT
rsm psr.i // disable interrupts
-#else
-(pUStk) rsm psr.i
-#endif
cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall
-(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
-.work_processed_syscall:
-#ifdef CONFIG_PREEMPT
(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
;;
.pred.rel.mutex pUStk,pKStk
(pKStk) ld4 r21=[r20] // r21 <- preempt_count
(pUStk) mov r21=0 // r21 <- 0
;;
-(p6) cmp.eq.unc p6,p0=r21,r0 // p6 <- p6 && (r21 = 0)
-#endif /* CONFIG_PREEMPT */
+ cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count = 0)
+#else /* !CONFIG_PREEMPT */
+(pUStk) rsm psr.i
+ cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall
+(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
+#endif
+.work_processed_syscall:
adds r16=PT(LOADRS)+16,r12
adds r17=PT(AR_BSPSTORE)+16,r12
adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
@@ -776,26 +782,31 @@
PT_REGS_UNWIND_INFO(0)
/*
* work.need_resched etc. mustn't get changed by this CPU before it returns to
- * user- or fsys-mode, hence we disable interrupts early on:
+ * user- or fsys-mode, hence we disable interrupts early on.
+ *
+ * p6 controls whether current_thread_info()->flags needs to be check for
+ * extra work. We always check for extra work when returning to user-level.
+ * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
+ * is 0. After extra work processing has been completed, execution
+ * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
+ * needs to be redone.
*/
#ifdef CONFIG_PREEMPT
rsm psr.i // disable interrupts
-#else
-(pUStk) rsm psr.i
-#endif
cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel
-(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
- ;;
-.work_processed_kernel:
-#ifdef CONFIG_PREEMPT
- adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
+(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
;;
.pred.rel.mutex pUStk,pKStk
(pKStk) ld4 r21=[r20] // r21 <- preempt_count
(pUStk) mov r21=0 // r21 <- 0
;;
-(p6) cmp.eq.unc p6,p0=r21,r0 // p6 <- p6 && (r21 = 0)
-#endif /* CONFIG_PREEMPT */
+ cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count = 0)
+#else
+(pUStk) rsm psr.i
+ cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel
+(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
+#endif
+.work_processed_kernel:
adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
;;
(p6) ld4 r31=[r17] // load current_thread_info()->flags
prev parent reply other threads:[~2004-06-29 18:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-06-14 7:29 Fw: [Bugme-new] [Bug 2885] New: realtime process can't preempt low Andrew Morton
2004-06-21 23:57 ` Fw: [Bugme-new] [Bug 2885] New: realtime process can't preempt low priority process in kernel Peter Chubb
2004-06-24 1:48 ` Zhu, Yi
2004-06-29 18:42 ` David Mosberger [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=16609.47143.757854.874764@napali.hpl.hp.com \
--to=davidm@napali.hpl.hp.com \
--cc=linux-ia64@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox