Hello,
hoping that someone can confirm that _mem_get_size() can incorrectly generate an MQX_INVALID_CHECKSUM error when preempted by a higher priority task which frees the previous block and has to coalesce the newly freed block with an already free block immediately before it. From _mem_get_size():
#if MQX_CHECK_VALIDITY
if ((!VALID_CHECKSUM(block_ptr))) {
kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR = block_ptr;
_task_set_error(MQX_INVALID_CHECKSUM);
return (0);
} /* Endif */
#endif
For the following memory block state:
Address 1 - Block A - Free
Address 2 - Block B - Allocated
Address 3 - Block C - Allocated
Sequence of operations:
1. Task L is active and calls _mem_get_size(Address 3)
2. While executing VALID_CHECKSUM calculation (after loading the PREVBLOCK address but before performing the CHECKSUM comparison), Task L is preempted by a higher priority Task H.
3. Task H calls _mem_free(Address 2), which needs to coalesce; _mem_check_coalesce_internal() changes Block C PREVBLOCK from Block B to Block A, and calculates and sets a new Block C CHECKSUM.
4. Task H finishes and Task L becomes active.
5. Task L finishes the VALID_CHECKSUM calculation on Block C but the calculated value was generated when PREVBLOCK pointed to Block B, and the CHECKSUM value was generated when PREVBLOCK pointed to Block A, resulting in an MQX_INVALID_CHECKSUM error.
So it looks to me like _mem_get_size() (_mem_transfer() too) should be wrapping the VALID_CHECKSUM calculation in INT_DISABLE/INT_ENABLE calls.
Thanks
Hi Matt:
It seems your issue is very similar to the mem driver bug fix in MQX 5.0
Please check the below release note for more details
https://www.nxp.com/docs/en/release-note/MQX_Release_Notes.pdf
Regards
Daniel
So I'll take that as a yes. i.e. This is a bug in MQX 4.2.
To squash this in MQX 4.2 we'll wrap it (VALID_CHECKSUM calculation) with INT_DISABLE/INT_ENABLE calls, unless there is a different recommended solution...