All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] drm: add interface to get drm devices on the system v3
@ 2015-08-17  3:09 Jammy Zhou
  2015-08-17  3:09 ` [PATCH 2/4] amdgpu: improve amdgpu_vamgr_init Jammy Zhou
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Jammy Zhou @ 2015-08-17  3:09 UTC (permalink / raw)
  To: dri-devel, Emil Velikov

From: Emil Velikov <emil.l.velikov@gmail.com>

For mutiple GPU support, the devices on the system should be enumerated
to get necessary information about each device, and the drmGetDevices
interface is added for this. Currently only PCI devices are supported for
the enumeration.

Typical usage:
int count;
drmDevicePtr *foo;
count = drmGetDevices(NULL, 0);
foo = calloc(count, sizeof(drmDevicePtr));
count = drmGetDevices(foo, count);
/* find proper device, open correct device node, etc */
drmFreeDevices(foo, count);
free(foo);

v2: change according to feedback from Emil
v3: fix the signed extension for PCI device info

Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com>
---
 xf86drm.c | 351 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 xf86drm.h |  34 ++++++
 2 files changed, 385 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 5e02969..7d9e5f9 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -55,6 +55,7 @@
 #ifdef HAVE_SYS_MKDEV_H
 # include <sys/mkdev.h> /* defines major(), minor(), and makedev() on Solaris */
 #endif
+#include <math.h>
 
 /* Not all systems have MAP_FAILED defined */
 #ifndef MAP_FAILED
@@ -2829,3 +2830,353 @@ char *drmGetRenderDeviceNameFromFd(int fd)
 {
 	return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
 }
+
+#ifdef __linux__
+static int drmParseSubsystemType(const char *str)
+{
+    char link[PATH_MAX + 1] = "";
+    char *name;
+
+    if (readlink(str, link, PATH_MAX) < 0)
+        return -EINVAL;
+
+    name = strrchr(link, '/');
+    if (!name)
+        return -EINVAL;
+
+    name++;
+
+    if (strncmp(name, "pci", 3) == 0)
+        return DRM_BUS_PCI;
+
+    return -EINVAL;
+}
+
+static int drmParsePciBusInfo(const char *str, drmPciBusInfoPtr info)
+{
+    int domain, bus, dev, func;
+    char *value;
+
+    if (str == NULL)
+        return -EINVAL;
+
+    value = strstr(str, "PCI_SLOT_NAME=");
+    if (value == NULL)
+        return -EINVAL;
+
+    value += strlen("PCI_SLOT_NAME=");
+
+    if (sscanf(value, "%04x:%02x:%02x.%1u",
+               &domain, &bus, &dev, &func) != 4)
+        return -EINVAL;
+
+    info->domain = domain;
+    info->bus = bus;
+    info->dev = dev;
+    info->func = func;
+
+    return 0;
+}
+
+static int drmSameDevice(drmDevicePtr a, drmDevicePtr b)
+{
+    if (a->bustype != b->bustype)
+        return 0;
+
+    switch (a->bustype) {
+    case DRM_BUS_PCI:
+        if (memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo)) == 0)
+            return 1;
+    default:
+        break;
+    }
+
+    return 0;
+}
+
+static int drmGetNodeType(const char *name)
+{
+    if (strncmp(name, DRM_PRIMARY_MINOR_NAME,
+        sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0)
+        return DRM_NODE_PRIMARY;
+
+    if (strncmp(name, DRM_CONTROL_MINOR_NAME,
+        sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0)
+        return DRM_NODE_CONTROL;
+
+    if (strncmp(name, DRM_RENDER_MINOR_NAME,
+        sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0)
+        return DRM_NODE_RENDER;
+
+    return -EINVAL;
+}
+
+static int drmParsePciDeviceInfo(const unsigned char *config,
+                                 drmPciDeviceInfoPtr device)
+{
+    if (config == NULL)
+        return -EINVAL;
+
+    device->vendor_id = config[0] | (config[1] << 8);
+    device->device_id = config[2] | (config[3] << 8);
+    device->revision_id = config[8];
+    device->subvendor_id = config[44] | (config[45] << 8);
+    device->subdevice_id = config[46] | (config[47] << 8);
+
+    return 0;
+}
+
+static void drmFreeDevice(drmDevicePtr device)
+{
+    int i;
+
+    if (device == NULL)
+        return;
+
+    if (device->nodes != NULL)
+        for (i = 0; i < DRM_NODE_MAX; i++)
+            free(device->nodes[i]);
+
+    free(device->nodes);
+    free(device->businfo.pci);
+    free(device->deviceinfo.pci);
+}
+
+void drmFreeDevices(drmDevicePtr devices[], int count)
+{
+    int i;
+
+    if (devices == NULL)
+        return;
+
+    for (i = 0; i < count; i++) {
+        drmFreeDevice(devices[i]);
+        free(devices[i]);
+        devices[i] = NULL;
+    }
+}
+
+/**
+ * Get drm devices on the system
+ *
+ * \param devices the array of devices with drmDevicePtr elements
+ *                can be NULL to get the device number first
+ * \param max_devices the maximum number of devices for the array
+ *
+ * \return on error - negative error code,
+ *         if devices is NULL - total number of devices available on the system,
+ *         alternatively the number of devices stored in devices[], which is
+ *         capped by the max_devices.
+ */
+int drmGetDevices(drmDevicePtr devices[], int max_devices)
+{
+    drmDevicePtr devs = NULL;
+    drmPciBusInfoPtr pcibus = NULL;
+    drmPciDeviceInfoPtr pcidevice = NULL;
+    DIR *sysdir = NULL;
+    struct dirent *dent = NULL;
+    struct stat sbuf = {0};
+    char node[PATH_MAX + 1] = "";
+    char path[PATH_MAX + 1] = "";
+    char data[128] = "";
+    unsigned char config[64] = "";
+    int node_type, subsystem_type;
+    int maj, min;
+    int fd;
+    int ret, i = 0, j, node_count, device_count = 0;
+    int max_count = 16;
+    int *duplicated = NULL;
+
+    devs = calloc(max_count, sizeof(*devs));
+    if (devs == NULL)
+        return -ENOMEM;
+
+    sysdir = opendir(DRM_DIR_NAME);
+    if (!sysdir) {
+        ret = -errno;
+        goto free_locals;
+    }
+
+    while ((dent = readdir(sysdir))) {
+        node_type = drmGetNodeType(dent->d_name);
+        if (node_type < 0)
+            continue;
+
+        snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name);
+        if (stat(node, &sbuf))
+            continue;
+
+        maj = major(sbuf.st_rdev);
+        min = minor(sbuf.st_rdev);
+
+        if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+            continue;
+
+        snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/subsystem",
+                 maj, min);
+        subsystem_type = drmParseSubsystemType(path);
+
+        if (subsystem_type < 0)
+            continue;
+
+        switch (subsystem_type) {
+        case DRM_BUS_PCI:
+            pcibus = calloc(1, sizeof(*pcibus));
+            if (pcibus == NULL) {
+                ret = -ENOMEM;
+                goto free_locals;
+            }
+
+            snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/uevent",
+                     maj, min);
+            fd = open(path, O_RDONLY);
+            if (fd < 0) {
+                ret = -errno;
+                goto free_locals;
+            }
+            ret = read(fd, data, sizeof(data));
+            if (ret < 0) {
+                ret = -errno;
+                close(fd);
+                goto free_locals;
+            }
+
+            ret = drmParsePciBusInfo(data, pcibus);
+            close(fd);
+            if (ret)
+                goto free_locals;
+
+            if (i >= max_count) {
+                max_count += 16;
+                devs = realloc(devs, max_count * sizeof(*devs));
+            }
+
+            devs[i].businfo.pci = pcibus;
+            devs[i].bustype = subsystem_type;
+            devs[i].nodes = calloc(DRM_NODE_MAX, sizeof(char *));
+            if (devs[i].nodes == NULL) {
+                ret = -ENOMEM;
+                goto free_locals;
+            }
+            devs[i].nodes[node_type] = strdup(node);
+            if (devs[i].nodes[node_type] == NULL) {
+                ret = -ENOMEM;
+                goto free_locals;
+            }
+            devs[i].available_nodes = 1 << node_type;
+
+            if (devices != NULL) {
+                snprintf(path, PATH_MAX, "/sys/class/drm/%s/device/config",
+                         dent->d_name);
+                fd = open(path, O_RDONLY);
+                if (fd < 0) {
+                     ret = -errno;
+                     goto free_locals;
+                }
+                ret = read(fd, config, 64);
+                if (ret < 0) {
+                    ret = -errno;
+                    close(fd);
+                    goto free_locals;
+                }
+
+                pcidevice = calloc(1, sizeof(*pcidevice));
+                if (pcidevice == NULL) {
+                    ret = -ENOMEM;
+                    goto free_locals;
+                }
+
+                ret = drmParsePciDeviceInfo(config, pcidevice);
+                if (ret)
+                    goto free_locals;
+
+                devs[i].deviceinfo.pci = pcidevice;
+                close(fd);
+            }
+            break;
+        default:
+            fprintf(stderr, "The subsystem type is not supported yet\n");
+            break;
+        }
+        i++;
+    }
+
+    node_count = i;
+
+    /* merge duplicated devices with same domain/bus/device/func IDs */
+    duplicated = calloc(node_count, sizeof(*duplicated));
+    if (duplicated == NULL) {
+        ret = -ENOMEM;
+        goto free_locals;
+    }
+
+    for (i = 0; i < node_count; i++) {
+        for (j = i+1; j < node_count; j++) {
+            if (duplicated[i] || duplicated[j])
+                continue;
+            if (drmSameDevice(&devs[i], &devs[j])) {
+                duplicated[j] = 1;
+                devs[i].available_nodes |= devs[j].available_nodes;
+                node_type = log2(devs[j].available_nodes);
+                devs[i].nodes[node_type] = devs[j].nodes[node_type];
+                free(devs[j].nodes);
+                free(devs[j].businfo.pci);
+                free(devs[j].deviceinfo.pci);
+            }
+        }
+    }
+
+    for (i = 0; i < node_count; i++) {
+        if(duplicated[i] == 0) {
+            if ((devices != NULL) && (device_count < max_devices)) {
+                devices[device_count] = calloc(1, sizeof(drmDevice));
+                if (devices[device_count] == NULL) {
+                    ret = -ENOMEM;
+                    break;
+                }
+                memcpy(devices[device_count], &devs[i], sizeof(drmDevice));
+            } else
+                drmFreeDevice(&devs[i]);
+            device_count++;
+        }
+    }
+
+    if (i < node_count) {
+        drmFreeDevices(devices, device_count);
+        for ( ; i < node_count; i++)
+            if(duplicated[i] == 0)
+                drmFreeDevice(&devs[i]);
+    } else
+        ret = device_count;
+
+    free(duplicated);
+    free(devs);
+    closedir(sysdir);
+    return ret;
+
+free_locals:
+    for (j = 0; j < i; j++)
+        drmFreeDevice(&devs[j]);
+    free(pcidevice);
+    free(pcibus);
+    free(devs);
+    closedir(sysdir);
+    return ret;
+}
+#else
+void drmFreeDevices(drmDevicePtr devices[], int count)
+{
+    (void)devices;
+    (void)count;
+}
+
+int drmGetDevices(drmDevicePtr devices[], int max_devices)
+{
+    (void)devices;
+    (void)max_devices;
+    return -EINVAL;
+}
+
+#warning "Missing implementation of drmGetDevices/drmFreeDevices"
+
+#endif
diff --git a/xf86drm.h b/xf86drm.h
index 360e04a..e82ca84 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -563,6 +563,8 @@ extern int           drmOpen(const char *name, const char *busid);
 #define DRM_NODE_PRIMARY 0
 #define DRM_NODE_CONTROL 1
 #define DRM_NODE_RENDER  2
+#define DRM_NODE_MAX     3
+
 extern int           drmOpenWithType(const char *name, const char *busid,
                                      int type);
 
@@ -759,6 +761,38 @@ extern int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle);
 extern char *drmGetPrimaryDeviceNameFromFd(int fd);
 extern char *drmGetRenderDeviceNameFromFd(int fd);
 
+#define DRM_BUS_PCI   0
+
+typedef struct _drmPciBusInfo {
+    uint16_t domain;
+    uint8_t bus;
+    uint8_t dev;
+    uint8_t func;
+} drmPciBusInfo, *drmPciBusInfoPtr;
+
+typedef struct _drmPciDeviceInfo {
+    uint16_t vendor_id;
+    uint16_t device_id;
+    uint16_t subvendor_id;
+    uint16_t subdevice_id;
+    uint8_t revision_id;
+} drmPciDeviceInfo, *drmPciDeviceInfoPtr;
+
+typedef struct _drmDevice {
+    char **nodes; /* DRM_NODE_MAX sized array */
+    int available_nodes; /* DRM_NODE_* bitmask */
+    int bustype;
+    union {
+        drmPciBusInfoPtr pci;
+    } businfo;
+    union {
+        drmPciDeviceInfoPtr pci;
+    } deviceinfo;
+} drmDevice, *drmDevicePtr;
+
+extern int drmGetDevices(drmDevicePtr devices[], int max_devices);
+extern void drmFreeDevices(drmDevicePtr devices[], int count);
+
 #if defined(__cplusplus)
 }
 #endif
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4] amdgpu: improve amdgpu_vamgr_init
  2015-08-17  3:09 [PATCH 1/4] drm: add interface to get drm devices on the system v3 Jammy Zhou
@ 2015-08-17  3:09 ` Jammy Zhou
  2015-08-17 20:36   ` Alex Deucher
  2015-08-17  3:09 ` [PATCH 3/4] amdgpu: add flag to support 32bit VA address v4 Jammy Zhou
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Jammy Zhou @ 2015-08-17  3:09 UTC (permalink / raw)
  To: dri-devel, Emil Velikov

