@@ -99,64 +99,78 @@ __rpc_add_timer(struct rpc_wait_queue *queue, struct rpc_task *task)
99
99
list_add (& task -> u .tk_wait .timer_list , & queue -> timer_list .list );
100
100
}
101
101
102
- static void rpc_rotate_queue_owner (struct rpc_wait_queue * queue )
103
- {
104
- struct list_head * q = & queue -> tasks [queue -> priority ];
105
- struct rpc_task * task ;
106
-
107
- if (!list_empty (q )) {
108
- task = list_first_entry (q , struct rpc_task , u .tk_wait .list );
109
- if (task -> tk_owner == queue -> owner )
110
- list_move_tail (& task -> u .tk_wait .list , q );
111
- }
112
- }
113
-
114
102
static void rpc_set_waitqueue_priority (struct rpc_wait_queue * queue , int priority )
115
103
{
116
104
if (queue -> priority != priority ) {
117
- /* Fairness: rotate the list when changing priority */
118
- rpc_rotate_queue_owner (queue );
119
105
queue -> priority = priority ;
106
+ queue -> nr = 1U << priority ;
120
107
}
121
108
}
122
109
123
- static void rpc_set_waitqueue_owner (struct rpc_wait_queue * queue , pid_t pid )
124
- {
125
- queue -> owner = pid ;
126
- queue -> nr = RPC_BATCH_COUNT ;
127
- }
128
-
129
110
static void rpc_reset_waitqueue_priority (struct rpc_wait_queue * queue )
130
111
{
131
112
rpc_set_waitqueue_priority (queue , queue -> maxpriority );
132
- rpc_set_waitqueue_owner (queue , 0 );
133
113
}
134
114
135
115
/*
136
- * Add new request to a priority queue.
116
+ * Add a request to a queue list
137
117
*/
138
- static void __rpc_add_wait_queue_priority (struct rpc_wait_queue * queue ,
139
- struct rpc_task * task ,
140
- unsigned char queue_priority )
118
+ static void
119
+ __rpc_list_enqueue_task (struct list_head * q , struct rpc_task * task )
141
120
{
142
- struct list_head * q ;
143
121
struct rpc_task * t ;
144
122
145
- INIT_LIST_HEAD (& task -> u .tk_wait .links );
146
- if (unlikely (queue_priority > queue -> maxpriority ))
147
- queue_priority = queue -> maxpriority ;
148
- if (queue_priority > queue -> priority )
149
- rpc_set_waitqueue_priority (queue , queue_priority );
150
- q = & queue -> tasks [queue_priority ];
151
123
list_for_each_entry (t , q , u .tk_wait .list ) {
152
124
if (t -> tk_owner == task -> tk_owner ) {
153
- list_add_tail (& task -> u .tk_wait .list , & t -> u .tk_wait .links );
125
+ list_add_tail (& task -> u .tk_wait .links ,
126
+ & t -> u .tk_wait .links );
127
+ /* Cache the queue head in task->u.tk_wait.list */
128
+ task -> u .tk_wait .list .next = q ;
129
+ task -> u .tk_wait .list .prev = NULL ;
154
130
return ;
155
131
}
156
132
}
133
+ INIT_LIST_HEAD (& task -> u .tk_wait .links );
157
134
list_add_tail (& task -> u .tk_wait .list , q );
158
135
}
159
136
137
+ /*
138
+ * Remove request from a queue list
139
+ */
140
+ static void
141
+ __rpc_list_dequeue_task (struct rpc_task * task )
142
+ {
143
+ struct list_head * q ;
144
+ struct rpc_task * t ;
145
+
146
+ if (task -> u .tk_wait .list .prev == NULL ) {
147
+ list_del (& task -> u .tk_wait .links );
148
+ return ;
149
+ }
150
+ if (!list_empty (& task -> u .tk_wait .links )) {
151
+ t = list_first_entry (& task -> u .tk_wait .links ,
152
+ struct rpc_task ,
153
+ u .tk_wait .links );
154
+ /* Assume __rpc_list_enqueue_task() cached the queue head */
155
+ q = t -> u .tk_wait .list .next ;
156
+ list_add_tail (& t -> u .tk_wait .list , q );
157
+ list_del (& task -> u .tk_wait .links );
158
+ }
159
+ list_del (& task -> u .tk_wait .list );
160
+ }
161
+
162
+ /*
163
+ * Add new request to a priority queue.
164
+ */
165
+ static void __rpc_add_wait_queue_priority (struct rpc_wait_queue * queue ,
166
+ struct rpc_task * task ,
167
+ unsigned char queue_priority )
168
+ {
169
+ if (unlikely (queue_priority > queue -> maxpriority ))
170
+ queue_priority = queue -> maxpriority ;
171
+ __rpc_list_enqueue_task (& queue -> tasks [queue_priority ], task );
172
+ }
173
+
160
174
/*
161
175
* Add new request to wait queue.
162
176
*
@@ -194,13 +208,7 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue,
194
208
*/
195
209
static void __rpc_remove_wait_queue_priority (struct rpc_task * task )
196
210
{
197
- struct rpc_task * t ;
198
-
199
- if (!list_empty (& task -> u .tk_wait .links )) {
200
- t = list_entry (task -> u .tk_wait .links .next , struct rpc_task , u .tk_wait .list );
201
- list_move (& t -> u .tk_wait .list , & task -> u .tk_wait .list );
202
- list_splice_init (& task -> u .tk_wait .links , & t -> u .tk_wait .links );
203
- }
211
+ __rpc_list_dequeue_task (task );
204
212
}
205
213
206
214
/*
@@ -212,7 +220,8 @@ static void __rpc_remove_wait_queue(struct rpc_wait_queue *queue, struct rpc_tas
212
220
__rpc_disable_timer (queue , task );
213
221
if (RPC_IS_PRIORITY (queue ))
214
222
__rpc_remove_wait_queue_priority (task );
215
- list_del (& task -> u .tk_wait .list );
223
+ else
224
+ list_del (& task -> u .tk_wait .list );
216
225
queue -> qlen -- ;
217
226
dprintk ("RPC: %5u removed from queue %p \"%s\"\n" ,
218
227
task -> tk_pid , queue , rpc_qname (queue ));
@@ -545,17 +554,9 @@ static struct rpc_task *__rpc_find_next_queued_priority(struct rpc_wait_queue *q
545
554
* Service a batch of tasks from a single owner.
546
555
*/
547
556
q = & queue -> tasks [queue -> priority ];
548
- if (!list_empty (q )) {
549
- task = list_entry (q -> next , struct rpc_task , u .tk_wait .list );
550
- if (queue -> owner == task -> tk_owner ) {
551
- if (-- queue -> nr )
552
- goto out ;
553
- list_move_tail (& task -> u .tk_wait .list , q );
554
- }
555
- /*
556
- * Check if we need to switch queues.
557
- */
558
- goto new_owner ;
557
+ if (!list_empty (q ) && -- queue -> nr ) {
558
+ task = list_first_entry (q , struct rpc_task , u .tk_wait .list );
559
+ goto out ;
559
560
}
560
561
561
562
/*
@@ -567,7 +568,7 @@ static struct rpc_task *__rpc_find_next_queued_priority(struct rpc_wait_queue *q
567
568
else
568
569
q = q - 1 ;
569
570
if (!list_empty (q )) {
570
- task = list_entry ( q -> next , struct rpc_task , u .tk_wait .list );
571
+ task = list_first_entry ( q , struct rpc_task , u .tk_wait .list );
571
572
goto new_queue ;
572
573
}
573
574
} while (q != & queue -> tasks [queue -> priority ]);
@@ -577,8 +578,6 @@ static struct rpc_task *__rpc_find_next_queued_priority(struct rpc_wait_queue *q
577
578
578
579
new_queue :
579
580
rpc_set_waitqueue_priority (queue , (unsigned int )(q - & queue -> tasks [0 ]));
580
- new_owner :
581
- rpc_set_waitqueue_owner (queue , task -> tk_owner );
582
581
out :
583
582
return task ;
584
583
}
0 commit comments