* The body of the task in charge of unloading autoloaded modules * that are not needed anymore. * Images can be cross-linked so we may need to make multiple passes, * but the time we spend in the loop is bounded because we clear entries * as we touch them. */
| 409 | * as we touch them. |
| 410 | */ |
| 411 | static void |
| 412 | unloadentry(void *unused1, int unused2) |
| 413 | { |
| 414 | struct priv_fw *fp; |
| 415 | int err; |
| 416 | |
| 417 | mtx_lock(&firmware_mtx); |
| 418 | restart: |
| 419 | LIST_FOREACH(fp, &firmware_table, link) { |
| 420 | if (fp->file == NULL || fp->refcnt != 0 || |
| 421 | (fp->flags & FW_UNLOAD) == 0) |
| 422 | continue; |
| 423 | |
| 424 | /* |
| 425 | * Found an entry. Now: |
| 426 | * 1. make sure we scan the table again |
| 427 | * 2. clear FW_UNLOAD so we don't try this entry again. |
| 428 | * 3. release the lock while trying to unload the module. |
| 429 | */ |
| 430 | fp->flags &= ~FW_UNLOAD; /* do not try again */ |
| 431 | |
| 432 | /* |
| 433 | * We rely on the module to call firmware_unregister() |
| 434 | * on unload to actually free the entry. |
| 435 | */ |
| 436 | mtx_unlock(&firmware_mtx); |
| 437 | err = linker_release_module(NULL, NULL, fp->file); |
| 438 | mtx_lock(&firmware_mtx); |
| 439 | |
| 440 | /* |
| 441 | * When we dropped the lock, another thread could have |
| 442 | * removed an element, so we must restart the scan. |
| 443 | */ |
| 444 | goto restart; |
| 445 | } |
| 446 | mtx_unlock(&firmware_mtx); |
| 447 | } |
| 448 | |
| 449 | /* |
| 450 | * Module glue. |
nothing calls this directly
no test coverage detected