| .. | .. |
|---|
| 176 | 176 | complete(&wq->worker_done); |
|---|
| 177 | 177 | } |
|---|
| 178 | 178 | |
|---|
| 179 | +bool io_wq_worker_stopped(void) |
|---|
| 180 | +{ |
|---|
| 181 | + struct io_worker *worker = current->pf_io_worker; |
|---|
| 182 | + |
|---|
| 183 | + if (WARN_ON_ONCE(!io_wq_current_is_worker())) |
|---|
| 184 | + return true; |
|---|
| 185 | + |
|---|
| 186 | + return test_bit(IO_WQ_BIT_EXIT, &worker->wqe->wq->state); |
|---|
| 187 | +} |
|---|
| 188 | + |
|---|
| 179 | 189 | static void io_worker_cancel_cb(struct io_worker *worker) |
|---|
| 180 | 190 | { |
|---|
| 181 | 191 | struct io_wqe_acct *acct = io_wqe_get_acct(worker); |
|---|
| .. | .. |
|---|
| 513 | 523 | |
|---|
| 514 | 524 | static bool io_flush_signals(void) |
|---|
| 515 | 525 | { |
|---|
| 516 | | - if (unlikely(test_thread_flag(TIF_NOTIFY_SIGNAL))) { |
|---|
| 526 | + if (test_thread_flag(TIF_NOTIFY_SIGNAL) || current->task_works) { |
|---|
| 517 | 527 | __set_current_state(TASK_RUNNING); |
|---|
| 518 | 528 | tracehook_notify_signal(); |
|---|
| 519 | 529 | return true; |
|---|
| .. | .. |
|---|
| 1217 | 1227 | |
|---|
| 1218 | 1228 | worker = container_of(cb, struct io_worker, create_work); |
|---|
| 1219 | 1229 | io_worker_cancel_cb(worker); |
|---|
| 1230 | + /* |
|---|
| 1231 | + * Only the worker continuation helper has worker allocated and |
|---|
| 1232 | + * hence needs freeing. |
|---|
| 1233 | + */ |
|---|
| 1234 | + if (cb->func == create_worker_cont) |
|---|
| 1235 | + kfree(worker); |
|---|
| 1220 | 1236 | } |
|---|
| 1221 | 1237 | } |
|---|
| 1222 | 1238 | |
|---|