Conversation
Signed-off-by: Prashit Vora <prashitvora2006@gmail.com>
b9f7bbb to
7f24633
Compare
|
Hi @fdesbiens, Could you approve the workflow runs for this PR? |
|
@fdesbiens could you review it ? i think its ready to merge. |
…reed Releasing the kernel stack ahead of the thread object made a failure of the kernel stack deallocation abort the thread object release. The thread had already been deleted at that point, so the thread object would have stayed allocated for the lifetime of the module. The thread object is now always released once the delete succeeds, and the kernel stack failure is reported only when it does not mask a thread object failure. Assisted-by: Copilot (Opus 5) <noreply@github.com>
|
Thanks for the detailed report and the QEMU reproduction, @prashit-vora. I confirmed the leak independently: Your fix is in the right place and the ordering is correct. The kernel stack is released only once I pushed one small follow-up commit to your branch rather than asking you for another round trip. In the original version, a failure of the kernel stack deallocation was assigned to Merging once CI is green. Thanks again for the clean investigation and the reproduction case. |
Thanks for explaining the follow-up change. Could you please clarify why the thread-object deallocation error is given priority if both deallocations fail? I’d like to better understand the reasoning behind that choice. |
|
Good question, and it was a deliberate choice rather than an arbitrary one. The mechanical constraint is that the dispatcher has a single The main reason for picking the thread object is actionability. The thread control block is the object the caller passed in, so a failure to release it is something the module can actually observe and reason about: it still holds The second reason is backward compatibility of the error contract. Before this PR, the only status a module could ever receive from this path after a successful delete was the thread object deallocation status. Keeping that one in front means existing module error handling sees exactly what it saw before, and the kernel stack status is purely additive: it surfaces only in the new case where it is the sole failure. If we had let it take priority, we would have changed the value returned in a pre-existing failure mode, which is a subtler kind of break than the leak we were fixing. In practice the distinction is mostly theoretical, because both calls go through Worth adding that neither failure is unbounded in any case: |
Fixes #400.
User-mode module threads allocate a separate kernel stack from the module object pool. The thread-delete dispatcher freed the
TX_THREADobject but left that kernel stack allocated.This change releases the kernel stack after
_txe_thread_delete()succeeds and before releasing the thread object.Testing:
mps2-an385.tx_thread_create()returnedTX_NO_MEMORYafter 18 create/delete cycles.Temporary QEMU reproduction
QEMU results
NOTE: This was not tested on physical hardware.