Skip to content
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

soundwire: stream: skip m_rt which is not in preparing stage #5246

Open
wants to merge 2 commits into
base: topic/sof-dev
Choose a base branch
from

Conversation

bardliao
Copy link
Collaborator

sdw_compute_group_params() will count payload bandwidth and it count all m_rt in the bus. The m_rt will be added to the bus by sdw_stream_add_master(). If 2 streams are opened simultaneously, the m_rt of the second stream will be counted when
sdw_compute_group_params() is counting the payload bandwidth of the first stream. Which is incorrect.
Set PREPARED state earlier so that sdw_compute_group_params() can skip the m_rt that is not in the preparing stage yet.

@@ -1456,15 +1464,15 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream,
if (ret < 0) {
dev_err(bus->dev, "Prepare port(s) failed ret = %d\n",
ret);
stream->state = state;
return ret;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why this is not jumping to restore_params?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't change bus->params at this point yet.

* the stream that is CONFIGURED and PREPARED and skip the stream that is CONFIGURED
* but not in the preparing stage.
*/
stream->state = SDW_STREAM_PREPARED;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in other patches we also moved the set to PREPARED state prior that we actually prepare things.

I got the reason and at the same time it sounds wrong to set something as PREPARED when it is not...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the stream->state may not represent the actual state perfectly. But, I can't find a better way to skip the m_rt that should not be counted yet. And stream->state is used by the stream helpers only and the helpers will be called one by one. So, I think it is safe to change the stream->state earlier in the same stream helper.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao this really seems like a hack or a workaround. Maybe the best thing to do would be to revisit the state machine so that we can gracefully skip the runtime thats not ready to be included yet?

@@ -189,6 +189,9 @@ static int sdw_compute_group_params(struct sdw_bus *bus,
}

list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
if (m_rt->stream->state < SDW_STREAM_PREPARED)
Copy link
Collaborator

@ranj063 ranj063 Nov 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the issue manifests because sdw_prepare_stream() looks at the m_rt associated with the stream but sdw_compute_group_params() looks at the bus->m_rt_list. Can you maybe filter this list in this function by passing the stream as an argument when called from sdw_prepare_stream()?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about that. sdw_compute_group_params() lools at the bus->m_rt_list is because it needs to calculate all the active stream's bandwidth in the bus. We assume that all m_rt in the bus are active, but that is not true. And we did similar change in d7722a643421. That's why I choose to set the PREPARE state earlier.
But I am fine with the passing stream solution, too. PR updated.

@bardliao bardliao force-pushed the fix-multilane branch 2 times, most recently from 819dda7 to 6628b7a Compare November 21, 2024 14:24
if (stream->state != SDW_STREAM_CONFIGURED)
continue;
} else {
if (m_rt->stream->state != SDW_STREAM_ENABLED &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and this is not intuitive at all. What are you trying to say here? Ignore a runtime thats not associated with the stream if it has already been activated once?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, to the opposite. Only calculate the bandwidth of the active streams, and add the bandwidth of the current stream.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok then the check for != ENABLED makes sense. but why also check for != DISABLED? Is this the case with open but paused streams? Anyway, I think this needs a comment here with the explanation. And the commit message needs to be modified too based on whatever explanation you add here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (m_rt->stream == stream) {
if (stream->state != SDW_STREAM_CONFIGURED)
continue;
} else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for an else after a continue btw

@@ -190,6 +190,21 @@ static int sdw_compute_group_params(struct sdw_bus *bus,
}

list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
/*
* sdw_compute_group_params could be called in the deprepared case, skip the
* m_rt in that case.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a better comment would be to include the runtime only during prepare

continue;
/*
* Stream stage ENABLED and DISABLED are between PREPARED and DEPREPARED,
* We should count the bandwidth only for ENABLED and DISABLED stages.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao I think looking at the enum definition, its easy to see this. A better explanation would be something like "Include runtimes with running (ENABLED state) and paused (DISABLED state) streams"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both updated.

ranj063
ranj063 previously approved these changes Nov 26, 2024
ujfalusi
ujfalusi previously approved these changes Nov 26, 2024
@ranj063
Copy link
Collaborator

ranj063 commented Nov 26, 2024

@bardliao there's a build error in qcom.c. You'll need to fix it too because you changed the signature

The stream parameter will be used in the follow up commit.
No function change.

Signed-off-by: Bard Liao <[email protected]>
…e streams only

sdw_compute_group_params() should only count payload bandwidth of the
active streams which is in the ENABLED and DISABLED state in the bus.
And add the payload bandwidth of the stream that calls
sdw_compute_group_params() in sdw_prepare_stream().

Signed-off-by: Bard Liao <[email protected]>
@bardliao
Copy link
Collaborator Author

@bardliao there's a build error in qcom.c. You'll need to fix it too because you changed the signature

Thanks for pointing this out. Fix it now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants