]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sunrpc/sched.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/joern/misc
[linux-2.6-omap-h63xx.git] / net / sunrpc / sched.c
index eff44bcdc95a2570e8ee9eb71117c225b78dfb84..6d87320074b1556f98280dde419157f6288a2cb7 100644 (file)
@@ -4,7 +4,7 @@
  * Scheduling for synchronous and asynchronous RPC requests.
  *
  * Copyright (C) 1996 Olaf Kirch, <okir@monad.swb.de>
- * 
+ *
  * TCP NFS related read + write fixes
  * (C) 1999 Dave Airlie, University of Limerick, Ireland <airlied@linux.ie>
  */
@@ -34,14 +34,15 @@ static int                  rpc_task_id;
 #define RPC_BUFFER_MAXSIZE     (2048)
 #define RPC_BUFFER_POOLSIZE    (8)
 #define RPC_TASK_POOLSIZE      (8)
-static kmem_cache_t    *rpc_task_slabp __read_mostly;
-static kmem_cache_t    *rpc_buffer_slabp __read_mostly;
+static struct kmem_cache       *rpc_task_slabp __read_mostly;
+static struct kmem_cache       *rpc_buffer_slabp __read_mostly;
 static mempool_t       *rpc_task_mempool __read_mostly;
 static mempool_t       *rpc_buffer_mempool __read_mostly;
 
 static void                    __rpc_default_timer(struct rpc_task *task);
 static void                    rpciod_killall(void);
 static void                    rpc_async_schedule(struct work_struct *);
+static void                     rpc_release_task(struct rpc_task *task);
 
 /*
  * RPC tasks sit here while waiting for conditions to improve.
@@ -73,7 +74,7 @@ static DEFINE_SPINLOCK(rpc_sched_lock);
 static inline void
 __rpc_disable_timer(struct rpc_task *task)
 {
-       dprintk("RPC: %4d disabling timer\n", task->tk_pid);
+       dprintk("RPC: %5u disabling timer\n", task->tk_pid);
        task->tk_timeout_fn = NULL;
        task->tk_timeout = 0;
 }
@@ -92,7 +93,7 @@ static void rpc_run_timer(struct rpc_task *task)
        callback = task->tk_timeout_fn;
        task->tk_timeout_fn = NULL;
        if (callback && RPC_IS_QUEUED(task)) {
-               dprintk("RPC: %4d running timer\n", task->tk_pid);
+               dprintk("RPC: %5u running timer\n", task->tk_pid);
                callback(task);
        }
        smp_mb__before_clear_bit();
@@ -109,7 +110,7 @@ __rpc_add_timer(struct rpc_task *task, rpc_action timer)
        if (!task->tk_timeout)
                return;
 
-       dprintk("RPC: %4d setting alarm for %lu ms\n",
+       dprintk("RPC: %5u setting alarm for %lu ms\n",
                        task->tk_pid, task->tk_timeout * 1000 / HZ);
 
        if (timer)
@@ -131,7 +132,7 @@ rpc_delete_timer(struct rpc_task *task)
                return;
        if (test_and_clear_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate)) {
                del_singleshot_timer_sync(&task->tk_timer);
-               dprintk("RPC: %4d deleting timer\n", task->tk_pid);
+               dprintk("RPC: %5u deleting timer\n", task->tk_pid);
        }
 }
 
@@ -178,8 +179,8 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue, struct rpc_task *
        queue->qlen++;
        rpc_set_queued(task);
 
-       dprintk("RPC: %4d added to queue %p \"%s\"\n",
-                               task->tk_pid, queue, rpc_qname(queue));
+       dprintk("RPC: %5u added to queue %p \"%s\"\n",
+                       task->tk_pid, queue, rpc_qname(queue));
 }
 
 /*
@@ -211,8 +212,8 @@ static void __rpc_remove_wait_queue(struct rpc_task *task)
        else
                list_del(&task->u.tk_wait.list);
        queue->qlen--;
-       dprintk("RPC: %4d removed from queue %p \"%s\"\n",
-                               task->tk_pid, queue, rpc_qname(queue));
+       dprintk("RPC: %5u removed from queue %p \"%s\"\n",
+                       task->tk_pid, queue, rpc_qname(queue));
 }
 
 static inline void rpc_set_waitqueue_priority(struct rpc_wait_queue *queue, int priority)
@@ -266,12 +267,28 @@ static int rpc_wait_bit_interruptible(void *word)
        return 0;
 }
 
+static void rpc_set_active(struct rpc_task *task)
+{
+       if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0)
+               return;
+       spin_lock(&rpc_sched_lock);
+#ifdef RPC_DEBUG
+       task->tk_magic = RPC_TASK_MAGIC_ID;
+       task->tk_pid = rpc_task_id++;
+#endif
+       /* Add to global list of all tasks */
+       list_add_tail(&task->tk_task, &all_tasks);
+       spin_unlock(&rpc_sched_lock);
+}
+
 /*
  * Mark an RPC call as having completed by clearing the 'active' bit
  */
