rp2: Run USB stack task exclusively from core 0.

The goal is to avoid a situation where core 1 is shut down while holding
the tinyusb spinlock, which could happen during soft reset if
mp_thread_deinit is called while core1 is running tud_task().

This also fixes a latent race where the two cores are competing to
decrement and compare `vm_hook_divisor` with no mem fence or atomic
protection -- only core0 will now do this.

Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
Jim Mussared 2022-06-29 14:40:41 +10:00 committed by Damien George
parent 158f1794e8
commit daff597753

View File

@ -238,7 +238,7 @@ extern const struct _mod_network_nic_type_t mod_network_nic_type_wiznet5k;
#define MICROPY_HW_USBDEV_TASK_HOOK extern void tud_task(void); tud_task(); #define MICROPY_HW_USBDEV_TASK_HOOK extern void tud_task(void); tud_task();
#define MICROPY_VM_HOOK_COUNT (10) #define MICROPY_VM_HOOK_COUNT (10)
#define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT; #define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT;
#define MICROPY_VM_HOOK_POLL if (--vm_hook_divisor == 0) { \ #define MICROPY_VM_HOOK_POLL if (get_core_num() == 0 && --vm_hook_divisor == 0) { \
vm_hook_divisor = MICROPY_VM_HOOK_COUNT; \ vm_hook_divisor = MICROPY_VM_HOOK_COUNT; \
MICROPY_HW_USBDEV_TASK_HOOK \ MICROPY_HW_USBDEV_TASK_HOOK \
} }
@ -250,7 +250,7 @@ extern const struct _mod_network_nic_type_t mod_network_nic_type_wiznet5k;
#define MICROPY_EVENT_POLL_HOOK_FAST \ #define MICROPY_EVENT_POLL_HOOK_FAST \
do { \ do { \
MICROPY_HW_USBDEV_TASK_HOOK \ if (get_core_num() == 0) { MICROPY_HW_USBDEV_TASK_HOOK } \
extern void mp_handle_pending(bool); \ extern void mp_handle_pending(bool); \
mp_handle_pending(true); \ mp_handle_pending(true); \
} while (0) } while (0)