Changeset 6caf5fb in mainline for kernel/generic/src/cap/cap.c
- Timestamp:
- 2025-01-16T21:42:15Z (20 hours ago)
- Parents:
- e0e2264 (diff), 455241b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2025-01-16 21:42:15)
- git-committer:
- GitHub <noreply@…> (2025-01-16 21:42:15)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/cap/cap.c
re0e2264 r6caf5fb 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; 99 static slab_cache_t *kobject_cache;100 99 101 100 kobject_ops_t *kobject_ops[KOBJECT_TYPE_MAX] = { … … 125 124 } 126 125 126 static void caps_remove_callback(ht_link_t *item) 127 { 128 cap_t *cap = hash_table_get_inst(item, cap_t, caps_link); 129 130 if (cap->kobject) { 131 kobject_t *kobj = cap->kobject; 132 133 mutex_lock(&kobj->caps_list_lock); 134 cap->kobject = NULL; 135 list_remove(&cap->kobj_link); 136 mutex_unlock(&kobj->caps_list_lock); 137 138 kobject_put(kobj); 139 } 140 141 list_remove(&cap->type_link); 142 143 slab_free(cap_cache, cap); 144 } 145 127 146 static const hash_table_ops_t caps_ops = { 128 147 .hash = caps_hash, 129 148 .key_hash = caps_key_hash, 130 .key_equal = caps_key_equal 149 .key_equal = caps_key_equal, 150 .remove_callback = caps_remove_callback, 131 151 }; 132 152 … … 135 155 cap_cache = slab_cache_create("cap_t", sizeof(cap_t), 0, NULL, 136 156 NULL, 0); 137 kobject_cache = slab_cache_create("kobject_t", sizeof(kobject_t), 0,138 NULL, NULL, 0);139 157 } 140 158 … … 148 166 if (!task->cap_info) 149 167 return ENOMEM; 168 169 if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops)) { 170 free(task->cap_info); 171 return ENOMEM; 172 } 173 174 mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE); 175 176 task->cap_info->handles = NULL; 177 178 for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++) 179 list_initialize(&task->cap_info->type_list[t]); 180 181 return EOK; 182 } 183 184 /** Initialize the capability info structure 185 * 186 * @param task Task for which to initialize the info structure. 187 */ 188 errno_t caps_task_init(task_t *task) 189 { 190 assert(task->cap_info); 191 assert(!task->cap_info->handles); 192 150 193 task->cap_info->handles = ra_arena_create(); 151 194 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; 195 return ENOMEM; 196 197 if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE)) { 198 ra_arena_destroy(task->cap_info->handles); 199 return ENOMEM; 200 } 201 157 202 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); 203 } 204 205 void caps_task_clear(task_t *task) 206 { 207 mutex_lock(&task->cap_info->lock); 208 209 hash_table_clear(&task->cap_info->caps); 210 211 if (task->cap_info->handles) { 212 ra_arena_destroy(task->cap_info->handles); 213 task->cap_info->handles = NULL; 214 } 173 215 174 216 for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++) 175 217 list_initialize(&task->cap_info->type_list[t]); 218 219 mutex_unlock(&task->cap_info->lock); 176 220 } 177 221 … … 183 227 { 184 228 hash_table_destroy(&task->cap_info->caps); 185 ra_arena_destroy(task->cap_info->handles); 229 230 if (task->cap_info->handles) 231 ra_arena_destroy(task->cap_info->handles); 232 186 233 free(task->cap_info); 187 234 } … … 300 347 cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj) 301 348 { 349 mutex_lock(&task->cap_info->lock); 302 350 mutex_lock(&kobj->caps_list_lock); 303 mutex_lock(&task->cap_info->lock);304 351 cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED); 305 352 assert(cap); … … 309 356 list_append(&cap->kobj_link, &kobj->caps_list); 310 357 list_append(&cap->type_link, &task->cap_info->type_list[kobj->type]); 311 mutex_unlock(&task->cap_info->lock);312 358 mutex_unlock(&kobj->caps_list_lock); 359 mutex_unlock(&task->cap_info->lock); 313 360 } 314 361 … … 340 387 kobject_t *kobj = NULL; 341 388 342 restart:343 389 mutex_lock(&task->cap_info->lock); 344 390 cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED); … … 347 393 /* Hand over cap's reference to kobj */ 348 394 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 } 395 396 mutex_lock(&kobj->caps_list_lock); 354 397 cap_unpublish_unsafe(cap); 355 398 mutex_unlock(&kobj->caps_list_lock); … … 376 419 { 377 420 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); 421 422 while (!list_empty(&kobj->caps_list)) { 423 cap_t *cap = list_get_instance(list_first(&kobj->caps_list), cap_t, kobj_link); 424 425 /* We're trying to acquire the two locks in reverse order. */ 426 if (mutex_trylock(&cap->task->cap_info->lock) != EOK) { 427 mutex_unlock(&kobj->caps_list_lock); 428 mutex_lock(&kobj->caps_list_lock); 429 continue; 430 } 431 381 432 cap_unpublish_unsafe(cap); 382 433 /* Drop the reference for the unpublished capability */ 383 434 kobject_put(kobj); 435 384 436 mutex_unlock(&cap->task->cap_info->lock); 385 437 } 438 386 439 mutex_unlock(&kobj->caps_list_lock); 387 440 } … … 404 457 hash_table_remove_item(&task->cap_info->caps, &cap->caps_link); 405 458 ra_free(task->cap_info->handles, cap_handle_raw(handle), 1); 406 slab_free(cap_cache, cap); 407 mutex_unlock(&task->cap_info->lock); 408 } 409 410 kobject_t *kobject_alloc(unsigned int flags) 411 { 412 return slab_alloc(kobject_cache, flags); 413 } 414 415 void kobject_free(kobject_t *kobj) 416 { 417 slab_free(kobject_cache, kobj); 459 mutex_unlock(&task->cap_info->lock); 418 460 } 419 461 … … 422 464 * @param kobj Kernel object to initialize. 423 465 * @param type Type of the kernel object. 424 * @param raw Raw pointer to the encapsulated object. 425 */ 426 void kobject_initialize(kobject_t *kobj, kobject_type_t type, void *raw) 427 { 428 atomic_store(&kobj->refcnt, 1); 466 */ 467 void kobject_initialize(kobject_t *kobj, kobject_type_t type) 468 { 469 refcount_init(&kobj->refcnt); 429 470 430 471 mutex_initialize(&kobj->caps_list_lock, MUTEX_PASSIVE); … … 432 473 433 474 kobj->type = type; 434 kobj->raw = raw;435 475 } 436 476 … … 455 495 if (cap->kobject->type == type) { 456 496 kobj = cap->kobject; 457 atomic_inc(&kobj->refcnt);497 refcount_up(&kobj->refcnt); 458 498 } 459 499 } … … 469 509 void kobject_add_ref(kobject_t *kobj) 470 510 { 471 atomic_inc(&kobj->refcnt);511 refcount_up(&kobj->refcnt); 472 512 } 473 513 … … 481 521 void kobject_put(kobject_t *kobj) 482 522 { 483 if (atomic_postdec(&kobj->refcnt) == 1) { 484 KOBJECT_OP(kobj)->destroy(kobj->raw); 485 kobject_free(kobj); 523 if (refcount_down(&kobj->refcnt)) { 524 KOBJECT_OP(kobj)->destroy(kobj); 486 525 } 487 526 }
Note:
See TracChangeset
for help on using the changeset viewer.