Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 673242c1 authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds
Browse files

[PATCH] x86-64: Make lockless machine check record passing a bit more robust.



One machine is constantly throwing NMI watchdog timeouts in mce_log

This was one attempt to fix it.

(AK: this doesn't actually fix the bug I'm seeing unfortunately, probably
drop.  I don't like it that the reader can spin forever now waiting
for a writer)

Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a54e678b
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ void mce_log(struct mce *mce)
	smp_wmb();
	for (;;) {
		entry = rcu_dereference(mcelog.next);
		for (;;) {
			/* When the buffer fills up discard new entries. Assume
			   that the earlier errors are the more interesting. */
			if (entry >= MCE_LOG_LEN) {
@@ -63,8 +64,11 @@ void mce_log(struct mce *mce)
				return;
			}
			/* Old left over entry. Skip. */
		if (mcelog.entry[entry].finished)
			if (mcelog.entry[entry].finished) {
				entry++;
				continue;
			}
		}
		smp_rmb();
		next = entry + 1;
		if (cmpxchg(&mcelog.next, entry, next) == entry)
@@ -405,8 +409,14 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff

	err = 0;
	for (i = 0; i < next; i++) {		
		if (!mcelog.entry[i].finished)
		unsigned long start = jiffies;
		while (!mcelog.entry[i].finished) {
			if (!time_before(jiffies, start + 2)) {
				memset(mcelog.entry + i,0, sizeof(struct mce));
				continue;
			}
			cpu_relax();
		}
		smp_rmb();
		err |= copy_to_user(buf, mcelog.entry + i, sizeof(struct mce));
		buf += sizeof(struct mce);