[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 1/9] AMD/IOMMU: redo awaiting of command completion
On 09/06/2021 13:08, Jan Beulich wrote: > On 09.06.2021 12:36, Andrew Cooper wrote: >> On 09/06/2021 10:26, Jan Beulich wrote: >>> @@ -49,28 +52,31 @@ static void send_iommu_command(struct am >>> static void flush_command_buffer(struct amd_iommu *iommu, >>> unsigned int timeout_base) >>> { >>> + static DEFINE_PER_CPU(uint64_t, poll_slot); >>> + uint64_t *this_poll_slot = &this_cpu(poll_slot); >>> + paddr_t addr = virt_to_maddr(this_poll_slot); >>> uint32_t cmd[4]; >>> s_time_t start, timeout; >>> static unsigned int __read_mostly threshold = 1; >>> >>> - /* RW1C 'ComWaitInt' in status register */ >>> - writel(IOMMU_STATUS_COMP_WAIT_INT, >>> - iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); >>> - >>> - /* send an empty COMPLETION_WAIT command to flush command buffer */ >>> - cmd[3] = cmd[2] = 0; >>> - set_field_in_reg_u32(IOMMU_CMD_COMPLETION_WAIT, 0, >>> + ACCESS_ONCE(*this_poll_slot) = CMD_COMPLETION_INIT; >>> + >>> + /* send a COMPLETION_WAIT command to flush command buffer */ >>> + cmd[0] = addr; >>> + set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, cmd[0], >>> + IOMMU_COMP_WAIT_S_FLAG_MASK, >>> + IOMMU_COMP_WAIT_S_FLAG_SHIFT, &cmd[0]); >> set_field_in_reg_u32() is a disaster of a function - both in terms of >> semantics, and code gen - and needs to be purged from the code. > Long ago I had an item on my todo list to get this cleaned up. But > it never really having made it up high enough, I dropped it at > some point, in the hope that we'd manage to get this sorted while > re-writing code step by step. > >> It is a shame we don't have a real struct for objects in the command >> buffer, but in lieu of that, this is just >> >> cmd[0] = addr | IOMMU_COMP_WAIT_S_FLAG_MASK; >> >> which is the direction that previous cleanup has gone. > I don't think I can spot a single instance of such. It's actually the other way around, for the emulation logic (which isn't used in practice). drivers/passthrough/amd/iommu_guest.c:348 i = cmd->data[0] & IOMMU_COMP_WAIT_I_FLAG_MASK; > Some work was > done to introduce (mainly bitfield) structs, but this surely goes > too far for the change at hand. I can spot two instances using > MASK_INSR(), so I can see two consistent ways of doing what you > ask for: > > cmd[0] = addr | MASK_INSR(IOMMU_CONTROL_ENABLED, > IOMMU_COMP_WAIT_S_FLAG_MASK); > > keeping the name as *_MASK (and I'd be open to replace > IOMMU_CONTROL_ENABLED by true) or > > cmd[0] = addr | IOMMU_COMP_WAIT_S_FLAG; > > i.e. dropping _MASK (but requiring adjustments elsewhere in the > code). Please let me know which one you'd prefer. TBH, I'd suggest just using cmd[0] = addr | IOMMU_COMP_WAIT_S_FLAG_MASK; for now. The constant is correct - its just the name which is wonky. This in particular will reduce the code churn for ... >> There are no current users of IOMMU_COMP_WAIT_S_FLAG_SHIFT, and ... >> >>> + cmd[1] = addr >> 32; >>> + set_field_in_reg_u32(IOMMU_CMD_COMPLETION_WAIT, cmd[1], >>> IOMMU_CMD_OPCODE_MASK, >>> IOMMU_CMD_OPCODE_SHIFT, &cmd[1]); >>> - set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, 0, >>> - IOMMU_COMP_WAIT_I_FLAG_MASK, >>> - IOMMU_COMP_WAIT_I_FLAG_SHIFT, &cmd[0]); >> ... this drops the final use of IOMMU_COMP_WAIT_I_FLAG_SHIFT, so both >> should be dropped. > Well, I can surely do so, but like this entire request of yours this > feels like scope creep - there was no intention here to do any > unrelated cleanup. And if I remove _S_ and _I_, then surely _F_ > wants dropping as well, while IOMMU_COMP_WAIT_ADDR_*_SHIFT have a > use each in iommu_guest.c and hence need to stay for now. ... this, which I'm perfectly happy leaving to a subsequent change. (I'll even do it, if you're too busy right now). What I am mainly concerned with is not using this opportunity to remove uses of set_field_in_reg_u32(). > >> As for IOMMU_CMD_OPCODE_SHIFT, that can't be dropped yet, but it would >> still be better to use >> >> cmd[1] = (addr >> 32) | MASK_INSR(IOMMU_CMD_COMPLETION_WAIT, >> IOMMU_CMD_COMPLETION_WAIT); >> >> in the short term. > Can do (using IOMMU_CMD_OPCODE_MASK). Oops yes. That was a copy&paste mistake. ~Andrew
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |