[PATCH libdrm v6 1/1] amdgpu: move asic id table to a separate file

Emil Velikov emil.l.velikov at gmail.com
Tue Jun 6 13:43:16 UTC 2017


Hi Samuel,

With all the other discussion aside here is some code specific input
which I'd hope you agree with.

On 31 May 2017 at 21:22, Samuel Li <Samuel.Li at amd.com> wrote:

> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -45,6 +45,9 @@ AM_DISTCHECK_CONFIGURE_FLAGS = \
>
>  pkgconfigdir = @pkgconfigdir@
>  pkgconfig_DATA = libdrm.pc
> +libdrmdatadir = $(datadir)/libdrm
> +dist_libdrmdata_DATA = include/drm/amdgpu.ids
> +export libdrmdatadir
Don't place exports in the makefiles. See how pkgconfigdir is managed
in configure.ac and do do with libdrmdatadir.


> --- /dev/null
> +++ b/amdgpu/amdgpu_asic_id.c

> +static int parse_one_line(const char *line, struct amdgpu_asic_id *id)
> +{
> +       char *buf, *saveptr;
> +       char *s_did;
> +       char *s_rid;
> +       char *s_name;
> +       char *endptr;
> +       int r = 0;
> +
> +       buf = strdup(line);
You don't need the extra strdup here if you use strchr over strtok.

> +       if (!buf)
> +               return -ENOMEM;
> +
> +       /* ignore empty line and commented line */
> +       if (strlen(line) == 0 || line[0] == '#') {
You might want to check/trim whitespace before #? Same question applies below.

> +               r = -EAGAIN;
> +               goto out;
With the strdup, hence free() gone, all the errors will be "return -EFOO;"


> +       /* trim leading whitespaces or tabs */
> +       while (*s_name == ' ' || *s_name == '\t')
> +               s_name++;
Use isblank/isspace - they should handle \r et al, which will creep as
someone on the team uses Windows ;-)



> +int amdgpu_parse_asic_ids(struct amdgpu_asic_id **p_asic_id_table)
> +{

> +       /* 1st valid line is file version */
> +       while ((n = getline(&line, &len, fp)) != -1) {
> +               /* trim trailing newline */
> +               if (line[n - 1] == '\n')
> +                       line[n - 1] = '\0';
Why do we need this - afaict none of the parsing code cares if we have
\n or not?
Same question applies for the second loop, below.

> +
> +               /* ignore empty line and commented line */
> +               if (strlen(line) == 0 || line[0] == '#') {
> +                       line_num++;
> +                       continue;
> +               }
> +
> +               drmMsg("%s version: %s\n", AMDGPU_ASIC_ID_TABLE, line);
> +               break;
> +       }
> +
Should the lack of a version line/tag be considered fatal or not? An
inline comment is welcome.

> +       while ((n = getline(&line, &len, fp)) != -1) {

> +
> +               if (table_size >= table_max_size) {
Move it at the top of the loop, since as-is it will end up reallocate
even when it doesn't need to.

> +                       /* double table size */
> +                       table_max_size *= 2;
> +                       asic_id_table = realloc(asic_id_table, table_max_size *
> +                                               sizeof(struct amdgpu_asic_id));
> +                       if (!asic_id_table) {
Memory originally pointed by asic_id_table is leaked.

> +                               r = -ENOMEM;
> +                               goto free;
> +                       }
> +               }
> +       }
> +
> +       /* end of table */
> +       id = asic_id_table + table_size;
> +       memset(id, 0, sizeof(struct amdgpu_asic_id));
Here one clears the sentinel, which is needed as we hit realloc above, correct?

> +       asic_id_table = realloc(asic_id_table, (table_size+1) *
> +                               sizeof(struct amdgpu_asic_id));
But why do we realloc again?

> +       if (!asic_id_table)
As above - we have a leak original asic_id_table.

> +               r = -ENOMEM;
> +
> +free:
> +       free(line);
> +
> +       if (r && asic_id_table) {
> +               while (table_size--) {
> +                       id = asic_id_table + table_size;
> +                       free(id->marketing_name);
> +               }
> +               free(asic_id_table);
> +               asic_id_table = NULL;
> +       }
> +close:
> +       fclose(fp);
> +
> +       *p_asic_id_table = asic_id_table;
> +
Please don't entwine the error path with the normal one.

Setting *p_asic_id_table (or any user provided pointer) when the
function fails is bad design.

Regards,
Emil


More information about the amd-gfx mailing list