00001
00012 #include <linux/aquosa/rres_config.h>
00013 #include "qres_config.h"
00014 #define QOS_DEBUG_LEVEL QRES_MOD_DEBUG_LEVEL
00015 #include <linux/aquosa/qos_debug.h>
00016
00017 #ifdef QRES_MOD_PROFILE
00018 # define QOS_PROFILE
00019 #endif
00020 #include <linux/aquosa/qos_prof.h>
00021
00022 #include "qres_gw_ks.h"
00023 #include "qsup_gw_ks.h"
00024 #include "qres_kpi_protected.h"
00025
00026 #include <linux/aquosa/qos_types.h>
00027 #include <linux/aquosa/qos_memory.h>
00028 #include <linux/aquosa/qos_func.h>
00029 #include <linux/aquosa/kal_sched.h>
00030
00035 static qos_rv find_task(pid_t pid, tid_t tid, struct task_struct **p_ptsk) {
00036 qos_chk_do(kal_atomic(), return QOS_E_INTERNAL_ERROR);
00037 if (pid != 0 && tid == 0)
00038 return QOS_E_INVALID_PARAM;
00039 if ((tid == 0) || (tid == current->pid)) {
00040 *p_ptsk = current;
00041 } else {
00042 *p_ptsk = kal_find_task_by_pid(tid);
00043 if (*p_ptsk == 0)
00044 return QOS_E_INVALID_PARAM;
00045 }
00046 return QOS_OK;
00047 }
00048
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00062 #define COPY_FROM_USER_TO(void_ptr, size, typed_ptr) do { \
00063 if ((size) != sizeof(*(typed_ptr))) { \
00064 qos_log_crit("Got %lu bytes, expecting %zu", \
00065 (size), sizeof(*(typed_ptr))); \
00066 return(QOS_E_INTERNAL_ERROR); \
00067 } \
00068 if (copy_from_user(typed_ptr, void_ptr, (size))) \
00069 return(QOS_E_INVALID_PARAM); \
00070 } while (0)
00071
00072 #define call_sync(func) ({ \
00073 kal_irq_state flags; \
00074 qos_rv __rv; \
00075 kal_spin_lock_irqsave(rres_get_spinlock(), &flags); \
00076 __rv = (func); \
00077 kal_spin_unlock_irqrestore(rres_get_spinlock(), &flags); \
00078 __rv; \
00079 })
00080
00081 qos_func_define(qos_rv, qres_gw_destroy_server, qres_sid_t sid) {
00082 qres_server_t *qres = qres_find_by_id(sid);
00083 if (qres == NULL)
00084 return QOS_E_NOT_FOUND;
00085 return qres_destroy_server(qres);
00086 }
00087
00088 qos_func_define(qos_rv, qres_gw_attach_task, qres_attach_iparams_t *iparams) {
00089 qres_server_t *qres;
00090 struct task_struct *tsk;
00091
00092 qos_chk_ok_ret(find_task(iparams->pid, iparams->tid, &tsk));
00093 qres = qres_find_by_id(iparams->server_id);
00094 if (qres == NULL)
00095 return QOS_E_NOT_FOUND;
00096 return qres_attach_task(qres, tsk);
00097 }
00098
00099 qos_func_define(qos_rv, qres_gw_detach_task, qres_attach_iparams_t *iparams) {
00100 qres_server_t *qres;
00101 struct task_struct *tsk;
00102
00103 qos_chk_ok_ret(find_task(iparams->pid, iparams->tid, &tsk));
00104 qres = qres_find_by_id(iparams->server_id);
00105 if (qres == NULL)
00106 return QOS_E_NOT_FOUND;
00107 return qres_detach_task(qres, tsk);
00108 }
00109
00110 qos_func_define(qos_rv, qres_gw_set_params, qres_iparams_t *iparams) {
00111 qres_server_t *qres;
00112
00113 qres = qres_find_by_id(iparams->server_id);
00114 if (qres == NULL)
00115 return QOS_E_NOT_FOUND;
00116 return qres_set_params(qres, &iparams->params);
00117 }
00118
00119 qos_func_define(qos_rv, qres_gw_get_params, qres_iparams_t *iparams) {
00120 qres_server_t *qres;
00121
00122 qres = qres_find_by_id(iparams->server_id);
00123 if (qres == NULL)
00124 return QOS_E_NOT_FOUND;
00125 return qres_get_params(qres, &iparams->params);
00126 }
00127
00133 qos_func_define(qos_rv, qres_gw_get_exec_time, qres_time_iparams_t *iparams) {
00134 qres_server_t *qres;
00135
00136 qres = qres_find_by_id(iparams->server_id);
00137 if (qres == NULL)
00138 return QOS_E_NOT_FOUND;
00139
00140 return qres_get_exec_abs_time(qres, &iparams->exec_time,
00141 &iparams->abs_time);
00142 }
00143
00144 qos_func_define(qos_rv, qres_gw_get_curr_budget, qres_time_iparams_t *iparams) {
00145 qres_server_t *qres;
00146
00147 qres = qres_find_by_id(iparams->server_id);
00148 if (qres == NULL)
00149 return QOS_E_NOT_FOUND;
00150
00151 iparams->exec_time = qres_get_curr_budget(qres);
00152 iparams->abs_time = 0;
00153
00154 return QOS_OK;
00155 }
00156
00157 qos_func_define(qos_rv, qres_gw_get_next_budget, qres_time_iparams_t *iparams) {
00158 qres_server_t *qres;
00159
00160 qres = qres_find_by_id(iparams->server_id);
00161 if (qres == NULL)
00162 return QOS_E_NOT_FOUND;
00163
00164 iparams->exec_time = qres_get_next_budget(qres);
00165 iparams->abs_time = 0;
00166
00167 return QOS_OK;
00168 }
00169
00170 qos_func_define(qos_rv, qres_gw_get_appr_budget, qres_time_iparams_t *iparams) {
00171 qres_server_t *qres;
00172
00173 qres = qres_find_by_id(iparams->server_id);
00174 if (qres == NULL)
00175 return QOS_E_NOT_FOUND;
00176
00177 iparams->exec_time = qres_get_appr_budget(qres);
00178 iparams->abs_time = 0;
00179
00180 return QOS_OK;
00181 }
00182
00183 qos_func_define(qos_rv, qres_gw_get_server_id, qres_attach_iparams_t *iparams) {
00184 server_t *rres;
00185 struct task_struct *tsk;
00186
00187 qos_chk_ok_ret(find_task(iparams->pid, iparams->tid, &tsk));
00188 qos_log_debug("Got tsk with: pid=%d, tgid=%d", tsk->pid, tsk->tgid);
00189 rres = rres_find_by_task(tsk);
00190 if (rres == NULL)
00191 return QOS_E_NOT_FOUND;
00192
00193 iparams->server_id = rres_get_sid(rres);
00194
00195 return QOS_OK;
00196 }
00197
00198 qos_func_define(qos_rv, qres_gw_get_deadline, qres_timespec_iparams_t *iparams) {
00199 qres_server_t *qres;
00200
00201 qres = qres_find_by_id(iparams->server_id);
00202 if (qres == NULL)
00203 return QOS_E_NOT_FOUND;
00204
00205 return qres_get_deadline(qres, &iparams->timespec);
00206 }
00207
00208 qos_func_define(qos_rv, qres_gw_set_weight, qres_weight_iparams_t *iparams) {
00209 qres_server_t *qres;
00210
00211 qres = qres_find_by_id(iparams->server_id);
00212 if (qres == NULL)
00213 return QOS_E_NOT_FOUND;
00214 if (iparams->weight == 0)
00215 return QOS_E_INVALID_PARAM;
00216 rres_set_weight(&qres->rres, iparams->weight);
00217 return QOS_OK;
00218 }
00219
00220 qos_func_define(qos_rv, qres_gw_get_weight, qres_weight_iparams_t *iparams) {
00221 qres_server_t *qres;
00222
00223 qres = qres_find_by_id(iparams->server_id);
00224 if (qres == NULL)
00225 return QOS_E_NOT_FOUND;
00226 iparams->weight = rres_get_weight(&qres->rres);
00227 return QOS_OK;
00228 }
00229
00262 qos_rv qres_gw_ks(qres_op_t op, void __user *up_iparams, unsigned long size) {
00263 union {
00264 qres_sid_t server_id;
00265 qres_iparams_t iparams;
00266 qres_attach_iparams_t attach_iparams;
00267 qres_time_iparams_t time_iparams;
00268 qres_timespec_iparams_t timespec_iparams;
00269 qres_weight_iparams_t weight_iparams;
00270 } u;
00271 qos_rv err = QOS_OK;
00272
00273 switch (op) {
00274 case QRES_OP_CREATE_SERVER:
00275 COPY_FROM_USER_TO(up_iparams, size, &u.iparams);
00276 err = call_sync(qres_create_server(&u.iparams.params, &u.iparams.server_id));
00277 if (err == QOS_OK && copy_to_user(up_iparams, &u.iparams, sizeof(qres_iparams_t)))
00278 err = QOS_E_INTERNAL_ERROR;
00279 break;
00280 case QRES_OP_GET_SERVER_ID:
00281 COPY_FROM_USER_TO(up_iparams, size, &u.attach_iparams);
00282 err = call_sync(qres_gw_get_server_id(&u.attach_iparams));
00283 if (err == QOS_OK && copy_to_user(up_iparams, &u.iparams, sizeof(qres_attach_iparams_t)))
00284 err = QOS_E_INTERNAL_ERROR;
00285 break;
00286 case QRES_OP_DESTROY_SERVER:
00287 COPY_FROM_USER_TO(up_iparams, size, &u.server_id);
00288 err = call_sync(qres_gw_destroy_server(u.server_id));
00289 break;
00290 case QRES_OP_ATTACH_TO_SERVER:
00291 COPY_FROM_USER_TO(up_iparams, size, &u.attach_iparams);
00292 err = call_sync(qres_gw_attach_task(&u.attach_iparams));
00293 break;
00294 case QRES_OP_DETACH_FROM_SERVER:
00295 COPY_FROM_USER_TO(up_iparams, size, &u.attach_iparams);
00296 err = call_sync(qres_gw_detach_task(&u.attach_iparams));
00297 break;
00298 case QRES_OP_SET_PARAMS:
00299 COPY_FROM_USER_TO(up_iparams, size, &u.iparams);
00300 err = call_sync(qres_gw_set_params(&u.iparams));
00301 break;
00302 case QRES_OP_GET_PARAMS:
00303 COPY_FROM_USER_TO(up_iparams, size, &u.iparams);
00304 err = call_sync(qres_gw_get_params(&u.iparams));
00305 if (err == QOS_OK && copy_to_user(up_iparams, &u.iparams, sizeof(qres_iparams_t)))
00306 err = QOS_E_INTERNAL_ERROR;
00307 break;
00308 case QRES_OP_GET_EXEC_TIME:
00309 COPY_FROM_USER_TO(up_iparams, size, &u.time_iparams);
00310 err = call_sync(qres_gw_get_exec_time(&u.time_iparams));
00311 if (err == QOS_OK && copy_to_user(up_iparams, &u.time_iparams, sizeof(qres_time_iparams_t)))
00312 err = QOS_E_INTERNAL_ERROR;
00313 break;
00314 case QRES_OP_GET_CURR_BUDGET:
00315 COPY_FROM_USER_TO(up_iparams, size, &u.time_iparams);
00316 err = call_sync(qres_gw_get_curr_budget(&u.time_iparams));
00317 if (err == QOS_OK && copy_to_user(up_iparams, &u.time_iparams, sizeof(qres_time_iparams_t)))
00318 err = QOS_E_INTERNAL_ERROR;
00319 break;
00320 case QRES_OP_GET_NEXT_BUDGET:
00321 COPY_FROM_USER_TO(up_iparams, size, &u.time_iparams);
00322 err = call_sync(qres_gw_get_next_budget(&u.time_iparams));
00323 if (err == QOS_OK && copy_to_user(up_iparams, &u.time_iparams, sizeof(qres_time_iparams_t)))
00324 err = QOS_E_INTERNAL_ERROR;
00325 break;
00326 case QRES_OP_GET_APPR_BUDGET:
00327 COPY_FROM_USER_TO(up_iparams, size, &u.time_iparams);
00328 err = call_sync(qres_gw_get_appr_budget(&u.time_iparams));
00329 if (err == QOS_OK && copy_to_user(up_iparams, &u.time_iparams, sizeof(qres_time_iparams_t)))
00330 err = QOS_E_INTERNAL_ERROR;
00331 break;
00332 case QRES_OP_GET_DEADLINE:
00333 COPY_FROM_USER_TO(up_iparams, size, &u.timespec_iparams);
00334 err = call_sync(qres_gw_get_deadline(&u.timespec_iparams));
00335 if (err == QOS_OK && copy_to_user(up_iparams, &u.time_iparams, sizeof(qres_timespec_iparams_t)))
00336 err = QOS_E_INTERNAL_ERROR;
00337 break;
00338 case QRES_OP_SET_WEIGHT:
00339 COPY_FROM_USER_TO(up_iparams, size, &u.weight_iparams);
00340 err = call_sync(qres_gw_set_weight(&u.weight_iparams));
00341 break;
00342 case QRES_OP_GET_WEIGHT:
00343 COPY_FROM_USER_TO(up_iparams, size, &u.weight_iparams);
00344 err = call_sync(qres_gw_set_weight(&u.weight_iparams));
00345 if (err == QOS_OK && copy_to_user(up_iparams, &u.weight_iparams, sizeof(qres_weight_iparams_t)))
00346 err = QOS_E_INTERNAL_ERROR;
00347 break;
00348 default:
00349 qos_log_err("Unhandled operation code");
00350 err = QOS_E_INTERNAL_ERROR;
00351 }
00352 qos_log_debug("Returning: %s", qos_strerror(err));
00353 return err;
00354 }