Re: [BUG,2.6.27] "fixpoint divide exception" while creating initramfs on Hercules

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

 



On Sun, 8 Mar 2009 19:35:53 +0100
Frans Pop <elendil@xxxxxxxxx> wrote:

> On Sunday 08 March 2009, Heiko Carstens wrote:
> > hmm.. (added Jonathan to cc list). So in theory this can only happen if
> > acct_timexp is greater than stime + utime of the task.
> > Just by looking at the code I would say that can't happen. ;)
> >
> > Could you try the patch below? Hopefully it gives us some more
> > hints about how much the values are screwed up.
> 
> stime: 2ee0 utime: 1f40 acct_timexpd: 4e20

Uh oh...

With the values from above the exception cannot happen since then we
would have a nice dtime of zero. That wouldn't give us an exception.

But still we have a negative dtime. So I think all this happen because
cpu time accounting happens completely unlocked from interrupt context
but acct_update_integrals gets also called from process context with
interrupts enabled.

So a possible explanation for this behaviour:

between reading tsk->stime/task->utime and tsk->acct_timexpd an
interrupt happens which updates accouting values. This causes
acct_timexpd to be greater than the former stime + utime and also
explains why the printk shows values which fit together.

I think the patch below should fix the bug:

---
 kernel/tsacct.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Index: linux-2.6.27.19/kernel/tsacct.c
===================================================================
--- linux-2.6.27.19.orig/kernel/tsacct.c
+++ linux-2.6.27.19/kernel/tsacct.c
@@ -120,8 +120,10 @@ void acct_update_integrals(struct task_s
 	if (likely(tsk->mm)) {
 		cputime_t time, dtime;
 		struct timeval value;
+		unsigned long flags;
 		u64 delta;
 
+		local_irq_save(flags);
 		time = tsk->stime + tsk->utime;
 		dtime = cputime_sub(time, tsk->acct_timexpd);
 		jiffies_to_timeval(cputime_to_jiffies(dtime), &value);
@@ -129,10 +131,12 @@ void acct_update_integrals(struct task_s
 		delta = delta * USEC_PER_SEC + value.tv_usec;
 
 		if (delta == 0)
-			return;
+			goto out;
 		tsk->acct_timexpd = time;
 		tsk->acct_rss_mem1 += delta * get_mm_rss(tsk->mm);
 		tsk->acct_vm_mem1 += delta * tsk->mm->total_vm;
+	out:
+		local_irq_restore(flags);
 	}
 }
 
--
To unsubscribe from this list: send the line "unsubscribe linux-s390" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Kernel Development]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Info]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Linux Media]     [Device Mapper]

  Powered by Linux