Hey Arnd, On Wed, Jan 04, 2023 at 11:19:44AM +0100, Arnd Bergmann wrote: > On Wed, Jan 4, 2023, at 10:23, Conor Dooley wrote: > >>Right, no need to touch the existing file as part of this series, > >>it probably just gets in the way of defining a good interface here. > > > > Sure. Can leave it where it was & I'll sort it out later when it's > > errata etc get added. > > > > Btw, would you mind pointing out where you wanted to have that if/else > > you mentioned on IRC? > > I meant replacing both of the runtime patching indirections in > arch_sync_dma_for_device(). At the moment, this function calls > ALT_CMO_OP(), which is patched to either call the ZICBOM or the > THEAD variant, and if I read this right you add a third case > there with another level of indirection using static_branch. Yah, pretty much. > I would try to replace both of these indirections and instead > handle it all from C code in arch_sync_dma_for_device() directly, > for the purpose of readability and maintainability. > static inline void dma_cache_clean(void *vaddr, size_t size) > { > if (!cache_maint_ops.clean) > zicbom_cache_clean(vaddr, size, riscv_cbom_block_size); And I figure that this function is effectively a wrapper around ALT_CMO_OP()? > else > cache_maint_ops.clean(vaddr, size, riscv_cbom_block_size); And this one gets registered by the driver using an interface like the one I already proposed, just with the cache_maint_ops struct expanded? Extrapolating, with these changes having an errata would not even be needed in order to do cache maintenance. Since the ALT_CMO_OP() version would only be used inside zicbom_cache_clean(), assuming I understood correctly, a driver could just register cache_maint_ops for a given platform without having to muck around with errata. If so, that seems like a distinct improvement over my suggestion & gets around the thing I mentioned in 0/9 about a shared case in the alternative application code. Again, assuming I understood correctly, I like this a lot. > } > > void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, > enum dma_data_direction dir) > { > void *vaddr = phys_to_virt(paddr); > > switch (dir) { > case DMA_TO_DEVICE: > case DMA_FROM_DEVICE: > dma_cache_clean(vaddr, size); > break; > case DMA_BIDIRECTIONAL: > dma_cache_flush(vaddr, size); > break; > default: > break; > } > } > > which then makes it very clear what the actual code path > is, while leaving the zicbom case free of indirect function > calls. You can still use a static_branch() to optimize the > conditional, but I would try to avoid any extra indirection > levels or errata checks. The other thing that I like about this is we can then remove the various calls to ALT_CMO_OP() that are scattered around arch/riscv now & replace them with functions that have more understandable names. Thanks Arnd! Conor.