DPDK patches and discussions
 help / color / mirror / Atom feed
From: "Medvedkin, Vladimir" <vladimir.medvedkin@intel.com>
To: <wenjing.qiao@intel.com>, <jingjing.wu@intel.com>,
	<beilei.xing@intel.com>, <qi.z.zhang@intel.com>
Cc: <dev@dpdk.org>
Subject: Re: [PATCH v2 1/2] net/cpfl: parse flow offloading hint from P4 context file
Date: Fri, 9 Feb 2024 16:20:02 +0000	[thread overview]
Message-ID: <2ebb4e92-3f1d-4e27-a7c7-7ea05607661b@intel.com> (raw)
In-Reply-To: <20240105081649.530384-2-wenjing.qiao@intel.com>

Hi Wenjing,

Please find comments inlined

On 05/01/2024 08:16, wenjing.qiao@intel.com wrote:
> From: Wenjing Qiao <wenjing.qiao@intel.com>
>
> To supporting P4-programmed network controller, reuse devargs
> "flow_parser" to specify the path of a p4 context JSON configure
> file. The cpfl PMD use the JSON configuration file to translate
> rte_flow tokens into low level hardware representation.
>
> Note, the p4 context JSON file is generated by the P4 compiler
> and is intended to work exclusively with a specific P4 pipeline
> configuration, which must be compiled and programmed into the hardware.
>
> Signed-off-by: Wenjing Qiao <wenjing.qiao@intel.com>
> ---
<snip>
> +	if (cpfl_check_is_p4_mode(root)) {
> +		PMD_DRV_LOG(NOTICE, "flow parser mode is p4 mode.");
> +		prog = rte_zmalloc("tdi_parser", sizeof(struct cpfl_tdi_program), 0);
> +		if (prog == NULL) {
> +			PMD_DRV_LOG(ERR, "Failed to create program object.");
> +			return -ENOMEM;
> +		}
> +		ret = cpfl_tdi_program_create(root, prog);
> +		if (ret != 0) {
> +			PMD_INIT_LOG(ERR, "Failed to create tdi program from file %s", filename);
> +			rte_free(prog);

This looks like doublefree to me because cpfl_tdi_program_create() on 
fail calls cpfl_tdi_program_destroy() which in turn does rte_free for 
program.

On a separate note maybe cpfl_tdi_program_create() function should not 
call cpfl_tdi_program_destroy() and maybe it should be responsibility of 
whoever calls _create().


<snip>

> +static int
> +cpfl_tdi_parse_match_key_field_obj(json_t *root, struct cpfl_tdi_match_key_field *mkf)
> +{
> +	int ret, val = 0;
> +	char last3char[4];
> +
> +	ret = cpfl_tdi_get_string_obj(root, "name", mkf->name);
> +	if (ret != 0)
> +		return ret;
> +
> +	ret = cpfl_tdi_get_string_obj(root, "instance_name", mkf->instance_name);
> +	if (ret != 0)
> +		return ret;
> +
> +	ret = cpfl_tdi_get_string_obj(root, "field_name", mkf->field_name);
> +	if (ret != 0)
> +		return ret;
> +	strncpy(last3char, mkf->field_name + strlen(mkf->field_name) - 3, 3);
> +	last3char[3] = '\0';
> +	if (!strcmp(last3char, "VSI") || !strcmp(last3char, "vsi"))

If this is now case sensitive then I'd suggest to make contents of the 
last3char lower case to handle all variations of "VSi".

> +		mkf->is_vsi = true;
> +	else
> +		mkf->is_vsi = false;
> +
> +	ret = cpfl_tdi_parse_match_type(root, mkf);
> +	if (ret != 0)
> +		return ret;
> +
> +	ret = cpfl_tdi_get_integer_obj(root, "bit_width", &val);
> +	if (ret != 0)
> +		return ret;
> +
> +	mkf->bit_width = (uint16_t)val;

Here and several places below, does it need to be range checked?

> +
> +	ret = cpfl_tdi_get_integer_obj(root, "index", &val);
> +	if (ret != 0)
> +		return ret;
> +
> +	mkf->index = (uint32_t)val;
> +
> +	ret = cpfl_tdi_get_integer_obj(root, "position", &val);
> +	if (ret != 0)
> +		return ret;
> +
> +	mkf->position = (uint32_t)val;
> +
> +	return 0;
> +}
> +
> +static int
> +cpfl_tdi_parse_match_key_fields(json_t *root, struct cpfl_tdi_table *table)
> +{
> +	int ret;
> +	int array_len = json_array_size(root);
> +
> +	if (array_len == 0)
> +		return 0;
> +
> +	table->match_key_field_num = (uint16_t)array_len;
> +	table->match_key_fields =
> +	    rte_zmalloc(NULL, sizeof(struct cpfl_tdi_match_key_field) * array_len, 0);
> +	if (table->match_key_fields == NULL) {
> +		PMD_DRV_LOG(ERR, "Failed to create match key field array.");
> +		return -ENOMEM;
> +	}
> +
> +	for (int i = 0; i < array_len; i++) {
> +		json_t *mkf_object = json_array_get(root, i);
> +
> +		ret = cpfl_tdi_parse_match_key_field_obj(mkf_object, &table->match_key_fields[i]);
> +		if (ret != 0)
Possible memory leak due to earlier rte_zmalloc(). There are several 
places below with the same problem.
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +cpfl_tdi_parse_byte_order(json_t *root, struct cpfl_tdi_match_key_format *mkf)
> +{
> +	char bo[CPFL_TDI_JSON_STR_SIZE_MAX];
> +	int ret;
> +
> +	ret = cpfl_tdi_get_string_obj(root, "byte_order", bo);
> +	if (ret != 0)
> +		return -EINVAL;
> +
> +	if (!strcmp(bo, "HOST")) {
Is it expected to be upper case always?
> +		mkf->byte_order = CPFL_TDI_BYTE_ORDER_HOST;
> +	} else if (!strcmp(bo, "NETWORK")) {
> +		mkf->byte_order = CPFL_TDI_BYTE_ORDER_NETWORK;
> +	} else {
> +		PMD_DRV_LOG(ERR, "Unknown byte order type %s", bo);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
<snip>
> +
> +static int
> +cpfl_tdi_pparse_action_code(json_t *root, struct cpfl_tdi_hw_action *ha)
double "p"
<snip>
> +static int
> +cpfl_tdi_parse_table_obj(json_t *root, struct cpfl_tdi_table *table)
> +{
> +	int ret, val = 0;
> +	struct json_t *jobj = NULL;
> +
> +	ret = cpfl_tdi_parse_table_type(root, table);
> +	if (ret != 0)
> +		return ret;
> +
> +	ret = cpfl_tdi_get_integer_obj(root, "handle", &val);
> +	if (ret != 0)
> +		return ret;
> +	table->handle = (uint32_t)val;
> +
> +	ret = cpfl_tdi_get_string_obj(root, "name", table->name);
> +	if (ret != 0)
> +		return ret;
> +
> +	if (table->table_type == CPFL_TDI_TABLE_TYPE_POLICER_METER) {
> +		/* TODO */
It looks like not implemented yet, should this return 0? Does it need to 
have some kind of logging?
> +		return 0;
> +	}
<snip>
> +static int
> +cpfl_tdi_parse_global_configs(json_t *root, struct cpfl_tdi_global_configs *gc)
> +{
> +	json_t *jobj = NULL;
> +	int ret;
> +
> +	ret = cpfl_tdi_get_array_obj(root, "hardware_blocks", &jobj);
> +	if (ret != 0)
> +		return ret;
> +
> +	return cpfl_tdi_parse_gc_hardware_blocks(jobj, gc);
> +}
> +
> +int
> +cpfl_tdi_program_create(json_t *root, struct cpfl_tdi_program *prog)
Should input parameters be checked against NULL?
> +{
> +	json_t *jobj = NULL;
> +	int ret;
> +
> +	ret = cpfl_tdi_get_string_obj(root, "program_name", prog->program_name);
> +	if (ret != 0)
> +		goto err;
> +
> +	ret = cpfl_tdi_get_string_obj(root, "build_date", prog->build_date);
> +	if (ret != 0)
> +		goto err;
> +
> +	ret = cpfl_tdi_get_string_obj(root, "compile_command", prog->compile_command);
> +	if (ret != 0)
> +		goto err;
> +
> +	ret = cpfl_tdi_get_string_obj(root, "compiler_version", prog->compiler_version);
> +	if (ret != 0)
> +		goto err;
> +
> +	ret = cpfl_tdi_get_string_obj(root, "schema_version", prog->schema_version);
> +	if (ret != 0)
> +		goto err;
> +
> +	ret = cpfl_tdi_get_string_obj(root, "target", prog->target);
> +	if (ret != 0)
> +		goto err;
> +
> +	ret = cpfl_tdi_get_object_obj(root, "global_configs", &jobj);
> +	if (ret != 0)
> +		goto err;
> +
> +	ret = cpfl_tdi_parse_global_configs(jobj, &prog->global_configs);
> +	if (ret != 0)
> +		goto err;
> +
> +	ret = cpfl_tdi_get_array_obj(root, "tables", &jobj);
> +	if (ret != 0)
> +		goto err;
> +
> +	ret = cpfl_tdi_parse_tables(jobj, prog);
> +	if (ret != 0)
> +		goto err;
> +
> +	json_decref(root);
is this json_decref() needed? This function is called from 
cpfl_parser_create() which already does json_decref().
> +
> +	return 0;
> +
> +err:
> +	cpfl_tdi_program_destroy(prog);
> +	return ret;
> +}
> +
<snip>

-- 
Regards,
Vladimir


  reply	other threads:[~2024-02-09 16:20 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-22 10:08 [PATCH 0/2] net/cpfl: support flow offloading for P4 wenjing.qiao
2023-12-22 10:08 ` [PATCH 1/2] net/cpfl: parse flow offloading hint from P4 context file wenjing.qiao
2024-01-05  8:16   ` [PATCH v2 0/2] net/cpfl: support flow offloading for P4 wenjing.qiao
2024-01-05  8:16   ` [PATCH v2 1/2] net/cpfl: parse flow offloading hint from P4 context file wenjing.qiao
2024-02-09 16:20     ` Medvedkin, Vladimir [this message]
2024-01-05  8:16   ` [PATCH v2 2/2] net/cpfl: add TDI to flow engine wenjing.qiao
2024-02-14 17:21     ` Medvedkin, Vladimir
2023-12-22 10:08 ` [PATCH " wenjing.qiao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2ebb4e92-3f1d-4e27-a7c7-7ea05607661b@intel.com \
    --to=vladimir.medvedkin@intel.com \
    --cc=beilei.xing@intel.com \
    --cc=dev@dpdk.org \
    --cc=jingjing.wu@intel.com \
    --cc=qi.z.zhang@intel.com \
    --cc=wenjing.qiao@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).