-static inline void rpc_mark_complete_task(struct rpc_task *task)
+static void rpc_mark_complete_task(struct rpc_task *task)
 {
-       rpc_clear_active(task);
+       smp_mb__before_clear_bit();
+       clear_bit(RPC_TASK_ACTIVE, &task->tk_runstate);
+       smp_mb__after_clear_bit();
        wake_up_bit(&task->tk_runstate, RPC_TASK_ACTIVE);
 }
 
@@ -290,18 +307,20 @@ EXPORT_SYMBOL(__rpc_wait_for_completion_task);
 /*
  * Make an RPC task runnable.
  *
- * Note: If the task is ASYNC, this must be called with 
+ * Note: If the task is ASYNC, this must be called with
  * the spinlock held to protect the wait queue operation.
  */
 static void rpc_make_runnable(struct rpc_task *task)
 {
-       int do_ret;
-
        BUG_ON(task->tk_timeout_fn);
-       do_ret = rpc_test_and_set_running(task);
        rpc_clear_queued(task);
-       if (do_ret)
+       if (rpc_test_and_set_running(task))
+               return;
+       /* We might have raced */
+       if (RPC_IS_QUEUED(task)) {
+               rpc_clear_running(task);
                return;
+       }
        if (RPC_IS_ASYNC(task)) {
                int status;
 
@@ -325,17 +344,14 @@ static void rpc_make_runnable(struct rpc_task *task)
 static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
                        rpc_action action, rpc_action timer)
 {
-       dprintk("RPC: %4d sleep_on(queue \"%s\" time %ld)\n", task->tk_pid,
-                               rpc_qname(q), jiffies);
+       dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n",
+                       task->tk_pid, rpc_qname(q), jiffies);
 
        if (!RPC_IS_ASYNC(task) && !RPC_IS_ACTIVATED(task)) {
                printk(KERN_ERR "RPC: Inactive synchronous task put to sleep!\n");
                return;
        }
 
-       /* Mark the task as being activated if so needed */
-       rpc_set_active(task);
-
        __rpc_add_wait_queue(q, task);
 
        BUG_ON(task->tk_callback != NULL);
@@ -346,6 +362,9 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
 void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
                                rpc_action action, rpc_action timer)
 {
+       /* Mark the task as being activated if so needed */
+       rpc_set_active(task);
+
        /*
         * Protect the queue operations.
         */
@@ -362,7 +381,8 @@ void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
  */
 static void __rpc_do_wake_up_task(struct rpc_task *task)
 {
-       dprintk("RPC: %4d __rpc_wake_up_task (now %ld)\n", task->tk_pid, jiffies);
+       dprintk("RPC: %5u __rpc_wake_up_task (now %lu)\n",
+                       task->tk_pid, jiffies);
 
 #ifdef RPC_DEBUG
        BUG_ON(task->tk_magic != RPC_TASK_MAGIC_ID);
@@ -378,7 +398,7 @@ static void __rpc_do_wake_up_task(struct rpc_task *task)
 
        rpc_make_runnable(task);
 
-       dprintk("RPC:      __rpc_wake_up_task done\n");
+       dprintk("RPC:       __rpc_wake_up_task done\n");
 }
 
 /*
@@ -399,7 +419,7 @@ static void __rpc_wake_up_task(struct rpc_task *task)
 static void
 __rpc_default_timer(struct rpc_task *task)
 {
-       dprintk("RPC: %d timeout (default timer)\n", task->tk_pid);
+       dprintk("RPC: %5u timeout (default timer)\n", task->tk_pid);
        task->tk_status = -ETIMEDOUT;
        rpc_wake_up_task(task);
 }
@@ -409,16 +429,19 @@ __rpc_default_timer(struct rpc_task *task)
  */
 void rpc_wake_up_task(struct rpc_task *task)
 {
+       rcu_read_lock_bh();
        if (rpc_start_wakeup(task)) {
                if (RPC_IS_QUEUED(task)) {
                        struct rpc_wait_queue *queue = task->u.tk_wait.rpc_waitq;
 
-                       spin_lock_bh(&queue->lock);
+                       /* Note: we're already in a bh-safe context */
+                       spin_lock(&queue->lock);
                        __rpc_do_wake_up_task(task);
-                       spin_unlock_bh(&queue->lock);
+                       spin_unlock(&queue->lock);
                }
                rpc_finish_wakeup(task);
        }
+       rcu_read_unlock_bh();
 }
 
 /*
@@ -480,15 +503,18 @@ struct rpc_task * rpc_wake_up_next(struct rpc_wait_queue *queue)
 {
        struct rpc_task *task = NULL;
 
-       dprintk("RPC:      wake_up_next(%p \"%s\")\n", queue, rpc_qname(queue));
-       spin_lock_bh(&queue->lock);
+       dprintk("RPC:       wake_up_next(%p \"%s\")\n",
+                       queue, rpc_qname(queue));
+       rcu_read_lock_bh();
+       spin_lock(&queue->lock);
        if (RPC_IS_PRIORITY(queue))
                task = __rpc_wake_up_next_priority(queue);
        else {
                task_for_first(task, &queue->tasks[0])
                        __rpc_wake_up_task(task);
        }
-       spin_unlock_bh(&queue->lock);
+       spin_unlock(&queue->lock);
+       rcu_read_unlock_bh();
 
        return task;
 }
@@ -504,7 +530,8 @@ void rpc_wake_up(struct rpc_wait_queue *queue)
        struct rpc_task *task, *next;
        struct list_head *head;
 
-       spin_lock_bh(&queue->lock);
+       rcu_read_lock_bh();
+       spin_lock(&queue->lock);
        head = &queue->tasks[queue->maxpriority];
        for (;;) {
                list_for_each_entry_safe(task, next, head, u.tk_wait.list)
@@ -513,7 +540,8 @@ void rpc_wake_up(struct rpc_wait_queue *queue)
                        break;
                head--;
        }
-       spin_unlock_bh(&queue->lock);
+       spin_unlock(&queue->lock);
+       rcu_read_unlock_bh();
 }
 
 /**
@@ -528,7 +556,8 @@ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
        struct rpc_task *task, *next;
        struct list_head *head;
 
-       spin_lock_bh(&queue->lock);
+       rcu_read_lock_bh();
+       spin_lock(&queue->lock);
        head = &queue->tasks[queue->maxpriority];
        for (;;) {
                list_for_each_entry_safe(task, next, head, u.tk_wait.list) {
@@ -539,7 +568,8 @@ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
                        break;
                head--;
        }
-       spin_unlock_bh(&queue->lock);
+       spin_unlock(&queue->lock);
+       rcu_read_unlock_bh();
 }
 
 static void __rpc_atrun(struct rpc_task *task)
@@ -561,7 +591,9 @@ void rpc_delay(struct rpc_task *task, unsigned long delay)
  */
 static void rpc_prepare_task(struct rpc_task *task)
 {
+       lock_kernel();
        task->tk_ops->rpc_call_prepare(task, task->tk_calldata);
+       unlock_kernel();
 }
 
 /*
@@ -571,7 +603,9 @@ void rpc_exit_task(struct rpc_task *task)
 {
        task->tk_action = NULL;
        if (task->tk_ops->rpc_call_done != NULL) {
+               lock_kernel();
                task->tk_ops->rpc_call_done(task, task->tk_calldata);
+               unlock_kernel();
                if (task->tk_action != NULL) {
                        WARN_ON(RPC_ASSASSINATED(task));
                        /* Always release the RPC slot and buffer memory */
@@ -581,15 +615,24 @@ void rpc_exit_task(struct rpc_task *task)
 }
 EXPORT_SYMBOL(rpc_exit_task);
 
