Allow filtering by PID for "db sem"
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 23 Feb 2017 16:21:47 +0000 (11:21 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 2 Mar 2017 18:01:28 +0000 (13:01 -0500)
The PID argument to "db sem" is optional.  Without it, it shows all
semaphores.  With it, it will only show sems with kthreads of a particular
process.  Use PID == 0 for "no process" (e.g., ktasks).

bash-4.3$ m db sem 272
All sems with waiters:
Semaphore 0xffff8000096db630 has -1 signals (neg = waiters)
        Kthread 0xffff800007dfd620 (open /net/tcp/0/listen at fd -100),
            proc 272, sysc 0x00007f7fff9fe840,
            pc/frame 0xffffffffc201948a 0xfffffff000017ad8

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/kthread.h
kern/src/kthread.c
kern/src/monitor.c

index ed0e43d..21d43dd 100644 (file)
@@ -121,8 +121,7 @@ bool sem_up(struct semaphore *sem);
 bool sem_trydown_irqsave(struct semaphore *sem, int8_t *irq_state);
 void sem_down_irqsave(struct semaphore *sem, int8_t *irq_state);
 bool sem_up_irqsave(struct semaphore *sem, int8_t *irq_state);
-void print_sem_info(struct semaphore *sem);
-void print_all_sem_info(void);
+void print_all_sem_info(pid_t pid);
 
 void cv_init(struct cond_var *cv);
 void cv_init_irqsave(struct cond_var *cv);
index 59db13c..908a40f 100644 (file)
@@ -593,11 +593,34 @@ static void debug_upped_sem(struct semaphore *sem)
 
 #endif /* CONFIG_SEMAPHORE_DEBUG */
 
-void print_sem_info(struct semaphore *sem)
+static bool __sem_has_pid(struct semaphore *sem, pid_t pid)
 {
        struct kthread *kth_i;
+
+       if (pid == -1)
+               return TRUE;
+       TAILQ_FOREACH(kth_i, &sem->waiters, link) {
+               if (kth_i->proc) {
+                       if (kth_i->proc->pid == pid)
+                               return TRUE;
+               } else {
+                       if (pid == 0)
+                               return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+static void print_sem_info(struct semaphore *sem, pid_t pid)
+{
+       struct kthread *kth_i;
+
        /* Always safe to irqsave */
        spin_lock_irqsave(&sem->lock);
+       if (!__sem_has_pid(sem, pid)) {
+               spin_unlock_irqsave(&sem->lock);
+               return;
+       }
        printk("Semaphore %p has %d signals (neg = waiters)\n", sem,
               sem->nr_signals);
        TAILQ_FOREACH(kth_i, &sem->waiters, link)
@@ -609,14 +632,14 @@ void print_sem_info(struct semaphore *sem)
        spin_unlock_irqsave(&sem->lock);
 }
 
-void print_all_sem_info(void)
+void print_all_sem_info(pid_t pid)
 {
 #ifdef CONFIG_SEMAPHORE_DEBUG
        struct semaphore *sem_i;
        printk("All sems with waiters:\n");
        spin_lock_irqsave(&sems_with_waiters_lock);
        TAILQ_FOREACH(sem_i, &sems_with_waiters, link)
-               print_sem_info(sem_i);
+               print_sem_info(sem_i, pid);
        spin_unlock_irqsave(&sems_with_waiters_lock);
 #else
        printk("Failed to print all sems: build with CONFIG_SEMAPHORE_DEBUG\n");
index fb9736b..b86207a 100644 (file)
@@ -1134,14 +1134,18 @@ int mon_msr(int argc, char **argv, struct hw_trapframe *hw_tf)
 
 int mon_db(int argc, char **argv, struct hw_trapframe *hw_tf)
 {
+       pid_t pid = -1;
+
        if (argc < 2) {
                printk("Usage: db OPTION\n");
-               printk("\tsem: print all semaphore info\n");
-               printk("\taddr: for PID lookup ADDR's file/vmr info\n");
+               printk("\tsem [PID]: print all semaphore info\n");
+               printk("\taddr PID 0xADDR: for PID lookup ADDR's file/vmr info\n");
                return 1;
        }
        if (!strcmp(argv[1], "sem")) {
-               print_all_sem_info();
+               if (argc > 2)
+                       pid = strtol(argv[2], 0, 0);
+               print_all_sem_info(pid);
        } else if (!strcmp(argv[1], "addr")) {
                if (argc < 4) {
                        printk("Usage: db addr PID 0xADDR\n");