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