Rev 423 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
423 | giacomo | 1 | /* |
2 | * linux/include/linux/sunrpc/sched.h |
||
3 | * |
||
4 | * Scheduling primitives for kernel Sun RPC. |
||
5 | * |
||
6 | * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> |
||
7 | */ |
||
8 | |||
9 | #ifndef _LINUX_SUNRPC_SCHED_H_ |
||
10 | #define _LINUX_SUNRPC_SCHED_H_ |
||
11 | |||
12 | #include <linux/timer.h> |
||
13 | #include <linux/sunrpc/types.h> |
||
14 | #include <linux/wait.h> |
||
15 | #include <linux/sunrpc/xdr.h> |
||
16 | |||
17 | /* |
||
18 | * This is the actual RPC procedure call info. |
||
19 | */ |
||
20 | struct rpc_procinfo; |
||
21 | struct rpc_message { |
||
22 | struct rpc_procinfo * rpc_proc; /* Procedure information */ |
||
23 | void * rpc_argp; /* Arguments */ |
||
24 | void * rpc_resp; /* Result */ |
||
25 | struct rpc_cred * rpc_cred; /* Credentials */ |
||
26 | }; |
||
27 | |||
28 | /* |
||
29 | * This is the RPC task struct |
||
30 | */ |
||
31 | struct rpc_task { |
||
32 | struct list_head tk_list; /* wait queue links */ |
||
33 | #ifdef RPC_DEBUG |
||
34 | unsigned long tk_magic; /* 0xf00baa */ |
||
35 | #endif |
||
36 | struct list_head tk_task; /* global list of tasks */ |
||
37 | struct rpc_clnt * tk_client; /* RPC client */ |
||
38 | struct rpc_rqst * tk_rqstp; /* RPC request */ |
||
39 | int tk_status; /* result of last operation */ |
||
40 | struct rpc_wait_queue * tk_rpcwait; /* RPC wait queue we're on */ |
||
41 | |||
42 | /* |
||
43 | * RPC call state |
||
44 | */ |
||
45 | struct rpc_message tk_msg; /* RPC call info */ |
||
46 | __u32 * tk_buffer; /* XDR buffer */ |
||
47 | size_t tk_bufsize; |
||
48 | __u8 tk_garb_retry, |
||
49 | tk_cred_retry, |
||
50 | tk_suid_retry; |
||
51 | u32 tk_gss_seqno; /* rpcsec_gss sequence number |
||
52 | used on this request */ |
||
53 | |||
54 | /* |
||
55 | * timeout_fn to be executed by timer bottom half |
||
56 | * callback to be executed after waking up |
||
57 | * action next procedure for async tasks |
||
58 | * exit exit async task and report to caller |
||
59 | */ |
||
60 | void (*tk_timeout_fn)(struct rpc_task *); |
||
61 | void (*tk_callback)(struct rpc_task *); |
||
62 | void (*tk_action)(struct rpc_task *); |
||
63 | void (*tk_exit)(struct rpc_task *); |
||
64 | void (*tk_release)(struct rpc_task *); |
||
65 | void * tk_calldata; |
||
66 | |||
67 | /* |
||
68 | * tk_timer is used for async processing by the RPC scheduling |
||
69 | * primitives. You should not access this directly unless |
||
70 | * you have a pathological interest in kernel oopses. |
||
71 | */ |
||
72 | struct timer_list tk_timer; /* kernel timer */ |
||
73 | wait_queue_head_t tk_wait; /* sync: sleep on this q */ |
||
74 | unsigned long tk_timeout; /* timeout for rpc_sleep() */ |
||
75 | unsigned short tk_flags; /* misc flags */ |
||
76 | unsigned char tk_active : 1;/* Task has been activated */ |
||
77 | unsigned long tk_runstate; /* Task run status */ |
||
78 | #ifdef RPC_DEBUG |
||
79 | unsigned short tk_pid; /* debugging aid */ |
||
80 | #endif |
||
81 | }; |
||
82 | #define tk_auth tk_client->cl_auth |
||
83 | #define tk_xprt tk_client->cl_xprt |
||
84 | |||
85 | /* support walking a list of tasks on a wait queue */ |
||
86 | #define task_for_each(task, pos, head) \ |
||
87 | list_for_each(pos, head) \ |
||
88 | if ((task=list_entry(pos, struct rpc_task, tk_list)),1) |
||
89 | |||
90 | #define task_for_first(task, head) \ |
||
91 | if (!list_empty(head) && \ |
||
92 | ((task=list_entry((head)->next, struct rpc_task, tk_list)),1)) |
||
93 | |||
94 | /* .. and walking list of all tasks */ |
||
95 | #define alltask_for_each(task, pos, head) \ |
||
96 | list_for_each(pos, head) \ |
||
97 | if ((task=list_entry(pos, struct rpc_task, tk_task)),1) |
||
98 | |||
99 | typedef void (*rpc_action)(struct rpc_task *); |
||
100 | |||
101 | /* |
||
102 | * RPC task flags |
||
103 | */ |
||
104 | #define RPC_TASK_ASYNC 0x0001 /* is an async task */ |
||
105 | #define RPC_TASK_SWAPPER 0x0002 /* is swapping in/out */ |
||
106 | #define RPC_TASK_SETUID 0x0004 /* is setuid process */ |
||
107 | #define RPC_TASK_CHILD 0x0008 /* is child of other task */ |
||
108 | #define RPC_CALL_REALUID 0x0010 /* try using real uid */ |
||
109 | #define RPC_CALL_MAJORSEEN 0x0020 /* major timeout seen */ |
||
110 | #define RPC_TASK_ROOTCREDS 0x0040 /* force root creds */ |
||
111 | #define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */ |
||
112 | #define RPC_TASK_KILLED 0x0100 /* task was killed */ |
||
113 | |||
114 | #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) |
||
115 | #define RPC_IS_SETUID(t) ((t)->tk_flags & RPC_TASK_SETUID) |
||
116 | #define RPC_IS_CHILD(t) ((t)->tk_flags & RPC_TASK_CHILD) |
||
117 | #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) |
||
118 | #define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS) |
||
119 | #define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) |
||
120 | #define RPC_IS_ACTIVATED(t) ((t)->tk_active) |
||
121 | #define RPC_DO_CALLBACK(t) ((t)->tk_callback != NULL) |
||
122 | |||
123 | #define RPC_TASK_SLEEPING 0 |
||
124 | #define RPC_TASK_RUNNING 1 |
||
125 | #define RPC_IS_SLEEPING(t) (test_bit(RPC_TASK_SLEEPING, &(t)->tk_runstate)) |
||
126 | #define RPC_IS_RUNNING(t) (test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)) |
||
127 | |||
128 | #define rpc_set_running(t) (set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)) |
||
129 | #define rpc_clear_running(t) (clear_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)) |
||
130 | |||
131 | #define rpc_set_sleeping(t) (set_bit(RPC_TASK_SLEEPING, &(t)->tk_runstate)) |
||
132 | |||
133 | #define rpc_clear_sleeping(t) \ |
||
134 | do { \ |
||
135 | smp_mb__before_clear_bit(); \ |
||
136 | clear_bit(RPC_TASK_SLEEPING, &(t)->tk_runstate); \ |
||
137 | smp_mb__after_clear_bit(); \ |
||
138 | } while(0) |
||
139 | |||
140 | /* |
||
141 | * RPC synchronization objects |
||
142 | */ |
||
143 | struct rpc_wait_queue { |
||
144 | struct list_head tasks; |
||
145 | #ifdef RPC_DEBUG |
||
146 | char * name; |
||
147 | #endif |
||
148 | }; |
||
149 | |||
150 | #ifndef RPC_DEBUG |
||
151 | # define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var)}) |
||
152 | # define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var.tasks,qname) |
||
153 | # define INIT_RPC_WAITQ(ptr,qname) do { \ |
||
154 | INIT_LIST_HEAD(&(ptr)->tasks); \ |
||
155 | } while(0) |
||
156 | #else |
||
157 | # define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var.tasks), qname}) |
||
158 | # define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var,qname) |
||
159 | # define INIT_RPC_WAITQ(ptr,qname) do { \ |
||
160 | INIT_LIST_HEAD(&(ptr)->tasks); (ptr)->name = qname; \ |
||
161 | } while(0) |
||
162 | #endif |
||
163 | |||
164 | /* |
||
165 | * Function prototypes |
||
166 | */ |
||
167 | struct rpc_task *rpc_new_task(struct rpc_clnt *, rpc_action, int flags); |
||
168 | struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent); |
||
169 | void rpc_init_task(struct rpc_task *, struct rpc_clnt *, |
||
170 | rpc_action exitfunc, int flags); |
||
171 | void rpc_release_task(struct rpc_task *); |
||
172 | void rpc_killall_tasks(struct rpc_clnt *); |
||
173 | int rpc_execute(struct rpc_task *); |
||
174 | void rpc_run_child(struct rpc_task *parent, struct rpc_task *child, |
||
175 | rpc_action action); |
||
176 | int rpc_add_wait_queue(struct rpc_wait_queue *, struct rpc_task *); |
||
177 | void rpc_remove_wait_queue(struct rpc_task *); |
||
178 | void rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *, |
||
179 | rpc_action action, rpc_action timer); |
||
180 | void rpc_add_timer(struct rpc_task *, rpc_action); |
||
181 | void rpc_wake_up_task(struct rpc_task *); |
||
182 | void rpc_wake_up(struct rpc_wait_queue *); |
||
183 | struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *); |
||
184 | void rpc_wake_up_status(struct rpc_wait_queue *, int); |
||
185 | void rpc_delay(struct rpc_task *, unsigned long); |
||
186 | void * rpc_malloc(struct rpc_task *, size_t); |
||
187 | void rpc_free(struct rpc_task *); |
||
188 | int rpciod_up(void); |
||
189 | void rpciod_down(void); |
||
190 | void rpciod_wake_up(void); |
||
191 | #ifdef RPC_DEBUG |
||
192 | void rpc_show_tasks(void); |
||
193 | #endif |
||
194 | int rpc_init_mempool(void); |
||
195 | void rpc_destroy_mempool(void); |
||
196 | |||
197 | static __inline__ void |
||
198 | rpc_exit(struct rpc_task *task, int status) |
||
199 | { |
||
200 | task->tk_status = status; |
||
201 | task->tk_action = NULL; |
||
202 | } |
||
203 | |||
204 | #ifdef RPC_DEBUG |
||
205 | static __inline__ char * |
||
206 | rpc_qname(struct rpc_wait_queue *q) |
||
207 | { |
||
208 | return q->name? q->name : "unknown"; |
||
209 | } |
||
210 | #endif |
||
211 | |||
212 | #endif /* _LINUX_SUNRPC_SCHED_H_ */ |