Skip to content

Conversation

@lyakh
Copy link
Collaborator

@lyakh lyakh commented Feb 23, 2023

The SOF already supports the REGISTER_KCPS IPC, this patch also adds support for it to the driver. A new topology token is used for this, which specified the KPCS requirement for each pipeline.

Do I need to bump up any ABI version numbers for this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why __s32 and not just s32?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

because it's an external parameter, a part of an ABI

Copy link
Collaborator

Choose a reason for hiding this comment

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

You also need to add to the extension:
SOF_IPC4_MOD_EXT_MSG_SIZE(sizeof(adjust))

or you can also use the dedicated function to do a proper LARGE_CONFIG, see #4212.
Since you are always going to send a single u32, it might be justified to have it open coded, but in general I prefer to use the function which exists for the purpose.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oh... sof_ipc4_set_get_data() is a kind of a monster... In general - yes, I'd also rather use a proper abstraction, so... But well, I still think it's better to use the accessor. Thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, it is a monster, but it adds the benefit that we use common code and we can also dump the payload as hex in one place.
It is good to have these handled in one path to help debugging things.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Well, yes and no, it is used to track the payload size in the mailbox, it is used in the IPC low level code to decide if we need to copy something to there or not.
Can you drop this comment?

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 think it's the msg.data_size, that's used for that in the IPC4 case, not the last parameter to sof_ipc_tx_message_no_reply(), but sure, I can drop it

Copy link
Collaborator

@ujfalusi ujfalusi Feb 23, 2023

Choose a reason for hiding this comment

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

Yes, which is coming from this size parameter:

msg->msg_size = msg_bytes;

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 stand corrected - I was looking at an older kernel version. Now it's used indeed!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not make the sof_ipc4_pipeline_send_kcps() handle the !kcps_adjust internally and then you can have this implemented in a more optimistic way:

if (!ret) {
	ret = sof_ipc4_pipeline_send_kcps(sdev, swidget, kcps_adjust);
	if (ret) {
		dev_err(sdev->dev, "failed to increase KCPS: %d, continuing\n", ret);
		ret = 0;
	} else { /* the error case */ }
}

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 was comparing the two options - where to put the check for 0 KCPS adjustment, and in the end I chose this option. It's a really small addition outside and makes it clear immediately at this level, whereas in the function - you'd be calling it just to return immediately. So, unless you feel strongly about this, I'd keep it as is

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't feel strongly about this, just it would make the caller sites cleaner, less number of if ().

Copy link
Collaborator

Choose a reason for hiding this comment

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

Then this is a dev_warn()

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah, dev_err() would be called by the CI, right? In fact I'm not even sure - should we make this a failure or not?

Copy link
Collaborator

Choose a reason for hiding this comment

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

if it is an error, then we should treat it as an error, here we are ignoring it, so it is a warning, imho

@ujfalusi
Copy link
Collaborator

The SOF already supports the REGISTER_KCPS IPC, this patch also adds support for it to the driver. A new topology token is used for this, which specified the KPCS requirement for each pipeline.

Do I need to bump up any ABI version numbers for this?

No need for ABI version update (and it is not really defined for IPC4 anyways). The KCPS update is an existing FW feature, we just missed it.

@lyakh
Copy link
Collaborator Author

lyakh commented Feb 23, 2023

The SOF counterpart is thesofproject/sof#7160

Copy link
Collaborator

@ujfalusi ujfalusi left a comment

Choose a reason for hiding this comment

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

The open coded IPC message crafting is not correct (I would use the ops for it to do the right thing) and there is the wrong comment about the last parameter of sof_ipc_tx_message_no_reply()

Copy link
Collaborator

Choose a reason for hiding this comment

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

this is a very ipc4 specific parameter, can we put it somewhere in one of the ipc4 structs instead of swidget?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

moved, thanks

Copy link
Member

@plbossart plbossart left a comment

Choose a reason for hiding this comment

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

Rather lost of what this kpcs token means, and what exactly it changes.

Copy link
Member

Choose a reason for hiding this comment

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

it's the first time I hear about a pipeline-level cycle count. We already have a module 'cpc' (cycle per chunk) and 'cps" *cycles per second", so it's not clear to me how those 3 tokens would be used.

Copy link

@RanderWang RanderWang Feb 27, 2023

Choose a reason for hiding this comment

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

why we need kcps ? In current 0004 branch, kcps is built from cpc and we already have cpc in module now. Why do we need to add kcps ?

int kcps = cd->cpc * 1000 / ppl_data->p->period;

Choose a reason for hiding this comment

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

In 0004 branch, kcps is built from each module in pipeline with the above algorithm, why we need pipeline kcps ?

                data.start = p->source_comp;
                data.p = p;
                walk_ctx.comp_func = add_pipeline_cps_consumption;

                if(!clocks_handled)
                        ret = walk_ctx.comp_func(p->source_comp, NULL, &walk_ctx, PPL_DIR_DOWNSTREAM);

