Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[K32W] Fix memory allocation #5242

Merged
merged 3 commits into from
Mar 12, 2021
Merged

[K32W] Fix memory allocation #5242

merged 3 commits into from
Mar 12, 2021

Conversation

doru91
Copy link
Contributor

@doru91 doru91 commented Mar 9, 2021

We had to fix the alloc/free pointers because OpenThread API changed.

Signed-off-by: Doru Gucea doru-cristian.gucea@nxp.com

@CLAassistant
Copy link

CLAassistant commented Mar 9, 2021

CLA assistant check
All committers have signed the CLA.

@@ -65,6 +65,8 @@ extern "C" void main_task(void const * argument)
(*pFunc)();
}

mbedtls_platform_set_calloc_free(otPlatCAlloc, otPlatFree);
Copy link
Contributor

@tcarmelveilleux tcarmelveilleux Mar 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why go through otPlatCalloc/otPlatFree? The mbedtls library should use whatever this platform's allocator is, and not rely on implementations from OpenThread, which, as it stands, are no longer supported to be called outside of OpenThread IIUC.

Suggested change
mbedtls_platform_set_calloc_free(otPlatCAlloc, otPlatFree);
mbedtls_platform_set_calloc_free(pvPortCallocRtos, vPortFree);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought malloc/calloc/free (and new/delete) are automatically mapped by FreeRTOS to the port calls.

What makes mbedtls require manual setting of the platform callbacks? Also for sure wondering why we move to ot (guessing openthread prefix) as an intermediate.

Copy link
Member

@jmartinez-silabs jmartinez-silabs Mar 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we use CHIPPlatformMemoryCalloc and CHIPPlatformMemoryFree as defined in src/lib/support/CHIPPlatformMemory.cpp

You can also map otPlatCAlloc and otPlatFree to use those too so it is consistent across the project

Copy link
Contributor Author

@doru91 doru91 Mar 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the call to mbedtls_platform_set_calloc_free(pvPortCallocRtos, vPortFree) as suggested by @tcarmelveilleux.

If I use CHIPPlatformMemoryCalloc then a call to malloc is done internally and I'm not sure if this is redirected to FreeRTOS pvPortMalloc.

Copy link
Contributor Author

@doru91 doru91 Mar 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Below is the pvPortMalloc function from heap3.c (FreeRTOS). In addition to calling malloc is also do some task related processing. So I believe that it's not safe to call directly CHIPPlatformMemoryCalloc instead of pvPortMalloc.

void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn;

	vTaskSuspendAll();
	{
		pvReturn = malloc( xWantedSize );
		traceMALLOC( pvReturn, xWantedSize );
	}
	( void ) xTaskResumeAll();

	#if( configUSE_MALLOC_FAILED_HOOK == 1 )
	{
		if( pvReturn == NULL )
		{
			extern void vApplicationMallocFailedHook( void );
			vApplicationMallocFailedHook();
		}
	}
	#endif

	return pvReturn;
}

Copy link
Contributor

@tcarmelveilleux tcarmelveilleux Mar 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few points here:

  • CHIPPlatformMemoryCalloc calls chip::platform::MemoryCalloc() which calls calloc().
  • pvPortMalloc on FreeRTOS, needs to be tied to replace the C/C++ library malloc, so that you don't have 2 heaps: FreeRTOS and C library "leftover linker space" in the linker script as an untracked heap. The other reason it needs to be replaced is that pvPortMalloc does the necessary processing to make malloc concurrency-safe on FreeRTOS.

It is odd to me that these allocators (e.g. chip::platform::MemoryCalloc()) are using global functions scoping and end-up calling C library, which is what you are trying to defeat by directly calling pvPortCallocRtos/vPortFree in other places. It means there is an expectation that all platforms override core malloc/calloc/free and that these remain callable. That's OK, I just didn't know about that assumption not being handled yet on your platform.

I agree with @andy31415 that a core expectation it seems is that C library malloc/calloc/free are redirected to a platform version rather than using whatever heap allocated is built-in to your C standard library.

Comment on lines 82 to 90
void * otPlatCAlloc(size_t aNum, size_t aSize)
{
return pvPortCallocRtos(aNum, aSize);
}

void otPlatFree(void * aPtr)
{
return vPortFree(aPtr);
}
Copy link
Contributor

@tcarmelveilleux tcarmelveilleux Mar 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really OpenThread-specific (like the ot prefix implies)? If so, why is it in *MbedtlsUtils.c ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, the naming is not correct. I moved otPlatCAlloc and otPlatFree to src/platform/K32W/ThreadStackManagerImpl.cpp.

return p;
}

extern "C" void * otPlatCAlloc(size_t aNum, size_t aSize)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are the otPlatCAlloc/otPlatFree methods still needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are still needed because I want OT to use the memory allocator from FreeRTOS.


extern "C" void * pvPortCallocRtos(size_t num, size_t size)
{
size_t totalAllocSize = (size_t)(num * size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This arithmetic is not always correct. calloc should fail if the multiplication overflows.

Please use C++ style casts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any suggestion on how to do it using C++ style casts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need a cast.

To check for overflow you can use division.

totalAllocSize = num * size;
if (size && totalAllocSize / size != num)
  return nullptr;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, pushed this fix!

@doru91
Copy link
Contributor Author

doru91 commented Mar 11, 2021

I don't know why the QEMU/ESP32 build is failing as this PR doesn't touch any ESP32 related files.

@bzbarsky-apple
Copy link
Contributor

I don't know why the QEMU/ESP32 build is failing as this PR doesn't touch any ESP32 related files.

Is the PR rebased to tip of master? If not, that might help; there was some sort of QEMU failure sometime last week, iirc.

doru91 and others added 3 commits March 11, 2021 23:20
We had to fix the alloc/free pointers because OpenThread API changed.

Signed-off-by: Doru Gucea <doru-cristian.gucea@nxp.com>
Signed-off-by: Doru Gucea <doru-cristian.gucea@nxp.com>
@doru91
Copy link
Contributor Author

doru91 commented Mar 12, 2021

I don't know why the QEMU/ESP32 build is failing as this PR doesn't touch any ESP32 related files.

Is the PR rebased to tip of master? If not, that might help; there was some sort of QEMU failure sometime last week, iirc.

OK, I just rebased, let's see if the issue is solved. L.E.: It was solved.

Copy link
Contributor

@LuDuda LuDuda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@andy31415 andy31415 merged commit 18b484f into project-chip:master Mar 12, 2021
doru91 added a commit to doru91/connectedhomeip that referenced this pull request Mar 17, 2021
* [K32W] Fix memory allocation

We had to fix the alloc/free pointers because OpenThread API changed.

Signed-off-by: Doru Gucea <doru-cristian.gucea@nxp.com>

* Restyled by clang-format

* [K32W] Fix possible buffer overflow

Signed-off-by: Doru Gucea <doru-cristian.gucea@nxp.com>

Co-authored-by: Restyled.io <commits@restyled.io>
andy31415 pushed a commit that referenced this pull request Mar 19, 2021
* [K32W] Fix memory allocation

We had to fix the alloc/free pointers because OpenThread API changed.

Signed-off-by: Doru Gucea <doru-cristian.gucea@nxp.com>

* Restyled by clang-format

* [K32W] Fix possible buffer overflow

Signed-off-by: Doru Gucea <doru-cristian.gucea@nxp.com>

Co-authored-by: Restyled.io <commits@restyled.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.