Skip to content

Commit e4b5921

Browse files
committed
trace: Update trace level after ipc message
Update process must be splited into two parts - updating global components, which have trace contect saved in dedicated section and updating ipc components, where trace contect is part of particular instance and data. Signed-off-by: Karol Trzcinski <karolx.trzcinski@linux.intel.com>
1 parent 097cf65 commit e4b5921

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

src/include/user/abi_dbg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#define __USER_ABI_DBG_H__
2020

2121
#define SOF_ABI_DBG_MAJOR 5
22-
#define SOF_ABI_DBG_MINOR 1
22+
#define SOF_ABI_DBG_MINOR 2
2323
#define SOF_ABI_DBG_PATCH 0
2424

2525
#define SOF_ABI_DBG_VERSION SOF_ABI_VER(SOF_ABI_DBG_MAJOR, \

src/trace/trace.c

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,99 @@ struct sof_ipc_trace_filter_elem *trace_filter_fill(struct sof_ipc_trace_filter_
203203
return NULL;
204204
}
205205

206+
/* update global components, which tr_ctx is stored inside special section */
207+
static int trace_filter_update_global(int32_t log_level, uint32_t uuid_id)
208+
{
209+
extern void *_trace_ctx_start;
210+
extern void *_trace_ctx_end;
211+
struct tr_ctx *ptr = (struct tr_ctx *)&_trace_ctx_start;
212+
struct tr_ctx *end = (struct tr_ctx *)&_trace_ctx_end;
213+
int cnt = 0;
214+
215+
/* iterate over global `tr_ctx` entries located in their own section */
216+
while (ptr < end) {
217+
/*
218+
* when looking for specific uuid element,
219+
* then find, update and stop searching
220+
*/
221+
if ((uint32_t)ptr->uuid_p == uuid_id) {
222+
ptr->level = log_level;
223+
return 1;
224+
}
225+
/* otherwise each element should be updated */
226+
if (!ptr->uuid_p) {
227+
ptr->level = log_level;
228+
++cnt;
229+
}
230+
++ptr;
231+
}
232+
233+
return cnt;
234+
}
235+
236+
/* return trace context from any ipc component type */
237+
static struct tr_ctx *trace_filter_ipc_comp_context(struct ipc_comp_dev *icd)
238+
{
239+
switch (icd->type) {
240+
case COMP_TYPE_COMPONENT:
241+
return &icd->cd->tctx;
242+
case COMP_TYPE_BUFFER:
243+
return &icd->cb->tctx;
244+
case COMP_TYPE_PIPELINE:
245+
return &icd->pipeline->tctx;
246+
/* each COMP_TYPE must be specified */
247+
default:
248+
tr_err(&ipc_tr, "Unknown trace context for ipc component type 0x%X",
249+
icd->type);
250+
return NULL;
251+
}
252+
}
253+
254+
/* update ipc components, wchich tr_ctx may be read from ipc_comp_dev structure */
255+
static int trace_filter_update_instances(int32_t log_level, uint32_t uuid_id,
256+
int32_t pipe_id, int32_t comp_id)
257+
{
258+
struct ipc *ipc = ipc_get();
259+
struct ipc_comp_dev *icd;
260+
struct list_item *clist;
261+
struct tr_ctx *ctx;
262+
bool correct_comp;
263+
int cnt = 0;
264+
265+
/* compare each ipc component with filter settings and update log level after pass */
266+
list_for_item(clist, &ipc->comp_list) {
267+
icd = container_of(clist, struct ipc_comp_dev, list);
268+
ctx = trace_filter_ipc_comp_context(icd);
269+
correct_comp = comp_id == -1 || icd->id == comp_id; /* todo: icd->topo_id */
270+
correct_comp &= uuid_id == 0 || (uint32_t)ctx->uuid_p == uuid_id;
271+
correct_comp &= pipe_id == -1 || ipc_comp_pipe_id(icd) == pipe_id;
272+
if (correct_comp) {
273+
ctx->level = log_level;
274+
++cnt;
275+
}
276+
277+
platform_shared_commit(icd, sizeof(*icd));
278+
}
279+
return cnt;
280+
}
281+
206282
int trace_filter_update(const struct trace_filter *filter)
207283
{
208-
return -EINVAL;
284+
int ret = 0;
285+
286+
/* validate log level, LOG_LEVEL_CRITICAL has low value, LOG_LEVEL_VERBOSE high */
287+
if (filter->log_level < LOG_LEVEL_CRITICAL ||
288+
filter->log_level > LOG_LEVEL_VERBOSE)
289+
return -EINVAL;
290+
291+
/* update `*`, `name*` or global `name` */
292+
if (filter->pipe_id == -1 && filter->comp_id == -1)
293+
ret = trace_filter_update_global(filter->log_level, filter->uuid_id);
294+
295+
/* update `*`, `name*`, `nameX.*` or `nameX.Y`, `name` may be '*' */
296+
ret += trace_filter_update_instances(filter->log_level, filter->uuid_id,
297+
filter->pipe_id, filter->comp_id);
298+
return ret > 0 ? ret : -EINVAL;
209299
}
210300

211301
void trace_flush(void)

0 commit comments

Comments
 (0)