aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark2018-01-24 14:08:46 -0600
committerRob Clark2018-01-26 14:29:10 -0600
commit6f0f6cee5e9be1dcf816c144e05d26352c85a9e8 (patch)
tree8326e8b234c44da67b35444a4f4977f0d84b66cd
parent82aef5f0cbeb5145408f8c5979dc826937d51b7b (diff)
downloadexternal-libgbm-6f0f6cee5e9be1dcf816c144e05d26352c85a9e8.tar.gz
external-libgbm-6f0f6cee5e9be1dcf816c144e05d26352c85a9e8.tar.xz
external-libgbm-6f0f6cee5e9be1dcf816c144e05d26352c85a9e8.zip
freedreno: clamp priority based on # of rings
In case of a kernel that is new enough to support multiple submit- queues, but with an adreno generation which doesn't support multiple prioritized ringbuffers, we'd attempt to open a submit-queue with prio=1 (medium), which is rejected by the kernel. This could happen either w/ an older mesa (which uses fd_pipe_new()) or a newer mesa which defaults to prio=1 if no pipe context priority flags are set. The simple answer to fix both cases is to clamp the requested priority according to the number of rings. This might not do exactly what you want, if we hypothetically had 2 rings (it would result in requested medium priority being high priority instead of low priority). But the number of rings (for hw gen's that support this) is purely a software construct, so the easy answer there is to have the kernel advertise at least 3 rings if it supports more than one. There isn't really any reason to do otherwise. Signed-off-by: Rob Clark <robclark@freedesktop.org>
-rw-r--r--freedreno/freedreno_priv.h2
-rw-r--r--freedreno/msm/msm_pipe.c28
2 files changed, 18 insertions, 12 deletions
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h
index 27307472..199ccb94 100644
--- a/freedreno/freedreno_priv.h
+++ b/freedreno/freedreno_priv.h
@@ -49,6 +49,7 @@
49#include "xf86atomic.h" 49#include "xf86atomic.h"
50 50
51#include "util_double_list.h" 51#include "util_double_list.h"
52#include "util_math.h"
52 53
53#include "freedreno_drmif.h" 54#include "freedreno_drmif.h"
54#include "freedreno_ringbuffer.h" 55#include "freedreno_ringbuffer.h"
@@ -173,7 +174,6 @@ struct fd_bo {
173 time_t free_time; /* time when added to bucket-list */ 174 time_t free_time; /* time when added to bucket-list */
174}; 175};
175 176
176#define ALIGN(v,a) (((v) + (a) - 1) & ~((a) - 1))
177#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 177#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
178 178
179#define enable_debug 0 /* TODO make dynamic */ 179#define enable_debug 0 /* TODO make dynamic */
diff --git a/freedreno/msm/msm_pipe.c b/freedreno/msm/msm_pipe.c
index 7395e573..12e4be59 100644
--- a/freedreno/msm/msm_pipe.c
+++ b/freedreno/msm/msm_pipe.c
@@ -100,42 +100,48 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp,
100 return 0; 100 return 0;
101} 101}
102 102
103static int open_submitqueue(struct fd_device *dev, uint32_t prio, 103static int open_submitqueue(struct fd_pipe *pipe, uint32_t prio)
104 uint32_t *queue_id)
105{ 104{
106 struct drm_msm_submitqueue req = { 105 struct drm_msm_submitqueue req = {
107 .flags = 0, 106 .flags = 0,
108 .prio = prio, 107 .prio = prio,
109 }; 108 };
109 uint64_t nr_rings = 1;
110 int ret; 110 int ret;
111 111
112 if (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES) { 112 if (fd_device_version(pipe->dev) < FD_VERSION_SUBMIT_QUEUES) {
113 *queue_id = 0; 113 to_msm_pipe(pipe)->queue_id = 0;
114 return 0; 114 return 0;
115 } 115 }
116 116
117 ret = drmCommandWriteRead(dev->fd, DRM_MSM_SUBMITQUEUE_NEW, &req, sizeof(req)); 117 msm_pipe_get_param(pipe, FD_NR_RINGS, &nr_rings);
118
119 req.prio = MIN2(req.prio, MAX2(nr_rings, 1) - 1);
120
121 ret = drmCommandWriteRead(pipe->dev->fd, DRM_MSM_SUBMITQUEUE_NEW,
122 &req, sizeof(req));
118 if (ret) { 123 if (ret) {
119 ERROR_MSG("could not create submitqueue! %d (%s)", ret, strerror(errno)); 124 ERROR_MSG("could not create submitqueue! %d (%s)", ret, strerror(errno));
120 return ret; 125 return ret;
121 } 126 }
122 127
123 *queue_id = req.id; 128 to_msm_pipe(pipe)->queue_id = req.id;
124 return 0; 129 return 0;
125} 130}
126 131
127static void close_submitqueue(struct fd_device *dev, uint32_t queue_id) 132static void close_submitqueue(struct fd_pipe *pipe, uint32_t queue_id)
128{ 133{
129 if (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES) 134 if (fd_device_version(pipe->dev) < FD_VERSION_SUBMIT_QUEUES)
130 return; 135 return;
131 136
132 drmCommandWrite(dev->fd, DRM_MSM_SUBMITQUEUE_CLOSE, &queue_id, sizeof(queue_id)); 137 drmCommandWrite(pipe->dev->fd, DRM_MSM_SUBMITQUEUE_CLOSE,
138 &queue_id, sizeof(queue_id));
133} 139}
134 140
135static void msm_pipe_destroy(struct fd_pipe *pipe) 141static void msm_pipe_destroy(struct fd_pipe *pipe)
136{ 142{
137 struct msm_pipe *msm_pipe = to_msm_pipe(pipe); 143 struct msm_pipe *msm_pipe = to_msm_pipe(pipe);
138 close_submitqueue(pipe->dev, msm_pipe->queue_id); 144 close_submitqueue(pipe, msm_pipe->queue_id);
139 free(msm_pipe); 145 free(msm_pipe);
140} 146}
141 147
@@ -193,7 +199,7 @@ drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
193 INFO_MSG(" Chip-id: 0x%08x", msm_pipe->chip_id); 199 INFO_MSG(" Chip-id: 0x%08x", msm_pipe->chip_id);
194 INFO_MSG(" GMEM size: 0x%08x", msm_pipe->gmem); 200 INFO_MSG(" GMEM size: 0x%08x", msm_pipe->gmem);
195 201
196 if (open_submitqueue(dev, prio, &msm_pipe->queue_id)) 202 if (open_submitqueue(pipe, prio))
197 goto fail; 203 goto fail;
198 204
199 return pipe; 205 return pipe;