Changeset fa3ed5b in mainline
- Timestamp:
- 2025-01-16T17:27:32Z (28 hours ago)
- Children:
- df721df
- Parents:
- 96368f56
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2025-01-16 14:30:47)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2025-01-16 17:27:32)
- Location:
- kernel/generic
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/cap/cap.h
r96368f56 rfa3ed5b 130 130 extern errno_t caps_task_alloc(struct task *); 131 131 extern void caps_task_free(struct task *); 132 extern void caps_task_init(struct task *); 132 extern void caps_task_clear(struct task *task); 133 extern errno_t caps_task_init(struct task *); 133 134 extern bool caps_apply_to_kobject_type(struct task *, kobject_type_t, 134 135 bool (*)(cap_t *, void *), void *); -
kernel/generic/src/cap/cap.c
r96368f56 rfa3ed5b 93 93 94 94 #define CAPS_START ((intptr_t) CAP_NIL + 1) 95 #define CAPS_ SIZE (INT_MAX - (int) CAPS_START)96 #define CAPS_ LAST (CAPS_SIZE -1)95 #define CAPS_LAST ((intptr_t) INT_MAX - 1) 96 #define CAPS_SIZE (CAPS_LAST - CAPS_START + 1) 97 97 98 98 static slab_cache_t *cap_cache; … … 125 125 } 126 126 127 static void caps_remove_callback(ht_link_t *item) 128 { 129 cap_t *cap = hash_table_get_inst(item, cap_t, caps_link); 130 131 if (cap->kobject) { 132 kobject_t *kobj = cap->kobject; 133 134 mutex_lock(&kobj->caps_list_lock); 135 cap->kobject = NULL; 136 list_remove(&cap->kobj_link); 137 mutex_unlock(&kobj->caps_list_lock); 138 139 kobject_put(kobj); 140 } 141 142 list_remove(&cap->type_link); 143 144 slab_free(cap_cache, cap); 145 } 146 127 147 static const hash_table_ops_t caps_ops = { 128 148 .hash = caps_hash, 129 149 .key_hash = caps_key_hash, 130 .key_equal = caps_key_equal 150 .key_equal = caps_key_equal, 151 .remove_callback = caps_remove_callback, 131 152 }; 132 153 … … 148 169 if (!task->cap_info) 149 170 return ENOMEM; 171 172 if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops)) { 173 free(task->cap_info); 174 return ENOMEM; 175 } 176 177 mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE); 178 179 task->cap_info->handles = NULL; 180 181 for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++) 182 list_initialize(&task->cap_info->type_list[t]); 183 184 return EOK; 185 } 186 187 /** Initialize the capability info structure 188 * 189 * @param task Task for which to initialize the info structure. 190 */ 191 errno_t caps_task_init(task_t *task) 192 { 193 assert(task->cap_info); 194 assert(!task->cap_info->handles); 195 150 196 task->cap_info->handles = ra_arena_create(); 151 197 if (!task->cap_info->handles) 152 goto error_handles; 153 if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE)) 154 goto error_span; 155 if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops)) 156 goto error_span; 198 return ENOMEM; 199 200 if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE)) { 201 ra_arena_destroy(task->cap_info->handles); 202 return ENOMEM; 203 } 204 157 205 return EOK; 158 159 error_span: 160 ra_arena_destroy(task->cap_info->handles); 161 error_handles: 162 free(task->cap_info); 163 return ENOMEM; 164 } 165 166 /** Initialize the capability info structure 167 * 168 * @param task Task for which to initialize the info structure. 169 */ 170 void caps_task_init(task_t *task) 171 { 172 mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE); 206 } 207 208 void caps_task_clear(task_t *task) 209 { 210 mutex_lock(&task->cap_info->lock); 211 212 hash_table_clear(&task->cap_info->caps); 213 214 if (task->cap_info->handles) { 215 ra_arena_destroy(task->cap_info->handles); 216 task->cap_info->handles = NULL; 217 } 173 218 174 219 for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++) 175 220 list_initialize(&task->cap_info->type_list[t]); 221 222 mutex_unlock(&task->cap_info->lock); 176 223 } 177 224 … … 183 230 { 184 231 hash_table_destroy(&task->cap_info->caps); 185 ra_arena_destroy(task->cap_info->handles); 232 233 if (task->cap_info->handles) 234 ra_arena_destroy(task->cap_info->handles); 235 186 236 free(task->cap_info); 187 237 } … … 300 350 cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj) 301 351 { 352 mutex_lock(&task->cap_info->lock); 302 353 mutex_lock(&kobj->caps_list_lock); 303 mutex_lock(&task->cap_info->lock);304 354 cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED); 305 355 assert(cap); … … 309 359 list_append(&cap->kobj_link, &kobj->caps_list); 310 360 list_append(&cap->type_link, &task->cap_info->type_list[kobj->type]); 311 mutex_unlock(&task->cap_info->lock);312 361 mutex_unlock(&kobj->caps_list_lock); 362 mutex_unlock(&task->cap_info->lock); 313 363 } 314 364 … … 340 390 kobject_t *kobj = NULL; 341 391 342 restart:343 392 mutex_lock(&task->cap_info->lock); 344 393 cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED); … … 347 396 /* Hand over cap's reference to kobj */ 348 397 kobj = cap->kobject; 349 if (mutex_trylock(&kobj->caps_list_lock) != EOK) { 350 mutex_unlock(&task->cap_info->lock); 351 kobj = NULL; 352 goto restart; 353 } 398 399 mutex_lock(&kobj->caps_list_lock); 354 400 cap_unpublish_unsafe(cap); 355 401 mutex_unlock(&kobj->caps_list_lock); … … 376 422 { 377 423 mutex_lock(&kobj->caps_list_lock); 378 list_foreach_safe(kobj->caps_list, cur, hlp) { 379 cap_t *cap = list_get_instance(cur, cap_t, kobj_link); 380 mutex_lock(&cap->task->cap_info->lock); 424 425 while (!list_empty(&kobj->caps_list)) { 426 cap_t *cap = list_get_instance(list_first(&kobj->caps_list), cap_t, kobj_link); 427 428 /* We're trying to acquire the two locks in reverse order. */ 429 if (mutex_trylock(&cap->task->cap_info->lock) != EOK) { 430 mutex_unlock(&kobj->caps_list_lock); 431 mutex_lock(&kobj->caps_list_lock); 432 continue; 433 } 434 381 435 cap_unpublish_unsafe(cap); 382 436 /* Drop the reference for the unpublished capability */ 383 437 kobject_put(kobj); 438 384 439 mutex_unlock(&cap->task->cap_info->lock); 385 440 } 441 386 442 mutex_unlock(&kobj->caps_list_lock); 387 443 } … … 404 460 hash_table_remove_item(&task->cap_info->caps, &cap->caps_link); 405 461 ra_free(task->cap_info->handles, cap_handle_raw(handle), 1); 406 slab_free(cap_cache, cap);407 462 mutex_unlock(&task->cap_info->lock); 408 463 } -
kernel/generic/src/proc/task.c
r96368f56 rfa3ed5b 201 201 return NULL; 202 202 203 if (caps_task_init(task) != EOK) { 204 slab_free(task_cache, task); 205 return NULL; 206 } 207 203 208 refcount_init(&task->refcount); 204 209 … … 212 217 task->ucycles = 0; 213 218 task->kcycles = 0; 214 215 caps_task_init(task);216 219 217 220 task->ipc_info.call_sent = 0; … … 287 290 */ 288 291 as_release(task->as); 292 293 caps_task_clear(task); 289 294 290 295 slab_free(task_cache, task); -
kernel/generic/src/proc/thread.c
r96368f56 rfa3ed5b 445 445 ipc_cleanup(); 446 446 sys_waitq_task_cleanup(); 447 caps_task_clear(TASK); 447 448 LOG("Cleanup of task %" PRIu64 " completed.", TASK->taskid); 448 449 }
Note:
See TracChangeset
for help on using the changeset viewer.