+void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata)
+{
+       if (ops->rpc_release != NULL) {
+               lock_kernel();
+               ops->rpc_release(calldata);
+               unlock_kernel();
+       }
+}
+
 /*
  * This is the RPC `scheduler' (or rather, the finite state machine).
  */
-static int __rpc_execute(struct rpc_task *task)
+static void __rpc_execute(struct rpc_task *task)
 {
        int             status = 0;
 
-       dprintk("RPC: %4d rpc_execute flgs %x\n",
-                               task->tk_pid, task->tk_flags);
+       dprintk("RPC: %5u __rpc_execute flags=0x%x\n",
+                       task->tk_pid, task->tk_flags);
 
        BUG_ON(RPC_IS_QUEUED(task));
 
@@ -605,8 +648,8 @@ static int __rpc_execute(struct rpc_task *task)
                if (RPC_DO_CALLBACK(task)) {
                        /* Define a callback save pointer */
                        void (*save_callback)(struct rpc_task *);
-       
-                       /* 
+
+                       /*
                         * If a callback exists, save it, reset it,
                         * call it.
                         * The save is needed to stop from resetting
@@ -615,9 +658,7 @@ static int __rpc_execute(struct rpc_task *task)
                         */
                        save_callback=task->tk_callback;
                        task->tk_callback=NULL;
-                       lock_kernel();
                        save_callback(task);
-                       unlock_kernel();
                }
 
                /*
@@ -628,9 +669,7 @@ static int __rpc_execute(struct rpc_task *task)
                if (!RPC_IS_QUEUED(task)) {
                        if (task->tk_action == NULL)
                                break;
-                       lock_kernel();
                        task->tk_action(task);
-                       unlock_kernel();
                }
 
                /*
@@ -642,14 +681,14 @@ static int __rpc_execute(struct rpc_task *task)
                if (RPC_IS_ASYNC(task)) {
                        /* Careful! we may have raced... */
                        if (RPC_IS_QUEUED(task))
-                               return 0;
+                               return;
                        if (rpc_test_and_set_running(task))
-                               return 0;
+                               return;
                        continue;
                }
 
                /* sync task: sleep here */
-               dprintk("RPC: %4d sync task going to sleep\n", task->tk_pid);
+               dprintk("RPC: %5u sync task going to sleep\n", task->tk_pid);
                /* Note: Caller should be using rpc_clnt_sigmask() */
                status = out_of_line_wait_on_bit(&task->tk_runstate,
                                RPC_TASK_QUEUED, rpc_wait_bit_interruptible,
@@ -661,21 +700,19 @@ static int __rpc_execute(struct rpc_task *task)
                         * clean up after sleeping on some queue, we don't
                         * break the loop here, but go around once more.
                         */
-                       dprintk("RPC: %4d got signal\n", task->tk_pid);
+                       dprintk("RPC: %5u got signal\n", task->tk_pid);
                        task->tk_flags |= RPC_TASK_KILLED;
                        rpc_exit(task, -ERESTARTSYS);
                        rpc_wake_up_task(task);
                }
                rpc_set_running(task);
-               dprintk("RPC: %4d sync task resuming\n", task->tk_pid);
+               dprintk("RPC: %5u sync task resuming\n", task->tk_pid);
        }
 
-       dprintk("RPC: %4d, return %d, status %d\n", task->tk_pid, status, task->tk_status);
-       /* Wake up anyone who is waiting for task completion */
-       rpc_mark_complete_task(task);
+       dprintk("RPC: %5u return %d, status %d\n", task->tk_pid, status,
+                       task->tk_status);
        /* Release all resources associated with the task */
        rpc_release_task(task);
