On Mon, Mar 04, 2024 at 01:03:55PM -0700, Dave Jiang wrote:
>
>
> On 2/29/24 6:31 PM, [email protected] wrote:
> > From: Alison Schofield <[email protected]>
> >
> > Media_error records are logged as events in the kernel tracing
> > subsystem. To prepare the media_error records for cxl list, enable
> > tracing, trigger the poison list read, and parse the generated
> > cxl_poison events into a json representation.
> >
> > Use the event_trace private parsing option to customize the json
> > representation based on cxl-list calling options and event field
> > settings.
> >
> > Signed-off-by: Alison Schofield <[email protected]>
> > ---
> > cxl/json.c | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 271 insertions(+)
> >
snip
> > +static int poison_event_to_json(struct tep_event *event,
> > + struct tep_record *record, void *ctx)
> > +{
> > + struct poison_ctx *p_ctx = (struct poison_ctx *)ctx;
> > + struct json_object *jobj, *jp, *jpoison = p_ctx->jpoison;
> > + unsigned long flags = p_ctx->flags;
> > + char flag_str[32] = { '\0' };
> > + bool overflow = false;
> > + u8 source, pflags;
> > + const char *name;
> > + u64 addr, ts;
> > + u32 length;
> > + char *str;
> > +
> > + jp = json_object_new_object();
> > + if (!jp)
> > + return -ENOMEM;
> > +
> > + /* Skip records not in this region when listing by region */
> > + name = p_ctx->region ? cxl_region_get_devname(p_ctx->region) : NULL;
> > + if (name)
> > + str = cxl_get_field_string(event, record, "region");
> > +
> > + if ((name) && (strcmp(name, str) != 0)) {
> > + json_object_put(jp);
> > + return 0;
> > + }
> > +
> > + /* Include endpoint decoder name with hpa, when present */
> > + name = cxl_get_field_string(event, record, "memdev");
> > + addr = cxl_get_field_u64(event, record, "hpa");
> > + if (addr != ULLONG_MAX)
> > + name = find_decoder_name(p_ctx, name, addr);
> > + else
> > + name = NULL;
>
> Why assign name a few lines above and then reassign here without using?
name is used as a param to find_decoder_name(). I'll move that to
only retrieve from the record if we're doing find_decod_name().
> Also I noticed the name gets reassigned for different purposes a few times.
> Can we have separate variables in order to make the code cleaner to read? I
> think maybe a region_name and a decoder_name.
Yes, done in v10.
> >
snip
> > +
> > + source = cxl_get_field_u8(event, record, "source");
> > + switch (source) {
> > + case CXL_POISON_SOURCE_UNKNOWN:
> > + jobj = json_object_new_string("Unknown");
> > + break;
> > + case CXL_POISON_SOURCE_EXTERNAL:
> > + jobj = json_object_new_string("External");
> > + break;
> > + case CXL_POISON_SOURCE_INTERNAL:
> > + jobj = json_object_new_string("Internal");
> > + break;
> > + case CXL_POISON_SOURCE_INJECTED:
> > + jobj = json_object_new_string("Injected");
> > + break;
> > + case CXL_POISON_SOURCE_VENDOR:
> > + jobj = json_object_new_string("Vendor");
> > + break;
> > + default:
> > + jobj = json_object_new_string("Reserved");
> > + }
>
> Seems like you can have a static string table here? Then you can do something
> like:
> if (source < CXL_POISON_SOURCE_MAX)
> jobj = json_object_new_string(cxl_poison_source[source]);
> else
> jobj = json_object_new_string("Reserved");
>
> DJ
Nice! Please take a look at in v10.
Thanks for the review!
snip