Copy link
Member

Choose a reason for hiding this comment

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

what does 'adjust' mean? is this to specify a kcycles value, or alter it from a baseline read in topology?

Completely unclear what this is about.

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 can call it "delta" if that would help

Copy link
Collaborator

Choose a reason for hiding this comment

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

or kcps_change?

Copy link
Collaborator

@ujfalusi ujfalusi Feb 24, 2023

Choose a reason for hiding this comment

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

if you call it 'delta' then the function should be not sof_ipc4_pipeline_send_kcps(), prehaps: sof_ipc4_send_kcps_update()?

Copy link
Member

Choose a reason for hiding this comment

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

I see nothing that's pipeline-specific here, I really don't understand what 'adjust' means here. If the message destination is the base firmware module how would one change pipeline Y ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

IIUC it doesn't matter which specific pipeline requests the change in clock rate, we just add up all pipelines and configure the clock with the sum

Copy link
Member

Choose a reason for hiding this comment

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

int or s32?

Copy link
Collaborator Author

@lyakh lyakh Feb 24, 2023

Choose a reason for hiding this comment

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

@plbossart the value that's sent out has to be s32, because it can be negative for a negative adjustment, and it has to be 32 bits because it's a part of an ABI. But here we're storing a generic integer unsigned value, so I think unsigned int is appropriate here.

@lgirdwood
Copy link
Member

Base FW today supports a global per core DSP frequency manager to select the most power efficient clock based on DSP core loading. Today it uses the following rules

  1. The FW frequency manager makes its frequency selection based on the kcps load value for each core.
  2. The driver sends new kcps delta values to base FW for each pipeline loaded/unloaded (or start/stop)
  3. The driver knows the cps value for each module from the ext manifest (these are non accurate test values that the driver is not reading today). Driver should sum these cps values and convert to a kcps when loading a pipeline with these modules.
  4. The driver also now knows the per pipeline kcps value from topology which if exists can override the manifest cps values (this is this PR).

Rules 1, 2, & 3 are compatibility, rule 4 is extended feature improvement on Linux. Rule 3 is not implemented in driver today and has no tooling to capture per module cps or to regenerate signed FWs with new ext manifest cps data.

Long term the DSP FW should be responsible to monitor the per core loading with hints from driver (manifest, topology) and adjust frequency as necessary.

The SOF already supports the REGISTER_KCPS IPC, this patch also adds
support for it to the driver. A new topology token is used for this,
which specified the KCPS requirement for each pipeline. When a
pipeline is created, that had a KCPS value specified for it in the
topology, that value is sent to the firmware for clock adjustment.
When such a pipeline is destroyed, the same negative value is sent to
return the system clock rate to the original state.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Copy link
Collaborator

@ujfalusi ujfalusi left a comment

Choose a reason for hiding this comment

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

I would still hide the delta_kcps check fro 0 in sof_ipc4_send_kcps(), but it is probably just a matter of taste.

@plbossart
Copy link
Member

I still don't get the relationship between pipeline and cores. We know that with the introduction of the DP domain the pipeline can be made of modules that are assigned on different cores. So how would the pipeline 'adjust' value be computed in this case?

Lost in space, and it's Monday 9:45am. Oh well.

@RanderWang
Copy link

I still don't know why we need kcps and how does fw support this. currently the FW algorithm is built based on module cpc. And I also found that cpc value in fw extended manifest was refined(mtl: add measured cps and cpc values). It seems that kernel driver should get cpc value from module extended config and send it to FW.

@lyakh
Copy link
Collaborator Author

lyakh commented Feb 28, 2023

I still don't get the relationship between pipeline and cores. We know that with the introduction of the DP domain the pipeline can be made of modules that are assigned on different cores. So how would the pipeline 'adjust' value be computed in this case?

@plbossart with this PR no KCPS calculations are done in the kernel. This PR does a very simple thing: takes values from the topology and sends them to the firmware.
As for different cores - I'm not sure we know that. We discussed that multiple times, also including in the DP PR, IIRC. And there as well I commented, that that isn't supported so far and it has been decided, that the DP doesn't have to run different modules on different cores, so as long as that isn't supported, we should avoid that. Note, that we have the same situation right now already - nothing prevents one from creating a topology, assigning connected pipelines or components on those pipelines to different cores. We just know, that that isn't supported and doesn't work, so we don't do that...

@plbossart
Copy link
Member

too many double-negatives in your answer @lyakh. The point is that if a component is assigned to a different core the entire logic looks wrong. Either we accept component-level core assignment or we don't.

