Skip to content

Upstream: address IPC tx/rx work necessity #580

Closed

Description

@keyonjie

To address comments from Mark:

"why can't we just immediately send the
message to the DSP from here, what's the benefit of scheduling some work
to do that? "

We need to remove tx/rx work from ipc struct, and call sending/receiving IPC function directly.

Activity

  1. changed the title [-]Upstream: address IPC tx/rx work necessarity[/-] [+]Upstream: address IPC tx/rx work necessity[/+] on Jan 23, 2019
  2. lyakh commented on Mar 1, 2019

    @lyakh
    Collaborator

    @plbossart Let's use this issue, since removing scheduled work is probably the most intrusive change of all proposed. Here's my analysis and a proposed transition:

    1. synchronous TX. Since every IPC transmission is anyway waiting for a reply,
      no need for work offloading. Instead sleep on a mutex, send, wait for reply.
      This will also make handling of simultaneous racing users explicit: they will
      be serialised by the mutex.

    2. synchronous RX. The FW always waits for the host to receive a message before
      sending the next one. DSP->Host messages can be of 3 types:

      1. replies. There must be exactly one reply to each Host->DSP message.
      2. panic messages.
      3. new message.
        (1) and (2) are processed immediately in the IRQ thread context, (3) is
        postponed to the scheduler work queue. Moving (3) to the IRQ thread would
        simplify the state machine, reduce latency, close a race window.

    1+2.
    That means, there is no need for .tx_list and .reply_list message queues,
    they can be replaced with just one pointer for the current message, waiting
    for a DSP response. We also don't need a list of empty messages, since we
    will only be processing one at a time. If a timeout is desired for sending, a
    timeout version can be created too.

    1. what happens if the Host and the DSP decide to send a message simultaneously?
      They both will check a "busy" flag and, if free, they will proceed with
      copying the data to the buffer and triggering an interrupt on the receiver
      side. This creates a race window. Mailbox windows are configured in FW in
      platform.c, Host and DSP windows are separate non-overlapping (verified only
      for cAVS) memory regions. Does simultaneously writing to initiator registers
      from the DSP and the Host sides work?

    2. snd_sof_dsp_is_ipc_ready() can be implemented using
      wait_event(_interruptible)(_timeout)(). Presumably if any of the HW busy
      flags is set, some processing - either sending or receiving - will be
      handling them, after which the event can be triggered. Since TX will be
      serialised, only an incoming RX message from the DSP can render the mailbox
      not ready. After RX processing completion the event would be toggled.
      However, Pierre explains, that not-ready is only produced by a TX in
      progress. If that's the case, snd_sof_dsp_is_ipc_ready() can simply be
      removed.

    3. for RPMsg compatibility, a callback-based sending can be added too. That
      version could use queued work, but maybe a dedicated work queue should be
      created. However, this doesn't seem like a major rework, therefore it can be
      left out for now.

    4. no need to search for a matching reply, no message ID is needed.

    5. no retry is needed with synchronous operation.

    6. writing cmd to shim: BDW and HSW don't do that. Again, it would be easier to
      limit upstreaming to HDA to begin with.

    7. page table fix:

    		u8 *pg_table;
    
    		if (i & 1)
    			put_unaligned_le32(pg_table[0] & 0xf | pfn << 4,
    					   pg_table);
    		else
    			put_unaligned_le32(pfn, pg_table);
    
    1. why are PM functions protected by a mutex? E.g. in sof_compressed_open(),
      sof_compressed_free(), sof_set_restore_stream().

    2. struct snd_sof_dev::ipc_lock has to be clarified. The comment "lock for IPC
      users" isn't very helpful. Maybe it can be completely replaced by a mutex.

    Proposed transition path:

    1. Currently the RX path has no locking. Explicit serialisation is also not
      required since it will be executed completely in IRQ thread context.
      Therefore it is safe to first eliminate the RX work.

    2. Add a mutex to sending, encompassing TX and waiting for a reply.

    3. Remove TX work

    4. Remove message lists

  3. plbossart commented on Mar 1, 2019

    @plbossart
    Member

    @lyakh: there's a ton of good info in there, but I am at a loss as to how to reply. GitHub is not a wiki or editable at will, it's just not productive to use this tool for an interactive design discussion. We might as well use Google Docs or something meant for collaborative editing.

  4. lyakh commented on Mar 18, 2019

    @lyakh
    Collaborator

    resolved by #695

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions