Commit 3ff7576d authored by Trond Myklebust's avatar Trond Myklebust

SUNRPC: Clean up the initialisation of priority queue scheduling info.

We want the default scheduling priority (priority == 0) to remain
RPC_PRIORITY_NORMAL.

Also ensure that the priority wait queue scheduling is per process id
instead of sometimes being per thread, and sometimes being per inode.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent c970aa85
...@@ -331,8 +331,6 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, ...@@ -331,8 +331,6 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
rpc_init_task(&data->task, &task_setup_data); rpc_init_task(&data->task, &task_setup_data);
NFS_PROTO(inode)->read_setup(data); NFS_PROTO(inode)->read_setup(data);
data->task.tk_cookie = (unsigned long) inode;
rpc_execute(&data->task); rpc_execute(&data->task);
dprintk("NFS: %5u initiated direct read call " dprintk("NFS: %5u initiated direct read call "
...@@ -465,9 +463,6 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) ...@@ -465,9 +463,6 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
rpc_init_task(&data->task, &task_setup_data); rpc_init_task(&data->task, &task_setup_data);
NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE); NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE);
data->task.tk_priority = RPC_PRIORITY_NORMAL;
data->task.tk_cookie = (unsigned long) inode;
/* /*
* We're called via an RPC callback, so BKL is already held. * We're called via an RPC callback, so BKL is already held.
*/ */
...@@ -534,8 +529,6 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) ...@@ -534,8 +529,6 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
rpc_init_task(&data->task, &task_setup_data); rpc_init_task(&data->task, &task_setup_data);
NFS_PROTO(data->inode)->commit_setup(data, 0); NFS_PROTO(data->inode)->commit_setup(data, 0);
data->task.tk_priority = RPC_PRIORITY_NORMAL;
data->task.tk_cookie = (unsigned long)data->inode;
/* Note: task.tk_ops->rpc_release will free dreq->commit_data */ /* Note: task.tk_ops->rpc_release will free dreq->commit_data */
dreq->commit_data = NULL; dreq->commit_data = NULL;
...@@ -718,9 +711,6 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, ...@@ -718,9 +711,6 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
rpc_init_task(&data->task, &task_setup_data); rpc_init_task(&data->task, &task_setup_data);
NFS_PROTO(inode)->write_setup(data, sync); NFS_PROTO(inode)->write_setup(data, sync);
data->task.tk_priority = RPC_PRIORITY_NORMAL;
data->task.tk_cookie = (unsigned long) inode;
rpc_execute(&data->task); rpc_execute(&data->task);
dprintk("NFS: %5u initiated direct write call " dprintk("NFS: %5u initiated direct write call "
......
...@@ -189,8 +189,6 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, ...@@ -189,8 +189,6 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
rpc_init_task(&data->task, &task_setup_data); rpc_init_task(&data->task, &task_setup_data);
NFS_PROTO(inode)->read_setup(data); NFS_PROTO(inode)->read_setup(data);
data->task.tk_cookie = (unsigned long)inode;
dprintk("NFS: %5u initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n", dprintk("NFS: %5u initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n",
data->task.tk_pid, data->task.tk_pid,
inode->i_sb->s_id, inode->i_sb->s_id,
......
...@@ -753,7 +753,7 @@ static void nfs_writepage_release(struct nfs_page *req) ...@@ -753,7 +753,7 @@ static void nfs_writepage_release(struct nfs_page *req)
nfs_clear_page_tag_locked(req); nfs_clear_page_tag_locked(req);
} }
static inline int flush_task_priority(int how) static int flush_task_priority(int how)
{ {
switch (how & (FLUSH_HIGHPRI|FLUSH_LOWPRI)) { switch (how & (FLUSH_HIGHPRI|FLUSH_LOWPRI)) {
case FLUSH_HIGHPRI: case FLUSH_HIGHPRI:
...@@ -775,11 +775,13 @@ static void nfs_write_rpcsetup(struct nfs_page *req, ...@@ -775,11 +775,13 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
{ {
struct inode *inode = req->wb_context->path.dentry->d_inode; struct inode *inode = req->wb_context->path.dentry->d_inode;
int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
int priority = flush_task_priority(how);
struct rpc_task_setup task_setup_data = { struct rpc_task_setup task_setup_data = {
.rpc_client = NFS_CLIENT(inode), .rpc_client = NFS_CLIENT(inode),
.callback_ops = call_ops, .callback_ops = call_ops,
.callback_data = data, .callback_data = data,
.flags = flags, .flags = flags,
.priority = priority,
}; };
/* Set up the RPC argument and reply structs /* Set up the RPC argument and reply structs
...@@ -805,9 +807,6 @@ static void nfs_write_rpcsetup(struct nfs_page *req, ...@@ -805,9 +807,6 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
rpc_init_task(&data->task, &task_setup_data); rpc_init_task(&data->task, &task_setup_data);
NFS_PROTO(inode)->write_setup(data, how); NFS_PROTO(inode)->write_setup(data, how);
data->task.tk_priority = flush_task_priority(how);
data->task.tk_cookie = (unsigned long)inode;
dprintk("NFS: %5u initiated write call " dprintk("NFS: %5u initiated write call "
"(req %s/%Ld, %u bytes @ offset %Lu)\n", "(req %s/%Ld, %u bytes @ offset %Lu)\n",
data->task.tk_pid, data->task.tk_pid,
...@@ -1152,11 +1151,13 @@ static void nfs_commit_rpcsetup(struct list_head *head, ...@@ -1152,11 +1151,13 @@ static void nfs_commit_rpcsetup(struct list_head *head,
struct nfs_page *first = nfs_list_entry(head->next); struct nfs_page *first = nfs_list_entry(head->next);
struct inode *inode = first->wb_context->path.dentry->d_inode; struct inode *inode = first->wb_context->path.dentry->d_inode;
int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
int priority = flush_task_priority(how);
struct rpc_task_setup task_setup_data = { struct rpc_task_setup task_setup_data = {
.rpc_client = NFS_CLIENT(inode), .rpc_client = NFS_CLIENT(inode),
.callback_ops = &nfs_commit_ops, .callback_ops = &nfs_commit_ops,
.callback_data = data, .callback_data = data,
.flags = flags, .flags = flags,
.priority = priority,
}; };
/* Set up the RPC argument and reply structs /* Set up the RPC argument and reply structs
...@@ -1180,9 +1181,6 @@ static void nfs_commit_rpcsetup(struct list_head *head, ...@@ -1180,9 +1181,6 @@ static void nfs_commit_rpcsetup(struct list_head *head,
rpc_init_task(&data->task, &task_setup_data); rpc_init_task(&data->task, &task_setup_data);
NFS_PROTO(inode)->commit_setup(data, how); NFS_PROTO(inode)->commit_setup(data, how);
data->task.tk_priority = flush_task_priority(how);
data->task.tk_cookie = (unsigned long)inode;
dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
} }
......
...@@ -56,8 +56,6 @@ struct rpc_task { ...@@ -56,8 +56,6 @@ struct rpc_task {
__u8 tk_garb_retry; __u8 tk_garb_retry;
__u8 tk_cred_retry; __u8 tk_cred_retry;
unsigned long tk_cookie; /* Cookie for batching tasks */
/* /*
* timeout_fn to be executed by timer bottom half * timeout_fn to be executed by timer bottom half
* callback to be executed after waking up * callback to be executed after waking up
...@@ -78,7 +76,6 @@ struct rpc_task { ...@@ -78,7 +76,6 @@ struct rpc_task {
struct timer_list tk_timer; /* kernel timer */ struct timer_list tk_timer; /* kernel timer */
unsigned long tk_timeout; /* timeout for rpc_sleep() */ unsigned long tk_timeout; /* timeout for rpc_sleep() */
unsigned short tk_flags; /* misc flags */ unsigned short tk_flags; /* misc flags */
unsigned char tk_priority : 2;/* Task priority */
unsigned long tk_runstate; /* Task run status */ unsigned long tk_runstate; /* Task run status */
struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could
* be any workqueue * be any workqueue
...@@ -94,6 +91,9 @@ struct rpc_task { ...@@ -94,6 +91,9 @@ struct rpc_task {
unsigned long tk_start; /* RPC task init timestamp */ unsigned long tk_start; /* RPC task init timestamp */
long tk_rtt; /* round-trip time (jiffies) */ long tk_rtt; /* round-trip time (jiffies) */
pid_t tk_owner; /* Process id for batching tasks */
unsigned char tk_priority : 2;/* Task priority */
#ifdef RPC_DEBUG #ifdef RPC_DEBUG
unsigned short tk_pid; /* debugging aid */ unsigned short tk_pid; /* debugging aid */
#endif #endif
...@@ -123,6 +123,7 @@ struct rpc_task_setup { ...@@ -123,6 +123,7 @@ struct rpc_task_setup {
const struct rpc_call_ops *callback_ops; const struct rpc_call_ops *callback_ops;
void *callback_data; void *callback_data;
unsigned short flags; unsigned short flags;
signed char priority;
}; };
/* /*
...@@ -187,10 +188,10 @@ struct rpc_task_setup { ...@@ -187,10 +188,10 @@ struct rpc_task_setup {
* Note: if you change these, you must also change * Note: if you change these, you must also change
* the task initialization definitions below. * the task initialization definitions below.
*/ */
#define RPC_PRIORITY_LOW 0 #define RPC_PRIORITY_LOW (-1)
#define RPC_PRIORITY_NORMAL 1 #define RPC_PRIORITY_NORMAL (0)
#define RPC_PRIORITY_HIGH 2 #define RPC_PRIORITY_HIGH (1)
#define RPC_NR_PRIORITY (RPC_PRIORITY_HIGH+1) #define RPC_NR_PRIORITY (1 + RPC_PRIORITY_HIGH - RPC_PRIORITY_LOW)
/* /*
* RPC synchronization objects * RPC synchronization objects
...@@ -198,7 +199,7 @@ struct rpc_task_setup { ...@@ -198,7 +199,7 @@ struct rpc_task_setup {
struct rpc_wait_queue { struct rpc_wait_queue {
spinlock_t lock; spinlock_t lock;
struct list_head tasks[RPC_NR_PRIORITY]; /* task queue for each priority level */ struct list_head tasks[RPC_NR_PRIORITY]; /* task queue for each priority level */
unsigned long cookie; /* cookie of last task serviced */ pid_t owner; /* process id of last task serviced */
unsigned char maxpriority; /* maximum priority (0 if queue is not a priority queue) */ unsigned char maxpriority; /* maximum priority (0 if queue is not a priority queue) */
unsigned char priority; /* current priority */ unsigned char priority; /* current priority */
unsigned char count; /* # task groups remaining serviced so far */ unsigned char count; /* # task groups remaining serviced so far */
......
...@@ -135,7 +135,7 @@ static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue, struct r ...@@ -135,7 +135,7 @@ static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue, struct r
if (unlikely(task->tk_priority > queue->maxpriority)) if (unlikely(task->tk_priority > queue->maxpriority))
q = &queue->tasks[queue->maxpriority]; q = &queue->tasks[queue->maxpriority];
list_for_each_entry(t, q, u.tk_wait.list) { list_for_each_entry(t, q, u.tk_wait.list) {
if (t->tk_cookie == task->tk_cookie) { if (t->tk_owner == task->tk_owner) {
list_add_tail(&task->u.tk_wait.list, &t->u.tk_wait.links); list_add_tail(&task->u.tk_wait.list, &t->u.tk_wait.links);
return; return;
} }
...@@ -208,26 +208,26 @@ static inline void rpc_set_waitqueue_priority(struct rpc_wait_queue *queue, int ...@@ -208,26 +208,26 @@ static inline void rpc_set_waitqueue_priority(struct rpc_wait_queue *queue, int
queue->count = 1 << (priority * 2); queue->count = 1 << (priority * 2);
} }
static inline void rpc_set_waitqueue_cookie(struct rpc_wait_queue *queue, unsigned long cookie) static inline void rpc_set_waitqueue_owner(struct rpc_wait_queue *queue, pid_t pid)
{ {
queue->cookie = cookie; queue->owner = pid;
queue->nr = RPC_BATCH_COUNT; queue->nr = RPC_BATCH_COUNT;
} }
static inline void rpc_reset_waitqueue_priority(struct rpc_wait_queue *queue) static inline void rpc_reset_waitqueue_priority(struct rpc_wait_queue *queue)
{ {
rpc_set_waitqueue_priority(queue, queue->maxpriority); rpc_set_waitqueue_priority(queue, queue->maxpriority);
rpc_set_waitqueue_cookie(queue, 0); rpc_set_waitqueue_owner(queue, 0);
} }
static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname, int maxprio) static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname, unsigned char nr_queues)
{ {
int i; int i;
spin_lock_init(&queue->lock); spin_lock_init(&queue->lock);
for (i = 0; i < ARRAY_SIZE(queue->tasks); i++) for (i = 0; i < ARRAY_SIZE(queue->tasks); i++)
INIT_LIST_HEAD(&queue->tasks[i]); INIT_LIST_HEAD(&queue->tasks[i]);
queue->maxpriority = maxprio; queue->maxpriority = nr_queues - 1;
rpc_reset_waitqueue_priority(queue); rpc_reset_waitqueue_priority(queue);
#ifdef RPC_DEBUG #ifdef RPC_DEBUG
queue->name = qname; queue->name = qname;
...@@ -236,12 +236,12 @@ static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const c ...@@ -236,12 +236,12 @@ static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const c
void rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname) void rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname)
{ {
__rpc_init_priority_wait_queue(queue, qname, RPC_PRIORITY_HIGH); __rpc_init_priority_wait_queue(queue, qname, RPC_NR_PRIORITY);
} }
void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname) void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname)
{ {
__rpc_init_priority_wait_queue(queue, qname, 0); __rpc_init_priority_wait_queue(queue, qname, 1);
} }
EXPORT_SYMBOL_GPL(rpc_init_wait_queue); EXPORT_SYMBOL_GPL(rpc_init_wait_queue);
...@@ -456,12 +456,12 @@ static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queu ...@@ -456,12 +456,12 @@ static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queu
struct rpc_task *task; struct rpc_task *task;
/* /*
* Service a batch of tasks from a single cookie. * Service a batch of tasks from a single owner.
*/ */
q = &queue->tasks[queue->priority]; q = &queue->tasks[queue->priority];
if (!list_empty(q)) { if (!list_empty(q)) {
task = list_entry(q->next, struct rpc_task, u.tk_wait.list); task = list_entry(q->next, struct rpc_task, u.tk_wait.list);
if (queue->cookie == task->tk_cookie) { if (queue->owner == task->tk_owner) {
if (--queue->nr) if (--queue->nr)
goto out; goto out;
list_move_tail(&task->u.tk_wait.list, q); list_move_tail(&task->u.tk_wait.list, q);
...@@ -470,7 +470,7 @@ static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queu ...@@ -470,7 +470,7 @@ static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queu
* Check if we need to switch queues. * Check if we need to switch queues.
*/ */
if (--queue->count) if (--queue->count)
goto new_cookie; goto new_owner;
} }
/* /*
...@@ -492,8 +492,8 @@ static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queu ...@@ -492,8 +492,8 @@ static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queu
new_queue: new_queue:
rpc_set_waitqueue_priority(queue, (unsigned int)(q - &queue->tasks[0])); rpc_set_waitqueue_priority(queue, (unsigned int)(q - &queue->tasks[0]));
new_cookie: new_owner:
rpc_set_waitqueue_cookie(queue, task->tk_cookie); rpc_set_waitqueue_owner(queue, task->tk_owner);
out: out:
__rpc_wake_up_task(task); __rpc_wake_up_task(task);
return task; return task;
...@@ -830,8 +830,8 @@ void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *task_setu ...@@ -830,8 +830,8 @@ void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *task_setu
task->tk_garb_retry = 2; task->tk_garb_retry = 2;
task->tk_cred_retry = 2; task->tk_cred_retry = 2;
task->tk_priority = RPC_PRIORITY_NORMAL; task->tk_priority = task_setup_data->priority - RPC_PRIORITY_LOW;
task->tk_cookie = (unsigned long)current; task->tk_owner = current->tgid;
/* Initialize workqueue for async tasks */ /* Initialize workqueue for async tasks */
task->tk_workqueue = rpciod_workqueue; task->tk_workqueue = rpciod_workqueue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment