ipc: remove unnecessary comp_driver_list spinlock#10861
Conversation
There was a problem hiding this comment.
Pull request overview
This PR removes the local IRQ disable/enable section from ipc4_search_for_drv() in the IPC4 helper, based on the assumption that IPC handling is serialized and cannot race with driver registration.
Changes:
- Removed
irq_local_disable()/irq_local_enable()and the associatedflagsvariable fromipc4_search_for_drv(). - Left UUID-based driver lookup otherwise unchanged.
| struct comp_driver_list *drivers = comp_drivers_get(); | ||
| struct list_item *clist; | ||
| const struct comp_driver *drv = NULL; | ||
| struct comp_driver_info *info; | ||
| uint32_t flags; | ||
|
|
There was a problem hiding this comment.
The old code did not protect against multicore case as it only disabled local interrupts. In any case, IPC processing is seriealized towards the host and even if IPC handling is on another core. So protection is simply not needed here access to drivers list is only triggered via IPC messages and IPC processing is serialized.
| irq_local_disable(flags); | ||
|
|
||
| /* search driver list with UUID */ | ||
| list_for_item(clist, &drivers->list) { |
There was a problem hiding this comment.
looking at other locations, where the driver list is manipulated, we find 3 cases in component.c in functions like comp_register(). And there the list is protected by a dedicated spin-lock (as is the right way to do that). But if we now decide that it needs no protection, maybe we can remove those too. Or maybe make ipc4_get_comp_drv() a syscall and have it take this lock too?
There was a problem hiding this comment.
Perhaps @lyakh but this PR is still valid, right?
There was a problem hiding this comment.
Perhaps @lyakh but this PR is still valid, right?
@kv2019i sorry, but I tend to reason "no." It is the same driver list, so locking it on one flow and not locking it at another one doesn't seem correct. At the very least I'd put next to one or more of these locations a huge red warning, but those tend to be left unaddressed for years...
There was a problem hiding this comment.
Fair enough, back to draft, I study other options.
There was a problem hiding this comment.
Now removed the lock from all places (in V2 patchset pushed today).
Drop the IRQ disable/enable in ipc4_search_for_drv(). The driver list is only modified at FW boot and when a new driver is registered at runtime via SOF_IPC4_GLB_LOAD_LIBRARY IPC. ipc4_search_for_drv() is only used when processing IPC messages. As IPC processing is serialized, it is not possible for the driver list to be modified concurrently with a call to ipc4_search_for_drv(). Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
The component driver list is only modified at FW boot and at runtime when a library is loaded. At boot, module init runs serially on the primary core (Zephyr SYS_INIT at APPLICATION level, before secondary cores are started; .initcall walked on a single core for XTOS). At runtime, registration happens from the IPC thread, which is serialized with only one command processed at a time. These two phases never overlap, as IPC message processing only begins after boot completes, so the list can never be modified concurrently. The lock was also already incoherent: comp_set_adapter_ops() iterate the list without holding the lock, so it provided no real mutual exclusion. Drop the spinlock from comp_register() and comp_unregister(), and from the UUID search in the IPC3 get_drv() reader. Remove the now-unused lock field from struct comp_driver_list and its initialization. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
683ec6d to
4fcddd7
Compare
|
V2 pushed:
|
lyakh
left a comment
There was a problem hiding this comment.
ok, so we are implying that we never traverse the driver list from the streaming context, during audio processing? I think this is most likely the case, but just making sure we aren't missing something
Drop the IRQ disable/enable in ipc4_search_for_drv(). The driver list is only modified at FW boot and when a new driver is registered at runtime via SOF_IPC4_GLB_LOAD_LIBRARY IPC. ipc4_search_for_drv() is only used when processing IPC messages. As IPC processing is serialized, it is not possible for the driver list to be modified concurrently with a call to ipc4_search_for_drv().