sna: Reorder connector initialisation to avoid leak

If the output was ignored, we would leak the allocations. However, we
can check the output name after the first GETCONNECTOR/GETENCODER
request before any allocations.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2014-05-05 09:32:59 +01:00
parent 55f567f9d8
commit 8fd13a5207
1 changed files with 32 additions and 32 deletions

View File

@ -2723,7 +2723,7 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial)
xf86OutputPtr *outputs, output;
const char *output_name;
char name[32];
int len, i, ret = -1;
int len, i;
DBG(("%s(%d)\n", __FUNCTION__, id));
@ -2750,11 +2750,41 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial)
return 0;
}
if (compat_conn.conn.connector_type < ARRAY_SIZE(output_names))
output_name = output_names[compat_conn.conn.connector_type];
else
output_name = "UNKNOWN";
len = snprintf(name, 32, "%s%d", output_name, compat_conn.conn.connector_type_id);
if (output_ignored(scrn, name))
return 0;
if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
DBG(("%s: GETENCODER failed, ret=%d\n", __FUNCTION__, errno));
return 0;
}
if (xf86IsEntityShared(scrn->entityList[0])) {
const char *str;
str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD);
if (str && !sna_zaphod_match(str, name)) {
DBG(("%s: zaphod mismatch, want %s, have %s\n", __FUNCTION__, str, name));
return 0;
}
if ((enc.possible_crtcs & (1 << scrn->confScreen->device->screen)) == 0) {
if (str) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"%s is an invalid output for screen (pipe) %d\n",
name, scrn->confScreen->device->screen);
return -1;
} else
return 0;
}
enc.possible_crtcs = 1;
}
sna_output = calloc(sizeof(struct sna_output), 1);
if (!sna_output)
return -1;
@ -2783,36 +2813,6 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial)
VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_ids, sizeof(uint32_t)*sna_output->num_props));
VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_values, sizeof(uint64_t)*sna_output->num_props));
if (compat_conn.conn.connector_type < ARRAY_SIZE(output_names))
output_name = output_names[compat_conn.conn.connector_type];
else
output_name = "UNKNOWN";
len = snprintf(name, 32, "%s%d", output_name, compat_conn.conn.connector_type_id);
if (output_ignored(scrn, name))
return 0;
if (xf86IsEntityShared(scrn->entityList[0])) {
const char *str;
str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD);
if (str && !sna_zaphod_match(str, name)) {
DBG(("%s: zaphod mismatch, want %s, have %s\n", __FUNCTION__, str, name));
ret = 0;
goto cleanup;
}
if ((enc.possible_crtcs & (1 << scrn->confScreen->device->screen)) == 0) {
if (str) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"%s is an invalid output for screen (pipe) %d\n",
name, scrn->confScreen->device->screen);
}
goto cleanup;
}
enc.possible_crtcs = 1;
}
output = calloc(1, sizeof(*output) + len + 1);
if (!output)
goto cleanup;
@ -2889,7 +2889,7 @@ cleanup:
free(sna_output->prop_ids);
free(sna_output->prop_values);
free(sna_output);
return ret;
return -1;
}
static void sna_output_del(xf86OutputPtr output)