offsetof(struct sof_ipc4_pipeline, use_chain_dma)},
{SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
offsetof(struct sof_ipc4_pipeline, core_id)},
{SOF_TKN_SCHED_PIPELINE_KCPS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
Copy link
Member

Choose a reason for hiding this comment

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

@lyakh, @ujfalusi and @jsarha I had a chat with @plbossart and can we modify this attribute to be per module i.e. needs to be in the base class of each module. This would then allow us to mix scheduling types in a pipeline and scale across cores.

Thinking further, can we also extend this to include format and be an array i.e.

{SOF_TKN_SCHED_MODULE_KCPS_S16LE, SND_SOC_TPLG_TUPLE_TYPE_ARRAY, get_token_u32_array,

Where the array index would be the channel count + 1. i.e. when defined in topology

1000, 2000, 0, 4000, 0, 0, 0, 0

This would then specify 1000 kcps for mono S16_LE, 2000kcps for stereo S16_LE, 3 channel S16_LE not known (can use platform max default), and so on.

Copy link
Member

Choose a reason for hiding this comment

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

IIRC the CPC/CPS are kind of worst-case figures. They are not meant to be adjusted depending on channel count or input/output formats. We're probably looking at one broadbrush estimate for each module and correction factor to account for the known unknowns (cache, IPC, solar eclipses and neutrinos).

@kv2019i
Copy link
Collaborator

kv2019i commented Mar 14, 2023

Clarification from FW is that kernel KCPS IPC should only sent in special cases to override the values on module config (defined in toml files). The implementation is not complete in SOF main but there is an early version available, see thesofproject/sof#7267

@plbossart
Copy link
Member

Clarification from FW is that kernel KCPS IPC should only sent in special cases to override the values on module config (defined in toml files). The implementation is not complete in SOF main but there is an early version available, see thesofproject/sof#7267

Not clear if the ask is to override the CPC/CPS values for a module (with the updated value impacting all pipelines with a module instance), for a module instance (with impact limited to the pipeline in which it is inserted), or for a pipeline containing a module instance (directly changing the total maintained at the pipeline level - if this makes sense).

@plbossart
Copy link
Member

@ranj063 @lyakh @kv2019i @ujfalusi I've lost track of this PR status, is this still needed as is, or evolutions needed? Or is this related to the CPC stuff that @ujfalusi was working on in #4262.

Bear with me, we have too many PRs in flight that need to be merged or closed.

@lyakh
Copy link
Collaborator Author

lyakh commented Apr 18, 2023

@ranj063 @lyakh @kv2019i @ujfalusi I've lost track of this PR status, is this still needed as is, or evolutions needed? Or is this related to the CPC stuff that @ujfalusi was working on in #4262.

@plbossart as far as I understand we decided, that we don't want KCPS set from the topology and instead we want a user-activated trigger to increase the clock and maybe also some situations where this will be done automatically

@ujfalusi
Copy link
Collaborator

Yes, we will need some place to store the magical KCPS for a platform and send that with a kcontrol.
afaik the KCPS == maximum core kHz, so we need to gather those for all platforms and store it somewhere, probably in sof_dev_desc.
I'm not sure if the KCPS is ncores * max_core_kHz.

@plbossart
Copy link
Member

Yes, we will need some place to store the magical KCPS for a platform and send that with a kcontrol. afaik the KCPS == maximum core kHz, so we need to gather those for all platforms and store it somewhere, probably in sof_dev_desc. I'm not sure if the KCPS is ncores * max_core_kHz.

Kcontrols are typically exposed in topology though...

debugfs sounds like a better place for this kind of things. We should not use kcontrol IMHO.

@ujfalusi
Copy link
Collaborator

Yes, we will need some place to store the magical KCPS for a platform and send that with a kcontrol. afaik the KCPS == maximum core kHz, so we need to gather those for all platforms and store it somewhere, probably in sof_dev_desc. I'm not sure if the KCPS is ncores * max_core_kHz.

#4262 added the fallback platfomr KCPS support, we can use that number for the 'boost'

Kcontrols are typically exposed in topology though...

debugfs sounds like a better place for this kind of things. We should not use kcontrol IMHO.

debugfs would be really simple for sure, but I think the issue is that this has to be exposed to user space and debugfs is not a good place for UCM to touch it for example.
The kcontrol cannot come from topology as this needs special handling, it is not attached to any firmware module, it is a different message to be sent targeting the basefw.
Code-wise it is not a big task, but figuring out a correct place to create that kcontrol is not that straight forward, we need to find the correct hook and have the needed information available at that point.
Likely at the end of the tplg loading, but I don't like that piggy-backing too much.

@plbossart
Copy link
Member

this PR is no longer aligned with our plans for MTL. We will first enable the parsing of CPC information from the manifest with #4338, and move all efforts to override the MCPS budget to a later point after revisiting the API for clock scaling with our firmware friends.

Let's close this for now.

@plbossart plbossart closed this May 4, 2023
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.

7 participants