-       return status;
 }
 
 /*
@@ -687,12 +724,11 @@ static int __rpc_execute(struct rpc_task *task)
  *      released. In particular note that tk_release() will have
  *      been called, so your task memory may have been freed.
  */
-int
-rpc_execute(struct rpc_task *task)
+void rpc_execute(struct rpc_task *task)
 {
        rpc_set_active(task);
        rpc_set_running(task);
-       return __rpc_execute(task);
+       __rpc_execute(task);
 }
 
 static void rpc_async_schedule(struct work_struct *work)
@@ -786,21 +822,12 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons
                        task->tk_flags |= RPC_TASK_NOINTR;
        }
 
-#ifdef RPC_DEBUG
-       task->tk_magic = RPC_TASK_MAGIC_ID;
-       task->tk_pid = rpc_task_id++;
-#endif
-       /* Add to global list of all tasks */
-       spin_lock(&rpc_sched_lock);
-       list_add_tail(&task->tk_task, &all_tasks);
-       spin_unlock(&rpc_sched_lock);
-
        BUG_ON(task->tk_ops == NULL);
 
        /* starting timestamp */
        task->tk_start = jiffies;
 
-       dprintk("RPC: %4d new task procpid %d\n", task->tk_pid,
+       dprintk("RPC:       new task initialized, procpid %u\n",
                                current->pid);
 }
 
@@ -810,9 +837,10 @@ rpc_alloc_task(void)
        return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS);
 }
 
-static void rpc_free_task(struct rpc_task *task)
+static void rpc_free_task(struct rcu_head *rcu)
 {
-       dprintk("RPC: %4d freeing task\n", task->tk_pid);
+       struct rpc_task *task = container_of(rcu, struct rpc_task, u.tk_rcu);
+       dprintk("RPC: %5u freeing task\n", task->tk_pid);
        mempool_free(task, rpc_task_mempool);
 }
 
@@ -831,7 +859,7 @@ struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc
 
        rpc_init_task(task, clnt, flags, tk_ops, calldata);
 
-       dprintk("RPC: %4d allocated task\n", task->tk_pid);
+       dprintk("RPC:       allocated task %p\n", task);
        task->tk_flags |= RPC_TASK_DYNAMIC;
 out:
        return task;
@@ -847,17 +875,35 @@ cleanup:
        goto out;
 }
 