Make it a generic function independent of the device info.

Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 amdgpu/amdgpu_vamgr.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index cc4a1c4..71fd2b1 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -46,11 +46,12 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
 	return -EINVAL;
 }
 
-static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, struct amdgpu_device *dev)
+static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+			      uint64_t max, uint64_t alignment)
 {
-	mgr->va_offset = dev->dev_info.virtual_address_offset;
-	mgr->va_max = dev->dev_info.virtual_address_max;
-	mgr->va_alignment = dev->dev_info.virtual_address_alignment;
+	mgr->va_offset = start;
+	mgr->va_max = max;
+	mgr->va_alignment = alignment;
 
 	list_inithead(&mgr->va_holes);
 	pthread_mutex_init(&mgr->bo_va_mutex, NULL);
@@ -72,7 +73,9 @@ drm_private struct amdgpu_bo_va_mgr * amdgpu_vamgr_get_global(struct amdgpu_devi
 	ref = atomic_inc_return(&vamgr.refcount);
 
 	if (ref == 1)
-		amdgpu_vamgr_init(&vamgr, dev);
+		amdgpu_vamgr_init(&vamgr, dev->dev_info.virtual_address_offset,
+				  dev->dev_info.virtual_address_max,
+				  dev->dev_info.virtual_address_alignment);
 	return &vamgr;
 }
 
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4] amdgpu: add flag to support 32bit VA address v4
  2015-08-17  3:09 [PATCH 1/4] drm: add interface to get drm devices on the system v3 Jammy Zhou
  2015-08-17  3:09 ` [PATCH 2/4] amdgpu: improve amdgpu_vamgr_init Jammy Zhou
@ 2015-08-17  3:09 ` Jammy Zhou
  2015-08-17  3:09 ` [PATCH 4/4] amdgpu: make vamgr per device v2 Jammy Zhou
  2015-08-17 14:12 ` [PATCH 1/4] drm: add interface to get drm devices on the system v3 Emil Velikov
  3 siblings, 0 replies; 10+ messages in thread
