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
xtensa/esp32: Fix the issue of WiFi internal malloc from PSRAM #2832
xtensa/esp32: Fix the issue of WiFi internal malloc from PSRAM #2832
Conversation
0367052
to
295e137
Compare
295e137
to
355ceed
Compare
355ceed
to
2dc0062
Compare
2dc0062
to
9a6d8a0
Compare
if (size == 0 || esp32_ptr_extram(ptr)) | ||
{ | ||
esp_free(ptr); | ||
return NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- size == 0 case is better to be left to kmm_realloc
- standard realloc is supposed to preserve the old memory in case of a failure. does this wifi_osi_funcs_t variant have a different semantics?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The size == 0 case means that the size of the new malloc is 0,
In the esp_realloc_internal processing of wifi_osi_funcs_t, you can refer to:
https://github.com/espressif/esp-idf/blob/master/components/heap/heap_caps.c#L318-L321
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the esp-idf implementation does not seem to free the given ptr
in case of error.
eg. https://github.com/espressif/esp-idf/blob/master/components/heap/heap_caps.c#L323-L327
it matches my expectation for realloc().
i guess this implementation should do the same.
unfortunately it seems ~impossible to implement it for !CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP case though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, as the heap management of NuttX and esp-idf is too different, this part of the modification is too big, now temporarily free the given ptr
in case of error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but doesn't it cause double-free sooner or later, as the library would think the ptr
still needs to be freed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe you can do something like the following instead of kmm_realloc. how do you think?
new_ptr = kmm_malloc(new_size);
if (esp32_ptr_extram(new_ptr)) {
kmm_free(new_ptr);
return NULL;
}
old_size = malloc_usable_size(old_ptr);
memcpy(new_ptr, old_ptr, min(old_size, new_size));
kmm_free(old_ptr);
return new_ptr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yamt The library will check ptr
and then free it, there is a risk of double-free and I also think the above code instead of kmm_realloc is more reasonable, I have modified it, thank you.
esp_free(ptr); | ||
return NULL; | ||
} | ||
|
||
return kmm_realloc(ptr, size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i guess you want to check esp32_ptr_extram on the result of kmm_realloc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to make sure that the old memory pointer is not in external RAM (PSRAM), although this is unlikely to happen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kmm_realloc
also needs to be checked by esp32_ptr_extram
, I have modified it, thank you for your reminder.
9a6d8a0
to
c2c67b6
Compare
@cwespressif is everything done? May we merge it now? |
@acassis I think it's OK, but I still need to wait to see if @yamt has any comments or suggestions ? |
if (size == 0 || esp32_ptr_extram(ptr)) | ||
{ | ||
esp_free(ptr); | ||
return NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the esp-idf implementation does not seem to free the given ptr
in case of error.
eg. https://github.com/espressif/esp-idf/blob/master/components/heap/heap_caps.c#L323-L327
it matches my expectation for realloc().
i guess this implementation should do the same.
unfortunately it seems ~impossible to implement it for !CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP case though.
} | ||
|
||
p = kmm_realloc(ptr, size); | ||
if (esp32_ptr_extram(ptr)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you mean p
, not ptr
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's p
, sorry for the mistake.
371563c
to
978c21e
Compare
@yamt do you have any more concerns? |
void *old_ptr = ptr; | ||
void *new_ptr = NULL; | ||
size_t old_size = 0; | ||
if (size == 0 || esp32_ptr_extram(old_ptr)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for size == 0
case, you should free ptr
.
i don't think you need to check esp32_ptr_extram(old_ptr). the old_ptr will be freed on successful realloc anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
978c21e
to
59a385f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. thank you
Summary
SPIRAM
is not DMA-capable, while WiFiinternal malloc
from heap must be DMA-capable, We must avoidinternal malloc
from the heap ofPSRAM
Impact
If WiFi
internal malloc
fromPSRAM
, it will cause the system block.Testing
ESP32