[PATCH libdrm v6 1/1] amdgpu: move asic id table to a separate file
Emil Velikov
emil.l.velikov at gmail.com
Wed Jun 7 11:12:00 UTC 2017
On 7 June 2017 at 09:40, Michel Dänzer <michel at daenzer.net> wrote:
> On 06/06/17 10:43 PM, Emil Velikov wrote:
>> On 31 May 2017 at 21:22, Samuel Li <Samuel.Li at amd.com> wrote:
>>
>>> --- /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.
>
> Beware that without strdup here, amdgpu_parse_asic_ids must set line =
> NULL after table_line++, so that getline allocates a new buffer for the
> next line.
>
A simple "line = NULL" will lead to a memory leak, AFAICT.
In either case, I'm a bit baffled how that is affected by the
presence/lack of strdup?
We don't alter or reuse the backing storage only
strcmp/isblank/strtol/strdup it.
>
>>> +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?
>
> The \n has to be removed somehow, otherwise it ends up as part of the
> marketing name returned to the application.
>
Wouldn't be better to do that in parse_one_line() around the
marketing_name = strdup(...) call?
It's a matter of taste, so feel free to ignore me.
>
>>> + /* 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?
>
> I asked for that, in order not to waste memory for unused table entries.
>
D'oh, indeed. Thank you. Worth adding a note?
>
>>> +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.
>
> I don't really see the issue with that; it's fine for the only caller of
> this function.
>
it's not obvious and might come to bite. Since *p_asic_id_table is
already NULL (we're using calloc) I'd opt for dropping it.
Not trying to force my opinion, just stating concerns.
Another crazy idea that just came to mind:
Since getline() can do multiple implicit realloc's one can allocate "a
sane" default and feed that instead of the current NULL.
Regards,
Emil
More information about the amd-gfx
mailing list