-void rpc_release_task(struct rpc_task *task)
+
+void rpc_put_task(struct rpc_task *task)
 {
        const struct rpc_call_ops *tk_ops = task->tk_ops;
        void *calldata = task->tk_calldata;
 
+       if (!atomic_dec_and_test(&task->tk_count))
+               return;
+       /* Release resources */
+       if (task->tk_rqstp)
+               xprt_release(task);
+       if (task->tk_msg.rpc_cred)
+               rpcauth_unbindcred(task);
+       if (task->tk_client) {
+               rpc_release_client(task->tk_client);
+               task->tk_client = NULL;
+       }
+       if (task->tk_flags & RPC_TASK_DYNAMIC)
+               call_rcu_bh(&task->u.tk_rcu, rpc_free_task);
+       rpc_release_calldata(tk_ops, calldata);
+}
+EXPORT_SYMBOL(rpc_put_task);
+
+static void rpc_release_task(struct rpc_task *task)
+{
 #ifdef RPC_DEBUG
        BUG_ON(task->tk_magic != RPC_TASK_MAGIC_ID);
 #endif
-       if (!atomic_dec_and_test(&task->tk_count))
-               return;
-       dprintk("RPC: %4d release task\n", task->tk_pid);
+       dprintk("RPC: %5u release task\n", task->tk_pid);
 
        /* Remove from global task list */
        spin_lock(&rpc_sched_lock);
@@ -869,23 +915,13 @@ void rpc_release_task(struct rpc_task *task)
        /* Synchronously delete any running timer */
        rpc_delete_timer(task);
 
-       /* Release resources */
-       if (task->tk_rqstp)
-               xprt_release(task);
-       if (task->tk_msg.rpc_cred)
-               rpcauth_unbindcred(task);
-       if (task->tk_client) {
-               rpc_release_client(task->tk_client);
-               task->tk_client = NULL;
-       }
-
 #ifdef RPC_DEBUG
        task->tk_magic = 0;
 #endif
-       if (task->tk_flags & RPC_TASK_DYNAMIC)
-               rpc_free_task(task);
-       if (tk_ops->rpc_release)
-               tk_ops->rpc_release(calldata);
+       /* Wake up anyone who is waiting for task completion */
+       rpc_mark_complete_task(task);
+
+       rpc_put_task(task);
 }
 
 /**
@@ -902,8 +938,7 @@ struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
        struct rpc_task *task;
        task = rpc_new_task(clnt, flags, ops, data);
        if (task == NULL) {
-               if (ops->rpc_release != NULL)
-                       ops->rpc_release(data);
+               rpc_release_calldata(ops, data);
                return ERR_PTR(-ENOMEM);
        }
        atomic_inc(&task->tk_count);
@@ -921,7 +956,7 @@ void rpc_killall_tasks(struct rpc_clnt *clnt)
        struct rpc_task *rovr;
        struct list_head *le;
 
-       dprintk("RPC:      killing all tasks for client %p\n", clnt);
+       dprintk("RPC:       killing all tasks for client %p\n", clnt);
 
        /*
         * Spin lock all_tasks to prevent changes...
@@ -950,7 +985,8 @@ static void rpciod_killall(void)
                rpc_killall_tasks(NULL);
                flush_workqueue(rpciod_workqueue);
                if (!list_empty(&all_tasks)) {
-                       dprintk("rpciod_killall: waiting for tasks to exit\n");
+                       dprintk("RPC:       rpciod_killall: waiting for tasks "
+                                       "to exit\n");
                        yield();
                }
        }
@@ -970,7 +1006,7 @@ rpciod_up(void)
        int error = 0;
 
        mutex_lock(&rpciod_mutex);
-       dprintk("rpciod_up: users %d\n", rpciod_users);
+       dprintk("RPC:       rpciod_up: users %u\n", rpciod_users);
        rpciod_users++;
        if (rpciod_workqueue)
                goto out;
@@ -978,7 +1014,7 @@ rpciod_up(void)
         * If there's no pid, we should be the first user.
         */
        if (rpciod_users > 1)
-               printk(KERN_WARNING "rpciod_up: no workqueue, %d users??\n", rpciod_users);
+               printk(KERN_WARNING "rpciod_up: no workqueue, %u users??\n", rpciod_users);
        /*
         * Create the rpciod thread and wait for it to start.
         */
@@ -1000,7 +1036,7 @@ void
 rpciod_down(void)
 {
        mutex_lock(&rpciod_mutex);
-       dprintk("rpciod_down sema %d\n", rpciod_users);
+       dprintk("RPC:       rpciod_down sema %u\n", rpciod_users);
        if (rpciod_users) {
                if (--rpciod_users)
                        goto out;
@@ -1008,7 +1044,7 @@ rpciod_down(void)
                printk(KERN_WARNING "rpciod_down: no users??\n");
 
        if (!rpciod_workqueue) {
-               dprintk("rpciod_down: Nothing to do!\n");
+               dprintk("RPC:       rpciod_down: Nothing to do!\n");
                goto out;
        }
        rpciod_killall();
@@ -1038,7 +1074,7 @@ void rpc_show_tasks(void)
                if (RPC_IS_QUEUED(t))
                        rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq);
 
-               printk("%05d %04d %04x %06d %8p %6d %8p %08ld %8s %8p %8p\n",
+               printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n",
                        t->tk_pid,
                        (t->tk_msg.rpc_proc ? t->tk_msg.rpc_proc->p_proc : -1),
                        t->tk_flags, t->tk_status,