code: plan9front

Download patch

ref: 044d3e74eb7be6c3c9bb9b7a39d04c731467d109
parent: 858893ff8ff8d3abd06742276bcb794f3422bab8
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Dec 22 13:28:25 EST 2023

kernel: add pc field in QLock for debugging

Maintain a QLock.pc and RWLock.wpc field which is
the callerpc() of the last owner of the qlock/wlock.

The previous patch that set QLock.use.pc was
kind of nonsensical as it will get overridden
by the next attempt to acquire the qlock.

--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -78,6 +78,7 @@
 	Lock	use;		/* to access Qlock structure */
 	Proc	*head;		/* next process waiting for object */
 	Proc	*tail;		/* last process waiting for object */
+	uintptr	pc;		/* pc of owner */
 	int	locked;		/* flag */
 };
 
@@ -93,9 +94,8 @@
 	Proc	*head;		/* list of waiting processes */
 	Proc	*tail;
 	uintptr	wpc;		/* pc of writer */
-	Proc	*wproc;		/* writing proc */
-	int	readers;	/* number of readers */
 	int	writer;		/* number of writers */
+	int	readers;	/* number of readers */
 };
 
 struct Alarms
--- a/sys/src/9/port/qlock.c
+++ b/sys/src/9/port/qlock.c
@@ -19,19 +19,23 @@
 eqlock(QLock *q)
 {
 	Proc *p;
+	uintptr pc;
 
+	pc = getcallerpc(&q);
+
 	if(m->ilockdepth != 0)
-		print("eqlock: %#p: ilockdepth %d\n", getcallerpc(&q), m->ilockdepth);
+		print("eqlock: %#p: ilockdepth %d\n", pc, m->ilockdepth);
 	if(up != nil && up->nlocks)
-		print("eqlock: %#p: nlocks %d\n", getcallerpc(&q), up->nlocks);
+		print("eqlock: %#p: nlocks %d\n", pc, up->nlocks);
 	if(up != nil && up->eql != nil)
-		print("eqlock: %#p: eql %p\n", getcallerpc(&q), up->eql);
+		print("eqlock: %#p: eql %p\n", pc, up->eql);
 	if(q->use.key == 0x55555555)
-		panic("eqlock: q %#p, key 5*", q);
+		panic("eqlock: %#p: q %#p, key 5*", pc, q);
 
 	lock(&q->use);
 	rwstats.qlock++;
 	if(!q->locked) {
+		q->pc = pc;
 		q->locked = 1;
 		unlock(&q->use);
 		return;
@@ -52,7 +56,7 @@
 	q->tail = up;
 	up->eql = q;
 	up->qnext = nil;
-	up->qpc = getcallerpc(&q);
+	up->qpc = pc;
 	up->state = Queueing;
 	unlock(&q->use);
 	sched();
@@ -67,19 +71,22 @@
 qlock(QLock *q)
 {
 	Proc *p;
+	uintptr pc;
 
+	pc = getcallerpc(&q);
+
 	if(m->ilockdepth != 0)
-		print("qlock: %#p: ilockdepth %d\n", getcallerpc(&q), m->ilockdepth);
+		print("qlock: %#p: ilockdepth %d\n", pc, m->ilockdepth);
 	if(up != nil && up->nlocks)
-		print("qlock: %#p: nlocks %d\n", getcallerpc(&q), up->nlocks);
+		print("qlock: %#p: nlocks %d\n", pc, up->nlocks);
 	if(up != nil && up->eql != nil)
-		print("qlock: %#p: eql %p\n", getcallerpc(&q), up->eql);
+		print("qlock: %#p: eql %p\n", pc, up->eql);
 	if(q->use.key == 0x55555555)
-		panic("qlock: q %#p, key 5*", q);
+		panic("qlock: %#p: q %#p, key 5*", pc, q);
 	lock(&q->use);
 	rwstats.qlock++;
 	if(!q->locked) {
-		q->use.pc = getcallerpc(&q);
+		q->pc = pc;
 		q->locked = 1;
 		unlock(&q->use);
 		return;
@@ -95,8 +102,8 @@
 	q->tail = up;
 	up->eql = nil;
 	up->qnext = nil;
+	up->qpc = pc;
 	up->state = Queueing;
-	up->qpc = getcallerpc(&q);
 	unlock(&q->use);
 	sched();
 }
@@ -111,6 +118,7 @@
 		return 0;
 	}
 	q->locked = 1;
+	q->pc = getcallerpc(&q);
 	unlock(&q->use);
 	return 1;
 }
@@ -126,6 +134,7 @@
 			getcallerpc(&q));
 	p = q->head;
 	if(p != nil){
+		q->pc = p->qpc;
 		q->head = p->qnext;
 		if(q->head == nil)
 			q->tail = nil;
@@ -184,6 +193,7 @@
 	q->head = p->qnext;
 	if(q->head == nil)
 		q->tail = nil;
+	q->wpc = p->qpc;
 	q->writer = 1;
 	unlock(&q->use);
 	ready(p);
@@ -193,13 +203,15 @@
 wlock(RWlock *q)
 {
 	Proc *p;
+	uintptr pc;
 
+	pc = getcallerpc(&q);
+
 	lock(&q->use);
 	rwstats.wlock++;
 	if(q->readers == 0 && q->writer == 0){
 		/* noone waiting, go for it */
-		q->wpc = getcallerpc(&q);
-		q->wproc = up;
+		q->wpc = pc;
 		q->writer = 1;
 		unlock(&q->use);
 		return;
@@ -216,6 +228,7 @@
 		p->qnext = up;
 	q->tail = up;
 	up->qnext = nil;
+	up->qpc = pc;
 	up->state = QueueingW;
 	unlock(&q->use);
 	sched();
@@ -235,6 +248,7 @@
 	}
 	if(p->state == QueueingW){
 		/* start waiting writer */
+		q->wpc = p->qpc;
 		q->head = p->qnext;
 		if(q->head == nil)
 			q->tail = nil;