From: Jammy Zhou @ 2015-08-17  3:09 UTC (permalink / raw)
  To: dri-devel, Emil Velikov

The AMDGPU_VA_RANGE_32_BIT flag is added to request VA range in the
32bit address space for amdgpu_va_range_alloc.

The 32bit address space is reserved at initialization time, and managed
with a separate VAMGR as part of the global VAMGR. And if no enough VA
space available in range above 4GB, this reserved range can be used as
fallback.

v2: add comment for AMDGPU_VA_RANGE_32_BIT, and add vamgr to va_range
v3: rebase to Emil's drm_private series
v4: fix one warning

Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 amdgpu/amdgpu.h          |  5 +++++
 amdgpu/amdgpu_device.c   | 20 ++++++++++++++++++++
 amdgpu/amdgpu_internal.h |  9 +++++++++
 amdgpu/amdgpu_vamgr.c    | 32 +++++++++++++++++++++++++-------
 4 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index a90c1ac..1e633e3 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1075,6 +1075,11 @@ int amdgpu_read_mm_registers(amdgpu_device_handle dev, unsigned dword_offset,
 			     uint32_t *values);
 
 /**
+ * Flag to request VA address range in the 32bit address space
+*/
+#define AMDGPU_VA_RANGE_32_BIT		0x1
+
+/**
  * Allocate virtual address range
  *
  * \param dev - [in] Device handle. See #amdgpu_device_initialize()
diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index b977847..0ef1d31 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -44,6 +44,7 @@
 #include "amdgpu_drm.h"
 #include "amdgpu_internal.h"
 #include "util_hash_table.h"
+#include "util_math.h"
 
 #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
 #define UINT_TO_PTR(x) ((void *)((intptr_t)(x)))
@@ -174,6 +175,7 @@ int amdgpu_device_initialize(int fd,
 	int flag_auth = 0;
 	int flag_authexist=0;
 	uint32_t accel_working = 0;
+	uint64_t start, max;
 
 	*device_handle = NULL;
 
@@ -252,6 +254,19 @@ int amdgpu_device_initialize(int fd,
 
 	dev->vamgr = amdgpu_vamgr_get_global(dev);
 
+	max = MIN2(dev->dev_info.virtual_address_max, 0xffffffff);
+	start = amdgpu_vamgr_find_va(dev->vamgr,
+				     max - dev->dev_info.virtual_address_offset,
+				     dev->dev_info.virtual_address_alignment, 0);
+	if (start > 0xffffffff)
+		goto free_va; /* shouldn't get here */
+
+	dev->vamgr_32 =  calloc(1, sizeof(struct amdgpu_bo_va_mgr));
+	if (dev->vamgr_32 == NULL)
+		goto free_va;
+	amdgpu_vamgr_init(dev->vamgr_32, start, max,
+			  dev->dev_info.virtual_address_alignment);
+
 	*major_version = dev->major_version;
 	*minor_version = dev->minor_version;
 	*device_handle = dev;
