-
Notifications
You must be signed in to change notification settings - Fork 349
[RFC] Implement APIs for coherent access of shared objects #4702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
plbossart
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am pretty sure I missed the big picture here, this isn't straightforward to review...
| * audio component buffer - connects 2 audio components together in pipeline. | ||
| * | ||
| * The buffer is a hot structure that must be shared on certain cache | ||
| * incoherent architectures. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't there be some property that actually checks if the buffer will be used between two cores? What happens in the typical case where the entire pipeline runs on one core? then all this cache coherency is not really needed except for DMA buffers, is it?
Put differently, is the multi-core support going to impact or possible cripple performance when chaining processing on a single core?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minimal impact for non shared objects - we still check the c->shared flag, so lock and cache ops are only performed on objects used by multiple cores.
__must_check static inline struct coherent *coherent_acquire(struct coherent *c,
const size_t size)
{
/* assert if someone passes a cache/local address in here. */
ADDR_IS_COHERENT(c);
/* this flavour should not be used in IRQ context */
CHECK_COHERENT_IRQ(c);
/* access the shared coherent object */
if (c->shared) {
CHECK_COHERENT_CORE(c);
spin_lock(&c->lock);
/* invalidate local copy */
dcache_invalidate_region(uncache_to_cache(c), size);
}
/* client can now use cached object safely */
return uncache_to_cache(c);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
concening @plbossart's remark on DMA use-cases: is this API actually supposed to be used for DMA memory too? Don't think it's well suited for that, since spinlocks don't protect against DMA. And I'm not sure why we'd need the Kconfig option then?
src/audio/crossover/crossover.c
Outdated
| if (!sinks[i]) | ||
| continue; | ||
| buffer_writeback(sinks[i], sinks_bytes[i]); | ||
| sinks[i] = buffer_release(sinks[i]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's rather unclear to me when a writeback is explicitly required and when it's handled by the release?
src/audio/mixer.c
Outdated
| sink_bytes = frames * audio_stream_frame_bytes(&sink->stream); | ||
|
|
||
| sink = buffer_release(sink); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so that one has no invalidate for the sources?
src/audio/mixer.c
Outdated
|
|
||
| audio_stream_set_zero(&sink->stream, sink_bytes); | ||
| buffer_writeback(sink, sink_bytes); | ||
| comp_update_buffer_produce(sink, sink_bytes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that one is super odd, you release before writing to tthe sink buffer?
lgirdwood
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've fixed build on all platforms - needs squashed and kconfig fix in lrg/topic/coherent_api
c0b2c4d to
d815821
Compare
Big picture is that we create a coherent object API so that
Further work would enhance this to support
|
|
"[DO NOT REVIEW YET]" ? |
Yes, please. still WIP and testing. I will remove the tag once it is ready for review |
d815821 to
5419e8b
Compare
f865cbf to
fdcc060
Compare
src/include/sof/audio/component.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like you have to make function parameters to struct comp_buffer **sink and struct comp_buffer **source to make sure the caller has valid pointers after function return, although in practice this has no effect
src/audio/host.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...or maybe buffer_release() shouldn't be __must_check or maybe even return void. Wouldn't it be cleaner to use a separate handle variable for an "acquired buffer" and keep buffer as a generic object reference. But if they're both of type struct buffer * this creates danger of mistakenly accessing the object via the buffer pointer. Or you could make a separate struct buffer_handle type for it, but then you'd have to change more... Thinking out loud
src/audio/host.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left-over
src/audio/pipeline/pipeline-graph.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also probably has to be **buffer and in all other similar cases
src/audio/pipeline/pipeline-params.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about making sure we don't have nested buffer_acquire() calls. So, maybe everywhere where a buffer is passed as a parameter it must be acquired by the caller?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nested will assert since the ptr alias being passed in will change..
src/ipc/ipc-helper.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't component buffer lists have to be protected? I still don't understand our design of component, buffer and other element sharing well enough, but it seems like it can be or become a problem? I see buffers are added to the lists in pipeline_connect() with just local interrupts disabled, but probably even with dynamic pipelines it cannot run simultaneously on different cores? Say, if you have a mixer, where one core is running a pipeline. Then an IPC is arriving to start a pipeline on another core with the same mixer, so that core tries to add a buffer to its list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The coherent list iterator is needed and is a subsequent PR.
fdcc060 to
db1b9da
Compare
|
SOFCI TEST |
|
@ranj063 fwiw, the internal CI failures are all on TplgPipeComplete IPC after the first iteration with the multicore enabled in CI (so this may mean the multicore is not enabled in the Kconfig - and hence the failure) |
|
@ranj063 what I Mean is the KConfig say multicore and teh topology says multicore, but coherent APi probably says unicore. |
|
So the outstanding review comments are minor styling and could be fixed in a subsequent PR. |
Certain data structures such as buffers, pipelines, comp_dev's
are used across cores and cache boundaries. Introduce APIs
to handle cached access to such objects by stipulating that
the lock is held during access and releasing the lock after.
For example:
/* uncached work */
if (buffer->flag == somevalue)
do this;
/* cached work */
buffer = coherent_acquire(buffer);
buffer->state = true;
/* back to uncached */
buffer = coherent_release(buffer);
Also, add a new kconfig INCOHERENT which will need to ibe set for platforms that
need software-managed coherency.
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Buffer are shared hot data structures that are used across core and cache boundaries. Manage cached buffer access by stipulating that cached access is granted by holding the buffer lock (which invalidates) and releasing the lock (invalidates and writeback). Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com> Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock() which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock() which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock() which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock() which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock() which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock() which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock() which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock() which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock() which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer lock/unlock which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock which will be deprecated Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock which will be deprecated Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock() which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock which will be deprecated. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer_lock/unlock which will be deprecated Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
instead of buffer lock/unlock which will be deprecated Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
all users replaced with buffer_acquire/release Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
With the addition of struct coherent member in struct buffer, the size of the struct exceeds 128 bytes. Increase the 256 block heap size and reduce the 128 block size to fix out of memory issues when running multiple-pipeline-all test. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
ca2a468 to
6b82d00
Compare
|
PR passed after rerun. |
|
SOFCI TEST |
|
CI showing a timeout on CML where the script was killed before it completed. |
src/include/sof/coherent.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ehm, not sure __coherent is a good name for it. It does nothing for coherency. I understand that it's used for coherency, but to me it sounds as if it could provide coherency. Also why packed?
src/include/sof/coherent.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry for late comments... Thinking about the name of coherent_acquire() - we are returning a cached alias, so it is incoherent actually. It's protected in software, yes, but that doesn't make it coherent...
src/include/sof/coherent.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at some later time when we use lockdep, we might want to define __acquires() similar to the kernel...
src/include/sof/coherent.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want to still use mixed cached / uncached access if CONFIG_INCOHERENT is disabled? Wouldn't it be possible and desirable to always use cached addresses in such cases?
src/audio/buffer.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to assign
src/audio/buffer.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
| * audio component buffer - connects 2 audio components together in pipeline. | ||
| * | ||
| * The buffer is a hot structure that must be shared on certain cache | ||
| * incoherent architectures. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
concening @plbossart's remark on DMA use-cases: is this API actually supposed to be used for DMA memory too? Don't think it's well suited for that, since spinlocks don't protect against DMA. And I'm not sure why we'd need the Kconfig option then?
src/include/sof/audio/buffer.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also here - it looks like all these methods aren't used for DMA handling
src/include/sof/coherent.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait, above you just asserted, that object is an uncached alias. And now you're using it for cache manipulation? Besides, if someone passes you an uncached object, doesn't it mean that there can be no stale cached data for it? Then why writing back its cache? Same in other similar locations
|
This topic is being revisited in: |
No description provided.