scx_sub_enable_workfn() has several failure paths that only return an errno (e.g. -ENOMEM from an allocation) and jump to err_disable without calling scx_error(). scx_flush_disable_work() runs the disable, and thus ops.exit(), only when an error has been recorded, so an errno-only failure leaves the half-initialized sub-scheduler linked. Record an error at the err_disable sink so every errno-only failure runs the disable path.
Unified · Split
| @@ -7746,6 +7746,12 @@ err_unlock_and_disable: · 7745 unmodified lines | ||
| 7746 | 7746 | percpu_up_write(&scx_fork_rwsem); |
| 7747 | 7747 | err_disable: |
| 7748 | 7748 | mutex_unlock(&scx_enable_mutex); |
| 7749 | + /* | |
| 7750 | + * Some enable failures only return an errno (e.g. -ENOMEM from an | |
| 7751 | + * allocation) without calling scx_error(). Record it so | |
| 7752 | + * scx_flush_disable_work() runs the disable and ops.exit() fires. | |
| 7753 | + */ | |
| 7754 | + scx_error(sch, "scx_sub_enable() failed (%d)", ret); | |
| 7749 | 7755 | scx_flush_disable_work(sch); |
| 7750 | 7756 | cmd->ret = 0; |
| 7751 | 7757 | } |