@@ -260,6 +275,11 @@ int amdgpu_device_initialize(int fd,
 
 	return 0;
 
+free_va:
+	r = -ENOMEM;
+	amdgpu_vamgr_free_va(dev->vamgr, start,
+			     max - dev->dev_info.virtual_address_offset);
+
 cleanup:
 	if (dev->fd >= 0)
 		close(dev->fd);
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index 92eb5ec..ca155be 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -65,6 +65,7 @@ struct amdgpu_va {
 	uint64_t address;
 	uint64_t size;
 	enum amdgpu_gpu_va_range range;
+	struct amdgpu_bo_va_mgr *vamgr;
 };
 
 struct amdgpu_device {
@@ -82,7 +83,10 @@ struct amdgpu_device {
 	pthread_mutex_t bo_table_mutex;
 	struct drm_amdgpu_info_device dev_info;
 	struct amdgpu_gpu_info info;
+	/** The global VA manager for the whole virtual address space */
 	struct amdgpu_bo_va_mgr *vamgr;
+	/** The VA manager for the 32bit address space */
+	struct amdgpu_bo_va_mgr *vamgr_32;
 };
 
 struct amdgpu_bo {
@@ -124,6 +128,11 @@ drm_private struct amdgpu_bo_va_mgr* amdgpu_vamgr_get_global(struct amdgpu_devic
 
 drm_private void amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst, struct amdgpu_bo_va_mgr *src);
 
+drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+		       uint64_t max, uint64_t alignment);
+
+drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr);
+
 drm_private uint64_t amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
 				uint64_t alignment, uint64_t base_required);
 
diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index 71fd2b1..698826d 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -46,7 +46,7 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
 	return -EINVAL;
 }
 
-static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
 			      uint64_t max, uint64_t alignment)
 {
 	mgr->va_offset = start;
@@ -57,7 +57,7 @@ static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
 	pthread_mutex_init(&mgr->bo_va_mutex, NULL);
 }
 
-static void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr)
+drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr)
 {
 	struct amdgpu_bo_va_hole *hole;
 	LIST_FOR_EACH_ENTRY(hole, &mgr->va_holes, list) {
@@ -252,23 +252,39 @@ int amdgpu_va_range_alloc(amdgpu_device_handle dev,
 			  amdgpu_va_handle *va_range_handle,
 			  uint64_t flags)
 {
-	va_base_alignment = MAX2(va_base_alignment, dev->vamgr->va_alignment);
-	size = ALIGN(size, vamgr.va_alignment);
+	struct amdgpu_bo_va_mgr *vamgr;
 
-	*va_base_allocated = amdgpu_vamgr_find_va(dev->vamgr, size,
+	if (flags & AMDGPU_VA_RANGE_32_BIT)
+		vamgr = dev->vamgr_32;
+	else
+		vamgr = dev->vamgr;
+
+	va_base_alignment = MAX2(va_base_alignment, vamgr->va_alignment);
+	size = ALIGN(size, vamgr->va_alignment);
+
+	*va_base_allocated = amdgpu_vamgr_find_va(vamgr, size,
+					va_base_alignment, va_base_required);
+
+	if (!(flags & AMDGPU_VA_RANGE_32_BIT) &&
+	    (*va_base_allocated == AMDGPU_INVALID_VA_ADDRESS)) {
+		/* fallback to 32bit address */
+		vamgr = dev->vamgr_32;
+		*va_base_allocated = amdgpu_vamgr_find_va(vamgr, size,
 					va_base_alignment, va_base_required);
+	}
 
 	if (*va_base_allocated != AMDGPU_INVALID_VA_ADDRESS) {
 		struct amdgpu_va* va;
 		va = calloc(1, sizeof(struct amdgpu_va));
 		if(!va){
-			amdgpu_vamgr_free_va(dev->vamgr, *va_base_allocated, size);
+			amdgpu_vamgr_free_va(vamgr, *va_base_allocated, size);
 			return -ENOMEM;
 		}
 		va->dev = dev;
 		va->address = *va_base_allocated;
 		va->size = size;
 		va->range = va_range_type;
+		va->vamgr = vamgr;
 		*va_range_handle = va;
 	} else {
 		return -EINVAL;
@@ -281,7 +297,9 @@ int amdgpu_va_range_free(amdgpu_va_handle va_range_handle)
 {
 	if(!va_range_handle || !va_range_handle->address)
 		return 0;
-	amdgpu_vamgr_free_va(va_range_handle->dev->vamgr, va_range_handle->address,
+
+	amdgpu_vamgr_free_va(va_range_handle->vamgr,
+			va_range_handle->address,
 			va_range_handle->size);
 	free(va_range_handle);
 	return 0;
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4] amdgpu: make vamgr per device v2
  2015-08-17  3:09 [PATCH 1/4] drm: add interface to get drm devices on the system v3 Jammy Zhou
  2015-08-17  3:09 ` [PATCH 2/4] amdgpu: improve amdgpu_vamgr_init Jammy Zhou
  2015-08-17  3:09 ` [PATCH 3/4] amdgpu: add flag to support 32bit VA address v4 Jammy Zhou
@ 2015-08-17  3:09 ` Jammy Zhou
  2015-08-17 14:12 ` [PATCH 1/4] drm: add interface to get drm devices on the system v3 Emil Velikov
  3 siblings, 0 replies; 10+ messages in thread
From: Jammy Zhou @ 2015-08-17  3:09 UTC (permalink / raw)
  To: dri-devel, Emil Velikov

Each device can have its own vamgr, so make it per device now.
This can fix the failure with multiple GPUs used in one single
process.

v2: rebase

Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 amdgpu/amdgpu_device.c   | 13 +++++++++++--
 amdgpu/amdgpu_internal.h |  5 -----
 amdgpu/amdgpu_vamgr.c    | 24 +-----------------------
 3 files changed, 12 insertions(+), 30 deletions(-)

diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index 0ef1d31..d5f65e5 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -131,7 +131,8 @@ static int amdgpu_get_auth(int fd, int *auth)
 
 static void amdgpu_device_free_internal(amdgpu_device_handle dev)
 {
-	amdgpu_vamgr_reference(&dev->vamgr, NULL);
+	amdgpu_vamgr_deinit(dev->vamgr);
+	free(dev->vamgr);
 	util_hash_table_destroy(dev->bo_flink_names);
 	util_hash_table_destroy(dev->bo_handles);
 	pthread_mutex_destroy(&dev->bo_table_mutex);
@@ -252,7 +253,13 @@ int amdgpu_device_initialize(int fd,
 	if (r)
 		goto cleanup;
 
-	dev->vamgr = amdgpu_vamgr_get_global(dev);
+	dev->vamgr = calloc(1, sizeof(struct amdgpu_bo_va_mgr));
+	if (dev->vamgr == NULL)
+		goto cleanup;
+
+	amdgpu_vamgr_init(dev->vamgr, dev->dev_info.virtual_address_offset,
+			  dev->dev_info.virtual_address_max,
+			  dev->dev_info.virtual_address_alignment);
 
 	max = MIN2(dev->dev_info.virtual_address_max, 0xffffffff);
 	start = amdgpu_vamgr_find_va(dev->vamgr,
@@ -279,6 +286,8 @@ free_va:
 	r = -ENOMEM;
 	amdgpu_vamgr_free_va(dev->vamgr, start,
 			     max - dev->dev_info.virtual_address_offset);
+	amdgpu_vamgr_deinit(dev->vamgr);
+	free(dev->vamgr);
 
 cleanup:
 	if (dev->fd >= 0)
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index ca155be..cb06dbf 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -51,7 +51,6 @@ struct amdgpu_bo_va_hole {
 };
 
 struct amdgpu_bo_va_mgr {
-	atomic_t refcount;
 	/* the start virtual address */
 	uint64_t va_offset;
 	uint64_t va_max;
@@ -124,10 +123,6 @@ struct amdgpu_context {
 
 drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo);
 
-drm_private struct amdgpu_bo_va_mgr* amdgpu_vamgr_get_global(struct amdgpu_device *dev);
-
-drm_private void amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst, struct amdgpu_bo_va_mgr *src);
-
 drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
 		       uint64_t max, uint64_t alignment);
 
diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index 698826d..659e6c8 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -33,8 +33,6 @@
 #include "amdgpu_internal.h"
 #include "util_math.h"
 
-static struct amdgpu_bo_va_mgr vamgr = {{0}};
-
 int amdgpu_va_range_query(amdgpu_device_handle dev,
 			  enum amdgpu_gpu_va_range type, uint64_t *start, uint64_t *end)
 {
@@ -67,26 +65,6 @@ drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr)
 	pthread_mutex_destroy(&mgr->bo_va_mutex);
 }
 
-drm_private struct amdgpu_bo_va_mgr * amdgpu_vamgr_get_global(struct amdgpu_device *dev)
-{
-	int ref;
-	ref = atomic_inc_return(&vamgr.refcount);
-
-	if (ref == 1)
-		amdgpu_vamgr_init(&vamgr, dev->dev_info.virtual_address_offset,
-				  dev->dev_info.virtual_address_max,
-				  dev->dev_info.virtual_address_alignment);
-	return &vamgr;
-}
-
-drm_private void amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst,
-				struct amdgpu_bo_va_mgr *src)
-{
-	if (update_references(&(*dst)->refcount, NULL))
-		amdgpu_vamgr_deinit(*dst);
-	*dst = src;
-}
-
 drm_private uint64_t amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
 				uint64_t alignment, uint64_t base_required)
 {
@@ -102,7 +80,7 @@ drm_private uint64_t amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t
 	pthread_mutex_lock(&mgr->bo_va_mutex);
 	/* TODO: using more appropriate way to track the holes */
 	/* first look for a hole */
-	LIST_FOR_EACH_ENTRY_SAFE(hole, n, &vamgr.va_holes, list) {
+	LIST_FOR_EACH_ENTRY_SAFE(hole, n, &mgr->va_holes, list) {
 		if (base_required) {
 			if(hole->offset > base_required ||
 				(hole->offset + hole->size) < (base_required + size))
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] drm: add interface to get drm devices on the system v3
  2015-08-17  3:09 [PATCH 1/4] drm: add interface to get drm devices on the system v3 Jammy Zhou
                   ` (2 preceding siblings ...)
  2015-08-17  3:09 ` [PATCH 4/4] amdgpu: make vamgr per device v2 Jammy Zhou
@ 2015-08-17 14:12 ` Emil Velikov
  2015-08-20  3:02   ` Zhou, Jammy
  3 siblings, 1 reply; 10+ messages in thread
From: Emil Velikov @ 2015-08-17 14:12 UTC (permalink / raw)
  To: Jammy Zhou; +Cc: ML dri-devel

On 17 August 2015 at 04:09, Jammy Zhou <Jammy.Zhou@amd.com> wrote:
> From: Emil Velikov <emil.l.velikov@gmail.com>
>
> For mutiple GPU support, the devices on the system should be enumerated
> to get necessary information about each device, and the drmGetDevices
> interface is added for this. Currently only PCI devices are supported for
> the enumeration.
>
> Typical usage:
> int count;
> drmDevicePtr *foo;
> count = drmGetDevices(NULL, 0);
> foo = calloc(count, sizeof(drmDevicePtr));
> count = drmGetDevices(foo, count);
> /* find proper device, open correct device node, etc */
> drmFreeDevices(foo, count);
> free(foo);
>
> v2: change according to feedback from Emil
> v3: fix the signed extension for PCI device info
>
Thanks Jammy. That's better.

As I would suspect the amdgpu changes to be urgent, can we leave this
around for a few more days. I'd suspect some (potential) users will
want to like to take a look.

-Emil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] amdgpu: improve amdgpu_vamgr_init
  2015-08-17  3:09 ` [PATCH 2/4] amdgpu: improve amdgpu_vamgr_init Jammy Zhou
@ 2015-08-17 20:36   ` Alex Deucher
  2015-08-18  2:08     ` Zhou, Jammy
  0 siblings, 1 reply; 10+ messages in thread
From: Alex Deucher @ 2015-08-17 20:36 UTC (permalink / raw)
  To: Jammy Zhou; +Cc: Emil Velikov, Maling list - DRI developers

On Sun, Aug 16, 2015 at 11:09 PM, Jammy Zhou <Jammy.Zhou@amd.com> wrote:
> Make it a generic function independent of the device info.
>
> Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com>
> Reviewed-by: Christian König <christian.koenig@amd.com>
> ---

I pushed patches 2-4.

Alex


>  amdgpu/amdgpu_vamgr.c | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
> index cc4a1c4..71fd2b1 100644
> --- a/amdgpu/amdgpu_vamgr.c
> +++ b/amdgpu/amdgpu_vamgr.c
> @@ -46,11 +46,12 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
>         return -EINVAL;
>  }
>
> -static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, struct amdgpu_device *dev)
> +static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
> +                             uint64_t max, uint64_t alignment)
>  {
> -       mgr->va_offset = dev->dev_info.virtual_address_offset;
> -       mgr->va_max = dev->dev_info.virtual_address_max;
> -       mgr->va_alignment = dev->dev_info.virtual_address_alignment;
> +       mgr->va_offset = start;
> +       mgr->va_max = max;
> +       mgr->va_alignment = alignment;
>
>         list_inithead(&mgr->va_holes);
>         pthread_mutex_init(&mgr->bo_va_mutex, NULL);
> @@ -72,7 +73,9 @@ drm_private struct amdgpu_bo_va_mgr * amdgpu_vamgr_get_global(struct amdgpu_devi
>         ref = atomic_inc_return(&vamgr.refcount);
>
>         if (ref == 1)
> -               amdgpu_vamgr_init(&vamgr, dev);
> +               amdgpu_vamgr_init(&vamgr, dev->dev_info.virtual_address_offset,
> +                                 dev->dev_info.virtual_address_max,
> +                                 dev->dev_info.virtual_address_alignment);
>         return &vamgr;
>  }
>
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH 2/4] amdgpu: improve amdgpu_vamgr_init
  2015-08-17 20:36   ` Alex Deucher
@ 2015-08-18  2:08     ` Zhou, Jammy
  0 siblings, 0 replies; 10+ messages in thread
From: Zhou, Jammy @ 2015-08-18  2:08 UTC (permalink / raw)
  To: Alex Deucher; +Cc: Emil Velikov, Maling list - DRI developers

Excellent. Thanks Alex.

Regards,
Jammy

-----Original Message-----
From: Alex Deucher [mailto:alexdeucher@gmail.com] 
Sent: Tuesday, August 18, 2015 4:36 AM
To: Zhou, Jammy
Cc: Maling list - DRI developers; Emil Velikov
Subject: Re: [PATCH 2/4] amdgpu: improve amdgpu_vamgr_init

On Sun, Aug 16, 2015 at 11:09 PM, Jammy Zhou <Jammy.Zhou@amd.com> wrote:
> Make it a generic function independent of the device info.
>
> Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com>
> Reviewed-by: Christian König <christian.koenig@amd.com>
> ---

I pushed patches 2-4.

Alex


>  amdgpu/amdgpu_vamgr.c | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c index 
> cc4a1c4..71fd2b1 100644
> --- a/amdgpu/amdgpu_vamgr.c
> +++ b/amdgpu/amdgpu_vamgr.c
> @@ -46,11 +46,12 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
>         return -EINVAL;
>  }
>
> -static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, struct 
> amdgpu_device *dev)
> +static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
> +                             uint64_t max, uint64_t alignment)
>  {
> -       mgr->va_offset = dev->dev_info.virtual_address_offset;
> -       mgr->va_max = dev->dev_info.virtual_address_max;
> -       mgr->va_alignment = dev->dev_info.virtual_address_alignment;
> +       mgr->va_offset = start;
> +       mgr->va_max = max;
> +       mgr->va_alignment = alignment;
>
>         list_inithead(&mgr->va_holes);
>         pthread_mutex_init(&mgr->bo_va_mutex, NULL); @@ -72,7 +73,9 @@ 
> drm_private struct amdgpu_bo_va_mgr * amdgpu_vamgr_get_global(struct amdgpu_devi
>         ref = atomic_inc_return(&vamgr.refcount);
>
>         if (ref == 1)
> -               amdgpu_vamgr_init(&vamgr, dev);
> +               amdgpu_vamgr_init(&vamgr, dev->dev_info.virtual_address_offset,
> +                                 dev->dev_info.virtual_address_max,
> +                                 
> + dev->dev_info.virtual_address_alignment);
>         return &vamgr;
>  }
>
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH 1/4] drm: add interface to get drm devices on the system v3
  2015-08-17 14:12 ` [PATCH 1/4] drm: add interface to get drm devices on the system v3 Emil Velikov
@ 2015-08-20  3:02   ` Zhou, Jammy
  2015-08-20 16:27     ` Emil Velikov
  0 siblings, 1 reply; 10+ messages in thread
From: Zhou, Jammy @ 2015-08-20  3:02 UTC (permalink / raw)
  To: Emil Velikov; +Cc: ML dri-devel

Hi Emil,

Can I get you RB now? It looks like there was no more comment from others.

Regards,
Jammy

-----Original Message-----
From: Emil Velikov [mailto:emil.l.velikov@gmail.com] 
Sent: Monday, August 17, 2015 10:13 PM
To: Zhou, Jammy
Cc: ML dri-devel
Subject: Re: [PATCH 1/4] drm: add interface to get drm devices on the system v3

On 17 August 2015 at 04:09, Jammy Zhou <Jammy.Zhou@amd.com> wrote:
> From: Emil Velikov <emil.l.velikov@gmail.com>
>
> For mutiple GPU support, the devices on the system should be 
> enumerated to get necessary information about each device, and the 
> drmGetDevices interface is added for this. Currently only PCI devices 
> are supported for the enumeration.
>
> Typical usage:
> int count;
> drmDevicePtr *foo;
> count = drmGetDevices(NULL, 0);
> foo = calloc(count, sizeof(drmDevicePtr)); count = drmGetDevices(foo, 
> count);
> /* find proper device, open correct device node, etc */ 
> drmFreeDevices(foo, count); free(foo);
>
> v2: change according to feedback from Emil
> v3: fix the signed extension for PCI device info
>
Thanks Jammy. That's better.

As I would suspect the amdgpu changes to be urgent, can we leave this around for a few more days. I'd suspect some (potential) users will want to like to take a look.

-Emil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] drm: add interface to get drm devices on the system v3
  2015-08-20  3:02   ` Zhou, Jammy
@ 2015-08-20 16:27     ` Emil Velikov
  2015-08-21  3:26       ` Zhou, Jammy
  0 siblings, 1 reply; 10+ messages in thread
From: Emil Velikov @ 2015-08-20 16:27 UTC (permalink / raw)
  To: Zhou, Jammy; +Cc: ML dri-devel

On 20 August 2015 at 04:02, Zhou, Jammy <Jammy.Zhou@amd.com> wrote:
> Hi Emil,
>
> Can I get you RB now? It looks like there was no more comment from others.
>
I'll ping (again) one the possible users and if we haven't heard any
objection by tomorrow midday I'll commit it to master.

Cheers,
Emil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH 1/4] drm: add interface to get drm devices on the system v3
  2015-08-20 16:27     ` Emil Velikov
@ 2015-08-21  3:26       ` Zhou, Jammy
  0 siblings, 0 replies; 10+ messages in thread
From: Zhou, Jammy @ 2015-08-21  3:26 UTC (permalink / raw)
  To: Emil Velikov; +Cc: ML dri-devel

Excellent. Thanks a lot.

Regards,
Jammy

-----Original Message-----
From: Emil Velikov [mailto:emil.l.velikov@gmail.com] 
Sent: Friday, August 21, 2015 12:28 AM
To: Zhou, Jammy
Cc: ML dri-devel
Subject: Re: [PATCH 1/4] drm: add interface to get drm devices on the system v3

On 20 August 2015 at 04:02, Zhou, Jammy <Jammy.Zhou@amd.com> wrote:
> Hi Emil,
>
> Can I get you RB now? It looks like there was no more comment from others.
>
I'll ping (again) one the possible users and if we haven't heard any objection by tomorrow midday I'll commit it to master.

Cheers,
Emil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-08-21  3:26 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-17  3:09 [PATCH 1/4] drm: add interface to get drm devices on the system v3 Jammy Zhou
2015-08-17  3:09 ` [PATCH 2/4] amdgpu: improve amdgpu_vamgr_init Jammy Zhou
2015-08-17 20:36   ` Alex Deucher
2015-08-18  2:08     ` Zhou, Jammy
2015-08-17  3:09 ` [PATCH 3/4] amdgpu: add flag to support 32bit VA address v4 Jammy Zhou
2015-08-17  3:09 ` [PATCH 4/4] amdgpu: make vamgr per device v2 Jammy Zhou
2015-08-17 14:12 ` [PATCH 1/4] drm: add interface to get drm devices on the system v3 Emil Velikov
2015-08-20  3:02   ` Zhou, Jammy
2015-08-20 16:27     ` Emil Velikov
2015-08-21  3:26       ` Zhou, Jammy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.