diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-16 18:48:00 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-16 18:48:00 -0500 |
commit | 796e1c55717e9a6ff5c81b12289ffa1ffd919b6f (patch) | |
tree | 27ce45cb1227156b72c641dbcbf2b399d23ba63d /drivers/gpu/drm/i915/i915_gem.c | |
parent | 8c334ce8f0fec7122fc3059c52a697b669a01b41 (diff) | |
parent | 45ee2dbc65cbf6910892c480e6f428be342fa733 (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"This is the main drm pull, it has a shared branch with some alsa
crossover but everything should be acked by relevant people.
New drivers:
- ATMEL HLCDC driver
- designware HDMI core support (used in multiple SoCs).
core:
- lots more atomic modesetting work, properties and atomic ioctl
(hidden under option)
- bridge rework allows support for Samsung exynos chromebooks to
work finally.
- some more panels supported
i915:
- atomic plane update support
- DSI uses shared DSI infrastructure
- Skylake basic support is all merged now
- component framework used for i915/snd-hda interactions
- write-combine cpu memory mappings
- engine init code refactored
- full ppgtt enabled where execlists are enabled.
- cherryview rps/gpu turbo and pipe CRC support.
radeon:
- indirect draw support for evergreen/cayman
- SMC and manual fan control for SI/CI
- Displayport audio support
amdkfd:
- SDMA usermode queue support
- replace suballocator usage with more suitable one
- rework for allowing interfacing to more than radeon
nouveau:
- major renaming in prep for later splitting work
- merge arm platform driver into nouveau
- GK20A reclocking support
msm:
- conversion to atomic modesetting
- YUV support for mdp4/5
- eDP support
- hw cursor for mdp5
tegra:
- conversion to atomic modesetting
- better suspend/resume support for child devices
rcar-du:
- interlaced support
imx:
- move to using dw_hdmi shared support
- mode_fixup support
sti:
- DVO support
- HDMI infoframe support
exynos:
- refactoring and cleanup, removed lots of internal unnecessary
abstraction
- exynos7 DECON display controller support
Along with the usual bunch of fixes, cleanups etc"
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (724 commits)
drm/radeon: fix voltage setup on hawaii
drm/radeon/dp: Set EDP_CONFIGURATION_SET for bridge chips if necessary
drm/radeon: only enable kv/kb dpm interrupts once v3
drm/radeon: workaround for CP HW bug on CIK
drm/radeon: Don't try to enable write-combining without PAT
drm/radeon: use 0-255 rather than 0-100 for pwm fan range
drm/i915: Clamp efficient frequency to valid range
drm/i915: Really ignore long HPD pulses on eDP
drm/exynos: Add DECON driver
drm/i915: Correct the base value while updating LP_OUTPUT_HOLD in MIPI_PORT_CTRL
drm/i915: Insert a command barrier on BLT/BSD cache flushes
drm/i915: Drop vblank wait from intel_dp_link_down
drm/exynos: fix NULL pointer reference
drm/exynos: remove exynos_plane_dpms
drm/exynos: remove mode property of exynos crtc
drm/exynos: Remove exynos_plane_dpms() call with no effect
drm/i915: Squelch overzealous uncore reset WARN_ON
drm/i915: Take runtime pm reference on hangcheck_info
drm/i915: Correct the IOSF Dev_FN field for IOSF transfers
drm/exynos: fix DMA_ATTR_NO_KERNEL_MAPPING usage
...
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 672 |
1 files changed, 311 insertions, 361 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5f614828d365..c26d36cc4b31 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -39,8 +39,7 @@ | |||
39 | #include <linux/dma-buf.h> | 39 | #include <linux/dma-buf.h> |
40 | 40 | ||
41 | static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); | 41 | static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); |
42 | static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj, | 42 | static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); |
43 | bool force); | ||
44 | static __must_check int | 43 | static __must_check int |
45 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, | 44 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, |
46 | bool readonly); | 45 | bool readonly); |
@@ -153,12 +152,6 @@ int i915_mutex_lock_interruptible(struct drm_device *dev) | |||
153 | return 0; | 152 | return 0; |
154 | } | 153 | } |
155 | 154 | ||
156 | static inline bool | ||
157 | i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) | ||
158 | { | ||
159 | return i915_gem_obj_bound_any(obj) && !obj->active; | ||
160 | } | ||
161 | |||
162 | int | 155 | int |
163 | i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | 156 | i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, |
164 | struct drm_file *file) | 157 | struct drm_file *file) |
@@ -1157,19 +1150,18 @@ i915_gem_check_wedge(struct i915_gpu_error *error, | |||
1157 | } | 1150 | } |
1158 | 1151 | ||
1159 | /* | 1152 | /* |
1160 | * Compare seqno against outstanding lazy request. Emit a request if they are | 1153 | * Compare arbitrary request against outstanding lazy request. Emit on match. |
1161 | * equal. | ||
1162 | */ | 1154 | */ |
1163 | int | 1155 | int |
1164 | i915_gem_check_olr(struct intel_engine_cs *ring, u32 seqno) | 1156 | i915_gem_check_olr(struct drm_i915_gem_request *req) |
1165 | { | 1157 | { |
1166 | int ret; | 1158 | int ret; |
1167 | 1159 | ||
1168 | BUG_ON(!mutex_is_locked(&ring->dev->struct_mutex)); | 1160 | WARN_ON(!mutex_is_locked(&req->ring->dev->struct_mutex)); |
1169 | 1161 | ||
1170 | ret = 0; | 1162 | ret = 0; |
1171 | if (seqno == ring->outstanding_lazy_seqno) | 1163 | if (req == req->ring->outstanding_lazy_request) |
1172 | ret = i915_add_request(ring, NULL); | 1164 | ret = i915_add_request(req->ring); |
1173 | 1165 | ||
1174 | return ret; | 1166 | return ret; |
1175 | } | 1167 | } |
@@ -1194,10 +1186,9 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv) | |||
1194 | } | 1186 | } |
1195 | 1187 | ||
1196 | /** | 1188 | /** |
1197 | * __i915_wait_seqno - wait until execution of seqno has finished | 1189 | * __i915_wait_request - wait until execution of request has finished |
1198 | * @ring: the ring expected to report seqno | 1190 | * @req: duh! |
1199 | * @seqno: duh! | 1191 | * @reset_counter: reset sequence associated with the given request |
1200 | * @reset_counter: reset sequence associated with the given seqno | ||
1201 | * @interruptible: do an interruptible wait (normally yes) | 1192 | * @interruptible: do an interruptible wait (normally yes) |
1202 | * @timeout: in - how long to wait (NULL forever); out - how much time remaining | 1193 | * @timeout: in - how long to wait (NULL forever); out - how much time remaining |
1203 | * | 1194 | * |
@@ -1208,15 +1199,16 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv) | |||
1208 | * reset_counter _must_ be read before, and an appropriate smp_rmb must be | 1199 | * reset_counter _must_ be read before, and an appropriate smp_rmb must be |
1209 | * inserted. | 1200 | * inserted. |
1210 | * | 1201 | * |
1211 | * Returns 0 if the seqno was found within the alloted time. Else returns the | 1202 | * Returns 0 if the request was found within the alloted time. Else returns the |
1212 | * errno with remaining time filled in timeout argument. | 1203 | * errno with remaining time filled in timeout argument. |
1213 | */ | 1204 | */ |
1214 | int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno, | 1205 | int __i915_wait_request(struct drm_i915_gem_request *req, |
1215 | unsigned reset_counter, | 1206 | unsigned reset_counter, |
1216 | bool interruptible, | 1207 | bool interruptible, |
1217 | s64 *timeout, | 1208 | s64 *timeout, |
1218 | struct drm_i915_file_private *file_priv) | 1209 | struct drm_i915_file_private *file_priv) |
1219 | { | 1210 | { |
1211 | struct intel_engine_cs *ring = i915_gem_request_get_ring(req); | ||
1220 | struct drm_device *dev = ring->dev; | 1212 | struct drm_device *dev = ring->dev; |
1221 | struct drm_i915_private *dev_priv = dev->dev_private; | 1213 | struct drm_i915_private *dev_priv = dev->dev_private; |
1222 | const bool irq_test_in_progress = | 1214 | const bool irq_test_in_progress = |
@@ -1228,7 +1220,7 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno, | |||
1228 | 1220 | ||
1229 | WARN(!intel_irqs_enabled(dev_priv), "IRQs disabled"); | 1221 | WARN(!intel_irqs_enabled(dev_priv), "IRQs disabled"); |
1230 | 1222 | ||
1231 | if (i915_seqno_passed(ring->get_seqno(ring, true), seqno)) | 1223 | if (i915_gem_request_completed(req, true)) |
1232 | return 0; | 1224 | return 0; |
1233 | 1225 | ||
1234 | timeout_expire = timeout ? | 1226 | timeout_expire = timeout ? |
@@ -1246,7 +1238,7 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno, | |||
1246 | return -ENODEV; | 1238 | return -ENODEV; |
1247 | 1239 | ||
1248 | /* Record current time in case interrupted by signal, or wedged */ | 1240 | /* Record current time in case interrupted by signal, or wedged */ |
1249 | trace_i915_gem_request_wait_begin(ring, seqno); | 1241 | trace_i915_gem_request_wait_begin(req); |
1250 | before = ktime_get_raw_ns(); | 1242 | before = ktime_get_raw_ns(); |
1251 | for (;;) { | 1243 | for (;;) { |
1252 | struct timer_list timer; | 1244 | struct timer_list timer; |
@@ -1265,7 +1257,7 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno, | |||
1265 | break; | 1257 | break; |
1266 | } | 1258 | } |
1267 | 1259 | ||
1268 | if (i915_seqno_passed(ring->get_seqno(ring, false), seqno)) { | 1260 | if (i915_gem_request_completed(req, false)) { |
1269 | ret = 0; | 1261 | ret = 0; |
1270 | break; | 1262 | break; |
1271 | } | 1263 | } |
@@ -1297,7 +1289,7 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno, | |||
1297 | } | 1289 | } |
1298 | } | 1290 | } |
1299 | now = ktime_get_raw_ns(); | 1291 | now = ktime_get_raw_ns(); |
1300 | trace_i915_gem_request_wait_end(ring, seqno); | 1292 | trace_i915_gem_request_wait_end(req); |
1301 | 1293 | ||
1302 | if (!irq_test_in_progress) | 1294 | if (!irq_test_in_progress) |
1303 | ring->irq_put(ring); | 1295 | ring->irq_put(ring); |
@@ -1324,32 +1316,40 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno, | |||
1324 | } | 1316 | } |
1325 | 1317 | ||
1326 | /** | 1318 | /** |
1327 | * Waits for a sequence number to be signaled, and cleans up the | 1319 | * Waits for a request to be signaled, and cleans up the |
1328 | * request and object lists appropriately for that event. | 1320 | * request and object lists appropriately for that event. |
1329 | */ | 1321 | */ |
1330 | int | 1322 | int |
1331 | i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno) | 1323 | i915_wait_request(struct drm_i915_gem_request *req) |
1332 | { | 1324 | { |
1333 | struct drm_device *dev = ring->dev; | 1325 | struct drm_device *dev; |
1334 | struct drm_i915_private *dev_priv = dev->dev_private; | 1326 | struct drm_i915_private *dev_priv; |
1335 | bool interruptible = dev_priv->mm.interruptible; | 1327 | bool interruptible; |
1336 | unsigned reset_counter; | 1328 | unsigned reset_counter; |
1337 | int ret; | 1329 | int ret; |
1338 | 1330 | ||
1331 | BUG_ON(req == NULL); | ||
1332 | |||
1333 | dev = req->ring->dev; | ||
1334 | dev_priv = dev->dev_private; | ||
1335 | interruptible = dev_priv->mm.interruptible; | ||
1336 | |||
1339 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); | 1337 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); |
1340 | BUG_ON(seqno == 0); | ||
1341 | 1338 | ||
1342 | ret = i915_gem_check_wedge(&dev_priv->gpu_error, interruptible); | 1339 | ret = i915_gem_check_wedge(&dev_priv->gpu_error, interruptible); |
1343 | if (ret) | 1340 | if (ret) |
1344 | return ret; | 1341 | return ret; |
1345 | 1342 | ||
1346 | ret = i915_gem_check_olr(ring, seqno); | 1343 | ret = i915_gem_check_olr(req); |
1347 | if (ret) | 1344 | if (ret) |
1348 | return ret; | 1345 | return ret; |
1349 | 1346 | ||
1350 | reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); | 1347 | reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); |
1351 | return __i915_wait_seqno(ring, seqno, reset_counter, interruptible, | 1348 | i915_gem_request_reference(req); |
1352 | NULL, NULL); | 1349 | ret = __i915_wait_request(req, reset_counter, |
1350 | interruptible, NULL, NULL); | ||
1351 | i915_gem_request_unreference(req); | ||
1352 | return ret; | ||
1353 | } | 1353 | } |
1354 | 1354 | ||
1355 | static int | 1355 | static int |
@@ -1361,11 +1361,11 @@ i915_gem_object_wait_rendering__tail(struct drm_i915_gem_object *obj) | |||
1361 | /* Manually manage the write flush as we may have not yet | 1361 | /* Manually manage the write flush as we may have not yet |
1362 | * retired the buffer. | 1362 | * retired the buffer. |
1363 | * | 1363 | * |
1364 | * Note that the last_write_seqno is always the earlier of | 1364 | * Note that the last_write_req is always the earlier of |
1365 | * the two (read/write) seqno, so if we haved successfully waited, | 1365 | * the two (read/write) requests, so if we haved successfully waited, |
1366 | * we know we have passed the last write. | 1366 | * we know we have passed the last write. |
1367 | */ | 1367 | */ |
1368 | obj->last_write_seqno = 0; | 1368 | i915_gem_request_assign(&obj->last_write_req, NULL); |
1369 | 1369 | ||
1370 | return 0; | 1370 | return 0; |
1371 | } | 1371 | } |
@@ -1378,15 +1378,14 @@ static __must_check int | |||
1378 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, | 1378 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, |
1379 | bool readonly) | 1379 | bool readonly) |
1380 | { | 1380 | { |
1381 | struct intel_engine_cs *ring = obj->ring; | 1381 | struct drm_i915_gem_request *req; |
1382 | u32 seqno; | ||
1383 | int ret; | 1382 | int ret; |
1384 | 1383 | ||
1385 | seqno = readonly ? obj->last_write_seqno : obj->last_read_seqno; | 1384 | req = readonly ? obj->last_write_req : obj->last_read_req; |
1386 | if (seqno == 0) | 1385 | if (!req) |
1387 | return 0; | 1386 | return 0; |
1388 | 1387 | ||
1389 | ret = i915_wait_seqno(ring, seqno); | 1388 | ret = i915_wait_request(req); |
1390 | if (ret) | 1389 | if (ret) |
1391 | return ret; | 1390 | return ret; |
1392 | 1391 | ||
@@ -1401,33 +1400,33 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj, | |||
1401 | struct drm_i915_file_private *file_priv, | 1400 | struct drm_i915_file_private *file_priv, |
1402 | bool readonly) | 1401 | bool readonly) |
1403 | { | 1402 | { |
1403 | struct drm_i915_gem_request *req; | ||
1404 | struct drm_device *dev = obj->base.dev; | 1404 | struct drm_device *dev = obj->base.dev; |
1405 | struct drm_i915_private *dev_priv = dev->dev_private; | 1405 | struct drm_i915_private *dev_priv = dev->dev_private; |
1406 | struct intel_engine_cs *ring = obj->ring; | ||
1407 | unsigned reset_counter; | 1406 | unsigned reset_counter; |
1408 | u32 seqno; | ||
1409 | int ret; | 1407 | int ret; |
1410 | 1408 | ||
1411 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); | 1409 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); |
1412 | BUG_ON(!dev_priv->mm.interruptible); | 1410 | BUG_ON(!dev_priv->mm.interruptible); |
1413 | 1411 | ||
1414 | seqno = readonly ? obj->last_write_seqno : obj->last_read_seqno; | 1412 | req = readonly ? obj->last_write_req : obj->last_read_req; |
1415 | if (seqno == 0) | 1413 | if (!req) |
1416 | return 0; | 1414 | return 0; |
1417 | 1415 | ||
1418 | ret = i915_gem_check_wedge(&dev_priv->gpu_error, true); | 1416 | ret = i915_gem_check_wedge(&dev_priv->gpu_error, true); |
1419 | if (ret) | 1417 | if (ret) |
1420 | return ret; | 1418 | return ret; |
1421 | 1419 | ||
1422 | ret = i915_gem_check_olr(ring, seqno); | 1420 | ret = i915_gem_check_olr(req); |
1423 | if (ret) | 1421 | if (ret) |
1424 | return ret; | 1422 | return ret; |
1425 | 1423 | ||
1426 | reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); | 1424 | reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); |
1425 | i915_gem_request_reference(req); | ||
1427 | mutex_unlock(&dev->struct_mutex); | 1426 | mutex_unlock(&dev->struct_mutex); |
1428 | ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL, | 1427 | ret = __i915_wait_request(req, reset_counter, true, NULL, file_priv); |
1429 | file_priv); | ||
1430 | mutex_lock(&dev->struct_mutex); | 1428 | mutex_lock(&dev->struct_mutex); |
1429 | i915_gem_request_unreference(req); | ||
1431 | if (ret) | 1430 | if (ret) |
1432 | return ret; | 1431 | return ret; |
1433 | 1432 | ||
@@ -1481,18 +1480,10 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1481 | if (ret) | 1480 | if (ret) |
1482 | goto unref; | 1481 | goto unref; |
1483 | 1482 | ||
1484 | if (read_domains & I915_GEM_DOMAIN_GTT) { | 1483 | if (read_domains & I915_GEM_DOMAIN_GTT) |
1485 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); | 1484 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); |
1486 | 1485 | else | |
1487 | /* Silently promote "you're not bound, there was nothing to do" | ||
1488 | * to success, since the client was just asking us to | ||
1489 | * make sure everything was done. | ||
1490 | */ | ||
1491 | if (ret == -EINVAL) | ||
1492 | ret = 0; | ||
1493 | } else { | ||
1494 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); | 1486 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); |
1495 | } | ||
1496 | 1487 | ||
1497 | unref: | 1488 | unref: |
1498 | drm_gem_object_unreference(&obj->base); | 1489 | drm_gem_object_unreference(&obj->base); |
@@ -1524,7 +1515,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | |||
1524 | 1515 | ||
1525 | /* Pinned buffers may be scanout, so flush the cache */ | 1516 | /* Pinned buffers may be scanout, so flush the cache */ |
1526 | if (obj->pin_display) | 1517 | if (obj->pin_display) |
1527 | i915_gem_object_flush_cpu_write_domain(obj, true); | 1518 | i915_gem_object_flush_cpu_write_domain(obj); |
1528 | 1519 | ||
1529 | drm_gem_object_unreference(&obj->base); | 1520 | drm_gem_object_unreference(&obj->base); |
1530 | unlock: | 1521 | unlock: |
@@ -1557,6 +1548,12 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
1557 | struct drm_gem_object *obj; | 1548 | struct drm_gem_object *obj; |
1558 | unsigned long addr; | 1549 | unsigned long addr; |
1559 | 1550 | ||
1551 | if (args->flags & ~(I915_MMAP_WC)) | ||
1552 | return -EINVAL; | ||
1553 | |||
1554 | if (args->flags & I915_MMAP_WC && !cpu_has_pat) | ||
1555 | return -ENODEV; | ||
1556 | |||
1560 | obj = drm_gem_object_lookup(dev, file, args->handle); | 1557 | obj = drm_gem_object_lookup(dev, file, args->handle); |
1561 | if (obj == NULL) | 1558 | if (obj == NULL) |
1562 | return -ENOENT; | 1559 | return -ENOENT; |
@@ -1572,6 +1569,19 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
1572 | addr = vm_mmap(obj->filp, 0, args->size, | 1569 | addr = vm_mmap(obj->filp, 0, args->size, |
1573 | PROT_READ | PROT_WRITE, MAP_SHARED, | 1570 | PROT_READ | PROT_WRITE, MAP_SHARED, |
1574 | args->offset); | 1571 | args->offset); |
1572 | if (args->flags & I915_MMAP_WC) { | ||
1573 | struct mm_struct *mm = current->mm; | ||
1574 | struct vm_area_struct *vma; | ||
1575 | |||
1576 | down_write(&mm->mmap_sem); | ||
1577 | vma = find_vma(mm, addr); | ||
1578 | if (vma) | ||
1579 | vma->vm_page_prot = | ||
1580 | pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); | ||
1581 | else | ||
1582 | addr = -ENOMEM; | ||
1583 | up_write(&mm->mmap_sem); | ||
1584 | } | ||
1575 | drm_gem_object_unreference_unlocked(obj); | 1585 | drm_gem_object_unreference_unlocked(obj); |
1576 | if (IS_ERR((void *)addr)) | 1586 | if (IS_ERR((void *)addr)) |
1577 | return addr; | 1587 | return addr; |
@@ -2256,14 +2266,18 @@ static void | |||
2256 | i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, | 2266 | i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, |
2257 | struct intel_engine_cs *ring) | 2267 | struct intel_engine_cs *ring) |
2258 | { | 2268 | { |
2259 | u32 seqno = intel_ring_get_seqno(ring); | 2269 | struct drm_i915_gem_request *req; |
2270 | struct intel_engine_cs *old_ring; | ||
2260 | 2271 | ||
2261 | BUG_ON(ring == NULL); | 2272 | BUG_ON(ring == NULL); |
2262 | if (obj->ring != ring && obj->last_write_seqno) { | 2273 | |
2263 | /* Keep the seqno relative to the current ring */ | 2274 | req = intel_ring_get_request(ring); |
2264 | obj->last_write_seqno = seqno; | 2275 | old_ring = i915_gem_request_get_ring(obj->last_read_req); |
2276 | |||
2277 | if (old_ring != ring && obj->last_write_req) { | ||
2278 | /* Keep the request relative to the current ring */ | ||
2279 | i915_gem_request_assign(&obj->last_write_req, req); | ||
2265 | } | 2280 | } |
2266 | obj->ring = ring; | ||
2267 | 2281 | ||
2268 | /* Add a reference if we're newly entering the active list. */ | 2282 | /* Add a reference if we're newly entering the active list. */ |
2269 | if (!obj->active) { | 2283 | if (!obj->active) { |
@@ -2273,7 +2287,7 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, | |||
2273 | 2287 | ||
2274 | list_move_tail(&obj->ring_list, &ring->active_list); | 2288 | list_move_tail(&obj->ring_list, &ring->active_list); |
2275 | 2289 | ||
2276 | obj->last_read_seqno = seqno; | 2290 | i915_gem_request_assign(&obj->last_read_req, req); |
2277 | } | 2291 | } |
2278 | 2292 | ||
2279 | void i915_vma_move_to_active(struct i915_vma *vma, | 2293 | void i915_vma_move_to_active(struct i915_vma *vma, |
@@ -2286,29 +2300,25 @@ void i915_vma_move_to_active(struct i915_vma *vma, | |||
2286 | static void | 2300 | static void |
2287 | i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) | 2301 | i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) |
2288 | { | 2302 | { |
2289 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
2290 | struct i915_address_space *vm; | ||
2291 | struct i915_vma *vma; | 2303 | struct i915_vma *vma; |
2292 | 2304 | ||
2293 | BUG_ON(obj->base.write_domain & ~I915_GEM_GPU_DOMAINS); | 2305 | BUG_ON(obj->base.write_domain & ~I915_GEM_GPU_DOMAINS); |
2294 | BUG_ON(!obj->active); | 2306 | BUG_ON(!obj->active); |
2295 | 2307 | ||
2296 | list_for_each_entry(vm, &dev_priv->vm_list, global_link) { | 2308 | list_for_each_entry(vma, &obj->vma_list, vma_link) { |
2297 | vma = i915_gem_obj_to_vma(obj, vm); | 2309 | if (!list_empty(&vma->mm_list)) |
2298 | if (vma && !list_empty(&vma->mm_list)) | 2310 | list_move_tail(&vma->mm_list, &vma->vm->inactive_list); |
2299 | list_move_tail(&vma->mm_list, &vm->inactive_list); | ||
2300 | } | 2311 | } |
2301 | 2312 | ||
2302 | intel_fb_obj_flush(obj, true); | 2313 | intel_fb_obj_flush(obj, true); |
2303 | 2314 | ||
2304 | list_del_init(&obj->ring_list); | 2315 | list_del_init(&obj->ring_list); |
2305 | obj->ring = NULL; | ||
2306 | 2316 | ||
2307 | obj->last_read_seqno = 0; | 2317 | i915_gem_request_assign(&obj->last_read_req, NULL); |
2308 | obj->last_write_seqno = 0; | 2318 | i915_gem_request_assign(&obj->last_write_req, NULL); |
2309 | obj->base.write_domain = 0; | 2319 | obj->base.write_domain = 0; |
2310 | 2320 | ||
2311 | obj->last_fenced_seqno = 0; | 2321 | i915_gem_request_assign(&obj->last_fenced_req, NULL); |
2312 | 2322 | ||
2313 | obj->active = 0; | 2323 | obj->active = 0; |
2314 | drm_gem_object_unreference(&obj->base); | 2324 | drm_gem_object_unreference(&obj->base); |
@@ -2319,13 +2329,10 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) | |||
2319 | static void | 2329 | static void |
2320 | i915_gem_object_retire(struct drm_i915_gem_object *obj) | 2330 | i915_gem_object_retire(struct drm_i915_gem_object *obj) |
2321 | { | 2331 | { |
2322 | struct intel_engine_cs *ring = obj->ring; | 2332 | if (obj->last_read_req == NULL) |
2323 | |||
2324 | if (ring == NULL) | ||
2325 | return; | 2333 | return; |
2326 | 2334 | ||
2327 | if (i915_seqno_passed(ring->get_seqno(ring, true), | 2335 | if (i915_gem_request_completed(obj->last_read_req, true)) |
2328 | obj->last_read_seqno)) | ||
2329 | i915_gem_object_move_to_inactive(obj); | 2336 | i915_gem_object_move_to_inactive(obj); |
2330 | } | 2337 | } |
2331 | 2338 | ||
@@ -2401,22 +2408,20 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno) | |||
2401 | 2408 | ||
2402 | int __i915_add_request(struct intel_engine_cs *ring, | 2409 | int __i915_add_request(struct intel_engine_cs *ring, |
2403 | struct drm_file *file, | 2410 | struct drm_file *file, |
2404 | struct drm_i915_gem_object *obj, | 2411 | struct drm_i915_gem_object *obj) |
2405 | u32 *out_seqno) | ||
2406 | { | 2412 | { |
2407 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | 2413 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
2408 | struct drm_i915_gem_request *request; | 2414 | struct drm_i915_gem_request *request; |
2409 | struct intel_ringbuffer *ringbuf; | 2415 | struct intel_ringbuffer *ringbuf; |
2410 | u32 request_ring_position, request_start; | 2416 | u32 request_start; |
2411 | int ret; | 2417 | int ret; |
2412 | 2418 | ||
2413 | request = ring->preallocated_lazy_request; | 2419 | request = ring->outstanding_lazy_request; |
2414 | if (WARN_ON(request == NULL)) | 2420 | if (WARN_ON(request == NULL)) |
2415 | return -ENOMEM; | 2421 | return -ENOMEM; |
2416 | 2422 | ||
2417 | if (i915.enable_execlists) { | 2423 | if (i915.enable_execlists) { |
2418 | struct intel_context *ctx = request->ctx; | 2424 | ringbuf = request->ctx->engine[ring->id].ringbuf; |
2419 | ringbuf = ctx->engine[ring->id].ringbuf; | ||
2420 | } else | 2425 | } else |
2421 | ringbuf = ring->buffer; | 2426 | ringbuf = ring->buffer; |
2422 | 2427 | ||
@@ -2429,7 +2434,7 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
2429 | * what. | 2434 | * what. |
2430 | */ | 2435 | */ |
2431 | if (i915.enable_execlists) { | 2436 | if (i915.enable_execlists) { |
2432 | ret = logical_ring_flush_all_caches(ringbuf); | 2437 | ret = logical_ring_flush_all_caches(ringbuf, request->ctx); |
2433 | if (ret) | 2438 | if (ret) |
2434 | return ret; | 2439 | return ret; |
2435 | } else { | 2440 | } else { |
@@ -2443,10 +2448,10 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
2443 | * GPU processing the request, we never over-estimate the | 2448 | * GPU processing the request, we never over-estimate the |
2444 | * position of the head. | 2449 | * position of the head. |
2445 | */ | 2450 | */ |
2446 | request_ring_position = intel_ring_get_tail(ringbuf); | 2451 | request->postfix = intel_ring_get_tail(ringbuf); |
2447 | 2452 | ||
2448 | if (i915.enable_execlists) { | 2453 | if (i915.enable_execlists) { |
2449 | ret = ring->emit_request(ringbuf); | 2454 | ret = ring->emit_request(ringbuf, request); |
2450 | if (ret) | 2455 | if (ret) |
2451 | return ret; | 2456 | return ret; |
2452 | } else { | 2457 | } else { |
@@ -2455,10 +2460,8 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
2455 | return ret; | 2460 | return ret; |
2456 | } | 2461 | } |
2457 | 2462 | ||
2458 | request->seqno = intel_ring_get_seqno(ring); | ||
2459 | request->ring = ring; | ||
2460 | request->head = request_start; | 2463 | request->head = request_start; |
2461 | request->tail = request_ring_position; | 2464 | request->tail = intel_ring_get_tail(ringbuf); |
2462 | 2465 | ||
2463 | /* Whilst this request exists, batch_obj will be on the | 2466 | /* Whilst this request exists, batch_obj will be on the |
2464 | * active_list, and so will hold the active reference. Only when this | 2467 | * active_list, and so will hold the active reference. Only when this |
@@ -2491,9 +2494,8 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
2491 | spin_unlock(&file_priv->mm.lock); | 2494 | spin_unlock(&file_priv->mm.lock); |
2492 | } | 2495 | } |
2493 | 2496 | ||
2494 | trace_i915_gem_request_add(ring, request->seqno); | 2497 | trace_i915_gem_request_add(request); |
2495 | ring->outstanding_lazy_seqno = 0; | 2498 | ring->outstanding_lazy_request = NULL; |
2496 | ring->preallocated_lazy_request = NULL; | ||
2497 | 2499 | ||
2498 | i915_queue_hangcheck(ring->dev); | 2500 | i915_queue_hangcheck(ring->dev); |
2499 | 2501 | ||
@@ -2503,8 +2505,6 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
2503 | round_jiffies_up_relative(HZ)); | 2505 | round_jiffies_up_relative(HZ)); |
2504 | intel_mark_busy(dev_priv->dev); | 2506 | intel_mark_busy(dev_priv->dev); |
2505 | 2507 | ||
2506 | if (out_seqno) | ||
2507 | *out_seqno = request->seqno; | ||
2508 | return 0; | 2508 | return 0; |
2509 | } | 2509 | } |
2510 | 2510 | ||
@@ -2532,7 +2532,8 @@ static bool i915_context_is_banned(struct drm_i915_private *dev_priv, | |||
2532 | if (ctx->hang_stats.banned) | 2532 | if (ctx->hang_stats.banned) |
2533 | return true; | 2533 | return true; |
2534 | 2534 | ||
2535 | if (elapsed <= DRM_I915_CTX_BAN_PERIOD) { | 2535 | if (ctx->hang_stats.ban_period_seconds && |
2536 | elapsed <= ctx->hang_stats.ban_period_seconds) { | ||
2536 | if (!i915_gem_context_is_default(ctx)) { | 2537 | if (!i915_gem_context_is_default(ctx)) { |
2537 | DRM_DEBUG("context hanging too fast, banning!\n"); | 2538 | DRM_DEBUG("context hanging too fast, banning!\n"); |
2538 | return true; | 2539 | return true; |
@@ -2568,33 +2569,39 @@ static void i915_set_reset_status(struct drm_i915_private *dev_priv, | |||
2568 | 2569 | ||
2569 | static void i915_gem_free_request(struct drm_i915_gem_request *request) | 2570 | static void i915_gem_free_request(struct drm_i915_gem_request *request) |
2570 | { | 2571 | { |
2571 | struct intel_context *ctx = request->ctx; | ||
2572 | |||
2573 | list_del(&request->list); | 2572 | list_del(&request->list); |
2574 | i915_gem_request_remove_from_client(request); | 2573 | i915_gem_request_remove_from_client(request); |
2575 | 2574 | ||
2575 | i915_gem_request_unreference(request); | ||
2576 | } | ||
2577 | |||
2578 | void i915_gem_request_free(struct kref *req_ref) | ||
2579 | { | ||
2580 | struct drm_i915_gem_request *req = container_of(req_ref, | ||
2581 | typeof(*req), ref); | ||
2582 | struct intel_context *ctx = req->ctx; | ||
2583 | |||
2576 | if (ctx) { | 2584 | if (ctx) { |
2577 | if (i915.enable_execlists) { | 2585 | if (i915.enable_execlists) { |
2578 | struct intel_engine_cs *ring = request->ring; | 2586 | struct intel_engine_cs *ring = req->ring; |
2579 | 2587 | ||
2580 | if (ctx != ring->default_context) | 2588 | if (ctx != ring->default_context) |
2581 | intel_lr_context_unpin(ring, ctx); | 2589 | intel_lr_context_unpin(ring, ctx); |
2582 | } | 2590 | } |
2591 | |||
2583 | i915_gem_context_unreference(ctx); | 2592 | i915_gem_context_unreference(ctx); |
2584 | } | 2593 | } |
2585 | kfree(request); | 2594 | |
2595 | kfree(req); | ||
2586 | } | 2596 | } |
2587 | 2597 | ||
2588 | struct drm_i915_gem_request * | 2598 | struct drm_i915_gem_request * |
2589 | i915_gem_find_active_request(struct intel_engine_cs *ring) | 2599 | i915_gem_find_active_request(struct intel_engine_cs *ring) |
2590 | { | 2600 | { |
2591 | struct drm_i915_gem_request *request; | 2601 | struct drm_i915_gem_request *request; |
2592 | u32 completed_seqno; | ||
2593 | |||
2594 | completed_seqno = ring->get_seqno(ring, false); | ||
2595 | 2602 | ||
2596 | list_for_each_entry(request, &ring->request_list, list) { | 2603 | list_for_each_entry(request, &ring->request_list, list) { |
2597 | if (i915_seqno_passed(completed_seqno, request->seqno)) | 2604 | if (i915_gem_request_completed(request, false)) |
2598 | continue; | 2605 | continue; |
2599 | 2606 | ||
2600 | return request; | 2607 | return request; |
@@ -2641,13 +2648,17 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, | |||
2641 | * pinned in place. | 2648 | * pinned in place. |
2642 | */ | 2649 | */ |
2643 | while (!list_empty(&ring->execlist_queue)) { | 2650 | while (!list_empty(&ring->execlist_queue)) { |
2644 | struct intel_ctx_submit_request *submit_req; | 2651 | struct drm_i915_gem_request *submit_req; |
2645 | 2652 | ||
2646 | submit_req = list_first_entry(&ring->execlist_queue, | 2653 | submit_req = list_first_entry(&ring->execlist_queue, |
2647 | struct intel_ctx_submit_request, | 2654 | struct drm_i915_gem_request, |
2648 | execlist_link); | 2655 | execlist_link); |
2649 | list_del(&submit_req->execlist_link); | 2656 | list_del(&submit_req->execlist_link); |
2650 | intel_runtime_pm_put(dev_priv); | 2657 | intel_runtime_pm_put(dev_priv); |
2658 | |||
2659 | if (submit_req->ctx != ring->default_context) | ||
2660 | intel_lr_context_unpin(ring, submit_req->ctx); | ||
2661 | |||
2651 | i915_gem_context_unreference(submit_req->ctx); | 2662 | i915_gem_context_unreference(submit_req->ctx); |
2652 | kfree(submit_req); | 2663 | kfree(submit_req); |
2653 | } | 2664 | } |
@@ -2669,10 +2680,8 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, | |||
2669 | i915_gem_free_request(request); | 2680 | i915_gem_free_request(request); |
2670 | } | 2681 | } |
2671 | 2682 | ||
2672 | /* These may not have been flush before the reset, do so now */ | 2683 | /* This may not have been flushed before the reset, so clean it now */ |
2673 | kfree(ring->preallocated_lazy_request); | 2684 | i915_gem_request_assign(&ring->outstanding_lazy_request, NULL); |
2674 | ring->preallocated_lazy_request = NULL; | ||
2675 | ring->outstanding_lazy_seqno = 0; | ||
2676 | } | 2685 | } |
2677 | 2686 | ||
2678 | void i915_gem_restore_fences(struct drm_device *dev) | 2687 | void i915_gem_restore_fences(struct drm_device *dev) |
@@ -2724,15 +2733,11 @@ void i915_gem_reset(struct drm_device *dev) | |||
2724 | void | 2733 | void |
2725 | i915_gem_retire_requests_ring(struct intel_engine_cs *ring) | 2734 | i915_gem_retire_requests_ring(struct intel_engine_cs *ring) |
2726 | { | 2735 | { |
2727 | uint32_t seqno; | ||
2728 | |||
2729 | if (list_empty(&ring->request_list)) | 2736 | if (list_empty(&ring->request_list)) |
2730 | return; | 2737 | return; |
2731 | 2738 | ||
2732 | WARN_ON(i915_verify_lists(ring->dev)); | 2739 | WARN_ON(i915_verify_lists(ring->dev)); |
2733 | 2740 | ||
2734 | seqno = ring->get_seqno(ring, true); | ||
2735 | |||
2736 | /* Move any buffers on the active list that are no longer referenced | 2741 | /* Move any buffers on the active list that are no longer referenced |
2737 | * by the ringbuffer to the flushing/inactive lists as appropriate, | 2742 | * by the ringbuffer to the flushing/inactive lists as appropriate, |
2738 | * before we free the context associated with the requests. | 2743 | * before we free the context associated with the requests. |
@@ -2744,7 +2749,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) | |||
2744 | struct drm_i915_gem_object, | 2749 | struct drm_i915_gem_object, |
2745 | ring_list); | 2750 | ring_list); |
2746 | 2751 | ||
2747 | if (!i915_seqno_passed(seqno, obj->last_read_seqno)) | 2752 | if (!i915_gem_request_completed(obj->last_read_req, true)) |
2748 | break; | 2753 | break; |
2749 | 2754 | ||
2750 | i915_gem_object_move_to_inactive(obj); | 2755 | i915_gem_object_move_to_inactive(obj); |
@@ -2759,10 +2764,10 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) | |||
2759 | struct drm_i915_gem_request, | 2764 | struct drm_i915_gem_request, |
2760 | list); | 2765 | list); |
2761 | 2766 | ||
2762 | if (!i915_seqno_passed(seqno, request->seqno)) | 2767 | if (!i915_gem_request_completed(request, true)) |
2763 | break; | 2768 | break; |
2764 | 2769 | ||
2765 | trace_i915_gem_request_retire(ring, request->seqno); | 2770 | trace_i915_gem_request_retire(request); |
2766 | 2771 | ||
2767 | /* This is one of the few common intersection points | 2772 | /* This is one of the few common intersection points |
2768 | * between legacy ringbuffer submission and execlists: | 2773 | * between legacy ringbuffer submission and execlists: |
@@ -2780,15 +2785,15 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) | |||
2780 | * of tail of the request to update the last known position | 2785 | * of tail of the request to update the last known position |
2781 | * of the GPU head. | 2786 | * of the GPU head. |
2782 | */ | 2787 | */ |
2783 | ringbuf->last_retired_head = request->tail; | 2788 | ringbuf->last_retired_head = request->postfix; |
2784 | 2789 | ||
2785 | i915_gem_free_request(request); | 2790 | i915_gem_free_request(request); |
2786 | } | 2791 | } |
2787 | 2792 | ||
2788 | if (unlikely(ring->trace_irq_seqno && | 2793 | if (unlikely(ring->trace_irq_req && |
2789 | i915_seqno_passed(seqno, ring->trace_irq_seqno))) { | 2794 | i915_gem_request_completed(ring->trace_irq_req, true))) { |
2790 | ring->irq_put(ring); | 2795 | ring->irq_put(ring); |
2791 | ring->trace_irq_seqno = 0; | 2796 | i915_gem_request_assign(&ring->trace_irq_req, NULL); |
2792 | } | 2797 | } |
2793 | 2798 | ||
2794 | WARN_ON(i915_verify_lists(ring->dev)); | 2799 | WARN_ON(i915_verify_lists(ring->dev)); |
@@ -2860,14 +2865,17 @@ i915_gem_idle_work_handler(struct work_struct *work) | |||
2860 | static int | 2865 | static int |
2861 | i915_gem_object_flush_active(struct drm_i915_gem_object *obj) | 2866 | i915_gem_object_flush_active(struct drm_i915_gem_object *obj) |
2862 | { | 2867 | { |
2868 | struct intel_engine_cs *ring; | ||
2863 | int ret; | 2869 | int ret; |
2864 | 2870 | ||
2865 | if (obj->active) { | 2871 | if (obj->active) { |
2866 | ret = i915_gem_check_olr(obj->ring, obj->last_read_seqno); | 2872 | ring = i915_gem_request_get_ring(obj->last_read_req); |
2873 | |||
2874 | ret = i915_gem_check_olr(obj->last_read_req); | ||
2867 | if (ret) | 2875 | if (ret) |
2868 | return ret; | 2876 | return ret; |
2869 | 2877 | ||
2870 | i915_gem_retire_requests_ring(obj->ring); | 2878 | i915_gem_retire_requests_ring(ring); |
2871 | } | 2879 | } |
2872 | 2880 | ||
2873 | return 0; | 2881 | return 0; |
@@ -2901,9 +2909,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | |||
2901 | struct drm_i915_private *dev_priv = dev->dev_private; | 2909 | struct drm_i915_private *dev_priv = dev->dev_private; |
2902 | struct drm_i915_gem_wait *args = data; | 2910 | struct drm_i915_gem_wait *args = data; |
2903 | struct drm_i915_gem_object *obj; | 2911 | struct drm_i915_gem_object *obj; |
2904 | struct intel_engine_cs *ring = NULL; | 2912 | struct drm_i915_gem_request *req; |
2905 | unsigned reset_counter; | 2913 | unsigned reset_counter; |
2906 | u32 seqno = 0; | ||
2907 | int ret = 0; | 2914 | int ret = 0; |
2908 | 2915 | ||
2909 | if (args->flags != 0) | 2916 | if (args->flags != 0) |
@@ -2924,13 +2931,10 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | |||
2924 | if (ret) | 2931 | if (ret) |
2925 | goto out; | 2932 | goto out; |
2926 | 2933 | ||
2927 | if (obj->active) { | 2934 | if (!obj->active || !obj->last_read_req) |
2928 | seqno = obj->last_read_seqno; | 2935 | goto out; |
2929 | ring = obj->ring; | ||
2930 | } | ||
2931 | 2936 | ||
2932 | if (seqno == 0) | 2937 | req = obj->last_read_req; |
2933 | goto out; | ||
2934 | 2938 | ||
2935 | /* Do this after OLR check to make sure we make forward progress polling | 2939 | /* Do this after OLR check to make sure we make forward progress polling |
2936 | * on this IOCTL with a timeout <=0 (like busy ioctl) | 2940 | * on this IOCTL with a timeout <=0 (like busy ioctl) |
@@ -2942,10 +2946,15 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | |||
2942 | 2946 | ||
2943 | drm_gem_object_unreference(&obj->base); | 2947 | drm_gem_object_unreference(&obj->base); |
2944 | reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); | 2948 | reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); |
2949 | i915_gem_request_reference(req); | ||
2945 | mutex_unlock(&dev->struct_mutex); | 2950 | mutex_unlock(&dev->struct_mutex); |
2946 | 2951 | ||
2947 | return __i915_wait_seqno(ring, seqno, reset_counter, true, | 2952 | ret = __i915_wait_request(req, reset_counter, true, &args->timeout_ns, |
2948 | &args->timeout_ns, file->driver_priv); | 2953 | file->driver_priv); |
2954 | mutex_lock(&dev->struct_mutex); | ||
2955 | i915_gem_request_unreference(req); | ||
2956 | mutex_unlock(&dev->struct_mutex); | ||
2957 | return ret; | ||
2949 | 2958 | ||
2950 | out: | 2959 | out: |
2951 | drm_gem_object_unreference(&obj->base); | 2960 | drm_gem_object_unreference(&obj->base); |
@@ -2969,10 +2978,12 @@ int | |||
2969 | i915_gem_object_sync(struct drm_i915_gem_object *obj, | 2978 | i915_gem_object_sync(struct drm_i915_gem_object *obj, |
2970 | struct intel_engine_cs *to) | 2979 | struct intel_engine_cs *to) |
2971 | { | 2980 | { |
2972 | struct intel_engine_cs *from = obj->ring; | 2981 | struct intel_engine_cs *from; |
2973 | u32 seqno; | 2982 | u32 seqno; |
2974 | int ret, idx; | 2983 | int ret, idx; |
2975 | 2984 | ||
2985 | from = i915_gem_request_get_ring(obj->last_read_req); | ||
2986 | |||
2976 | if (from == NULL || to == from) | 2987 | if (from == NULL || to == from) |
2977 | return 0; | 2988 | return 0; |
2978 | 2989 | ||
@@ -2981,24 +2992,25 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj, | |||
2981 | 2992 | ||
2982 | idx = intel_ring_sync_index(from, to); | 2993 | idx = intel_ring_sync_index(from, to); |
2983 | 2994 | ||
2984 | seqno = obj->last_read_seqno; | 2995 | seqno = i915_gem_request_get_seqno(obj->last_read_req); |
2985 | /* Optimization: Avoid semaphore sync when we are sure we already | 2996 | /* Optimization: Avoid semaphore sync when we are sure we already |
2986 | * waited for an object with higher seqno */ | 2997 | * waited for an object with higher seqno */ |
2987 | if (seqno <= from->semaphore.sync_seqno[idx]) | 2998 | if (seqno <= from->semaphore.sync_seqno[idx]) |
2988 | return 0; | 2999 | return 0; |
2989 | 3000 | ||
2990 | ret = i915_gem_check_olr(obj->ring, seqno); | 3001 | ret = i915_gem_check_olr(obj->last_read_req); |
2991 | if (ret) | 3002 | if (ret) |
2992 | return ret; | 3003 | return ret; |
2993 | 3004 | ||
2994 | trace_i915_gem_ring_sync_to(from, to, seqno); | 3005 | trace_i915_gem_ring_sync_to(from, to, obj->last_read_req); |
2995 | ret = to->semaphore.sync_to(to, from, seqno); | 3006 | ret = to->semaphore.sync_to(to, from, seqno); |
2996 | if (!ret) | 3007 | if (!ret) |
2997 | /* We use last_read_seqno because sync_to() | 3008 | /* We use last_read_req because sync_to() |
2998 | * might have just caused seqno wrap under | 3009 | * might have just caused seqno wrap under |
2999 | * the radar. | 3010 | * the radar. |
3000 | */ | 3011 | */ |
3001 | from->semaphore.sync_seqno[idx] = obj->last_read_seqno; | 3012 | from->semaphore.sync_seqno[idx] = |
3013 | i915_gem_request_get_seqno(obj->last_read_req); | ||
3002 | 3014 | ||
3003 | return ret; | 3015 | return ret; |
3004 | } | 3016 | } |
@@ -3054,10 +3066,8 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
3054 | * cause memory corruption through use-after-free. | 3066 | * cause memory corruption through use-after-free. |
3055 | */ | 3067 | */ |
3056 | 3068 | ||
3057 | /* Throw away the active reference before moving to the unbound list */ | 3069 | if (i915_is_ggtt(vma->vm) && |
3058 | i915_gem_object_retire(obj); | 3070 | vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) { |
3059 | |||
3060 | if (i915_is_ggtt(vma->vm)) { | ||
3061 | i915_gem_object_finish_gtt(obj); | 3071 | i915_gem_object_finish_gtt(obj); |
3062 | 3072 | ||
3063 | /* release the fence reg _after_ flushing */ | 3073 | /* release the fence reg _after_ flushing */ |
@@ -3071,8 +3081,15 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
3071 | vma->unbind_vma(vma); | 3081 | vma->unbind_vma(vma); |
3072 | 3082 | ||
3073 | list_del_init(&vma->mm_list); | 3083 | list_del_init(&vma->mm_list); |
3074 | if (i915_is_ggtt(vma->vm)) | 3084 | if (i915_is_ggtt(vma->vm)) { |
3075 | obj->map_and_fenceable = false; | 3085 | if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) { |
3086 | obj->map_and_fenceable = false; | ||
3087 | } else if (vma->ggtt_view.pages) { | ||
3088 | sg_free_table(vma->ggtt_view.pages); | ||
3089 | kfree(vma->ggtt_view.pages); | ||
3090 | vma->ggtt_view.pages = NULL; | ||
3091 | } | ||
3092 | } | ||
3076 | 3093 | ||
3077 | drm_mm_remove_node(&vma->node); | 3094 | drm_mm_remove_node(&vma->node); |
3078 | i915_gem_vma_destroy(vma); | 3095 | i915_gem_vma_destroy(vma); |
@@ -3080,6 +3097,10 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
3080 | /* Since the unbound list is global, only move to that list if | 3097 | /* Since the unbound list is global, only move to that list if |
3081 | * no more VMAs exist. */ | 3098 | * no more VMAs exist. */ |
3082 | if (list_empty(&obj->vma_list)) { | 3099 | if (list_empty(&obj->vma_list)) { |
3100 | /* Throw away the active reference before | ||
3101 | * moving to the unbound list. */ | ||
3102 | i915_gem_object_retire(obj); | ||
3103 | |||
3083 | i915_gem_gtt_finish_object(obj); | 3104 | i915_gem_gtt_finish_object(obj); |
3084 | list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list); | 3105 | list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list); |
3085 | } | 3106 | } |
@@ -3270,17 +3291,12 @@ static void i915_gem_write_fence(struct drm_device *dev, int reg, | |||
3270 | "bogus fence setup with stride: 0x%x, tiling mode: %i\n", | 3291 | "bogus fence setup with stride: 0x%x, tiling mode: %i\n", |
3271 | obj->stride, obj->tiling_mode); | 3292 | obj->stride, obj->tiling_mode); |
3272 | 3293 | ||
3273 | switch (INTEL_INFO(dev)->gen) { | 3294 | if (IS_GEN2(dev)) |
3274 | case 9: | 3295 | i830_write_fence_reg(dev, reg, obj); |
3275 | case 8: | 3296 | else if (IS_GEN3(dev)) |
3276 | case 7: | 3297 | i915_write_fence_reg(dev, reg, obj); |
3277 | case 6: | 3298 | else if (INTEL_INFO(dev)->gen >= 4) |
3278 | case 5: | 3299 | i965_write_fence_reg(dev, reg, obj); |
3279 | case 4: i965_write_fence_reg(dev, reg, obj); break; | ||
3280 | case 3: i915_write_fence_reg(dev, reg, obj); break; | ||
3281 | case 2: i830_write_fence_reg(dev, reg, obj); break; | ||
3282 | default: BUG(); | ||
3283 | } | ||
3284 | 3300 | ||
3285 | /* And similarly be paranoid that no direct access to this region | 3301 | /* And similarly be paranoid that no direct access to this region |
3286 | * is reordered to before the fence is installed. | 3302 | * is reordered to before the fence is installed. |
@@ -3319,12 +3335,12 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, | |||
3319 | static int | 3335 | static int |
3320 | i915_gem_object_wait_fence(struct drm_i915_gem_object *obj) | 3336 | i915_gem_object_wait_fence(struct drm_i915_gem_object *obj) |
3321 | { | 3337 | { |
3322 | if (obj->last_fenced_seqno) { | 3338 | if (obj->last_fenced_req) { |
3323 | int ret = i915_wait_seqno(obj->ring, obj->last_fenced_seqno); | 3339 | int ret = i915_wait_request(obj->last_fenced_req); |
3324 | if (ret) | 3340 | if (ret) |
3325 | return ret; | 3341 | return ret; |
3326 | 3342 | ||
3327 | obj->last_fenced_seqno = 0; | 3343 | i915_gem_request_assign(&obj->last_fenced_req, NULL); |
3328 | } | 3344 | } |
3329 | 3345 | ||
3330 | return 0; | 3346 | return 0; |
@@ -3497,7 +3513,8 @@ static struct i915_vma * | |||
3497 | i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, | 3513 | i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, |
3498 | struct i915_address_space *vm, | 3514 | struct i915_address_space *vm, |
3499 | unsigned alignment, | 3515 | unsigned alignment, |
3500 | uint64_t flags) | 3516 | uint64_t flags, |
3517 | const struct i915_ggtt_view *view) | ||
3501 | { | 3518 | { |
3502 | struct drm_device *dev = obj->base.dev; | 3519 | struct drm_device *dev = obj->base.dev; |
3503 | struct drm_i915_private *dev_priv = dev->dev_private; | 3520 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -3547,7 +3564,7 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, | |||
3547 | 3564 | ||
3548 | i915_gem_object_pin_pages(obj); | 3565 | i915_gem_object_pin_pages(obj); |
3549 | 3566 | ||
3550 | vma = i915_gem_obj_lookup_or_create_vma(obj, vm); | 3567 | vma = i915_gem_obj_lookup_or_create_vma_view(obj, vm, view); |
3551 | if (IS_ERR(vma)) | 3568 | if (IS_ERR(vma)) |
3552 | goto err_unpin; | 3569 | goto err_unpin; |
3553 | 3570 | ||
@@ -3577,15 +3594,19 @@ search_free: | |||
3577 | if (ret) | 3594 | if (ret) |
3578 | goto err_remove_node; | 3595 | goto err_remove_node; |
3579 | 3596 | ||
3597 | trace_i915_vma_bind(vma, flags); | ||
3598 | ret = i915_vma_bind(vma, obj->cache_level, | ||
3599 | flags & PIN_GLOBAL ? GLOBAL_BIND : 0); | ||
3600 | if (ret) | ||
3601 | goto err_finish_gtt; | ||
3602 | |||
3580 | list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); | 3603 | list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); |
3581 | list_add_tail(&vma->mm_list, &vm->inactive_list); | 3604 | list_add_tail(&vma->mm_list, &vm->inactive_list); |
3582 | 3605 | ||
3583 | trace_i915_vma_bind(vma, flags); | ||
3584 | vma->bind_vma(vma, obj->cache_level, | ||
3585 | flags & PIN_GLOBAL ? GLOBAL_BIND : 0); | ||
3586 | |||
3587 | return vma; | 3606 | return vma; |
3588 | 3607 | ||
3608 | err_finish_gtt: | ||
3609 | i915_gem_gtt_finish_object(obj); | ||
3589 | err_remove_node: | 3610 | err_remove_node: |
3590 | drm_mm_remove_node(&vma->node); | 3611 | drm_mm_remove_node(&vma->node); |
3591 | err_free_vma: | 3612 | err_free_vma: |
@@ -3622,11 +3643,14 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj, | |||
3622 | * snooping behaviour occurs naturally as the result of our domain | 3643 | * snooping behaviour occurs naturally as the result of our domain |
3623 | * tracking. | 3644 | * tracking. |
3624 | */ | 3645 | */ |
3625 | if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) | 3646 | if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) { |
3647 | obj->cache_dirty = true; | ||
3626 | return false; | 3648 | return false; |
3649 | } | ||
3627 | 3650 | ||
3628 | trace_i915_gem_object_clflush(obj); | 3651 | trace_i915_gem_object_clflush(obj); |
3629 | drm_clflush_sg(obj->pages); | 3652 | drm_clflush_sg(obj->pages); |
3653 | obj->cache_dirty = false; | ||
3630 | 3654 | ||
3631 | return true; | 3655 | return true; |
3632 | } | 3656 | } |
@@ -3662,15 +3686,14 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) | |||
3662 | 3686 | ||
3663 | /** Flushes the CPU write domain for the object if it's dirty. */ | 3687 | /** Flushes the CPU write domain for the object if it's dirty. */ |
3664 | static void | 3688 | static void |
3665 | i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj, | 3689 | i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) |
3666 | bool force) | ||
3667 | { | 3690 | { |
3668 | uint32_t old_write_domain; | 3691 | uint32_t old_write_domain; |
3669 | 3692 | ||
3670 | if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) | 3693 | if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) |
3671 | return; | 3694 | return; |
3672 | 3695 | ||
3673 | if (i915_gem_clflush_object(obj, force)) | 3696 | if (i915_gem_clflush_object(obj, obj->pin_display)) |
3674 | i915_gem_chipset_flush(obj->base.dev); | 3697 | i915_gem_chipset_flush(obj->base.dev); |
3675 | 3698 | ||
3676 | old_write_domain = obj->base.write_domain; | 3699 | old_write_domain = obj->base.write_domain; |
@@ -3692,15 +3715,10 @@ i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj, | |||
3692 | int | 3715 | int |
3693 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) | 3716 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) |
3694 | { | 3717 | { |
3695 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
3696 | struct i915_vma *vma = i915_gem_obj_to_ggtt(obj); | ||
3697 | uint32_t old_write_domain, old_read_domains; | 3718 | uint32_t old_write_domain, old_read_domains; |
3719 | struct i915_vma *vma; | ||
3698 | int ret; | 3720 | int ret; |
3699 | 3721 | ||
3700 | /* Not valid to be called on unbound objects. */ | ||
3701 | if (vma == NULL) | ||
3702 | return -EINVAL; | ||
3703 | |||
3704 | if (obj->base.write_domain == I915_GEM_DOMAIN_GTT) | 3722 | if (obj->base.write_domain == I915_GEM_DOMAIN_GTT) |
3705 | return 0; | 3723 | return 0; |
3706 | 3724 | ||
@@ -3709,7 +3727,20 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) | |||
3709 | return ret; | 3727 | return ret; |
3710 | 3728 | ||
3711 | i915_gem_object_retire(obj); | 3729 | i915_gem_object_retire(obj); |
3712 | i915_gem_object_flush_cpu_write_domain(obj, false); | 3730 | |
3731 | /* Flush and acquire obj->pages so that we are coherent through | ||
3732 | * direct access in memory with previous cached writes through | ||
3733 | * shmemfs and that our cache domain tracking remains valid. | ||
3734 | * For example, if the obj->filp was moved to swap without us | ||
3735 | * being notified and releasing the pages, we would mistakenly | ||
3736 | * continue to assume that the obj remained out of the CPU cached | ||
3737 | * domain. | ||
3738 | */ | ||
3739 | ret = i915_gem_object_get_pages(obj); | ||
3740 | if (ret) | ||
3741 | return ret; | ||
3742 | |||
3743 | i915_gem_object_flush_cpu_write_domain(obj); | ||
3713 | 3744 | ||
3714 | /* Serialise direct access to this object with the barriers for | 3745 | /* Serialise direct access to this object with the barriers for |
3715 | * coherent writes from the GPU, by effectively invalidating the | 3746 | * coherent writes from the GPU, by effectively invalidating the |
@@ -3740,9 +3771,10 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) | |||
3740 | old_write_domain); | 3771 | old_write_domain); |
3741 | 3772 | ||
3742 | /* And bump the LRU for this access */ | 3773 | /* And bump the LRU for this access */ |
3743 | if (i915_gem_object_is_inactive(obj)) | 3774 | vma = i915_gem_obj_to_ggtt(obj); |
3775 | if (vma && drm_mm_node_allocated(&vma->node) && !obj->active) | ||
3744 | list_move_tail(&vma->mm_list, | 3776 | list_move_tail(&vma->mm_list, |
3745 | &dev_priv->gtt.base.inactive_list); | 3777 | &to_i915(obj->base.dev)->gtt.base.inactive_list); |
3746 | 3778 | ||
3747 | return 0; | 3779 | return 0; |
3748 | } | 3780 | } |
@@ -3788,36 +3820,23 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, | |||
3788 | } | 3820 | } |
3789 | 3821 | ||
3790 | list_for_each_entry(vma, &obj->vma_list, vma_link) | 3822 | list_for_each_entry(vma, &obj->vma_list, vma_link) |
3791 | if (drm_mm_node_allocated(&vma->node)) | 3823 | if (drm_mm_node_allocated(&vma->node)) { |
3792 | vma->bind_vma(vma, cache_level, | 3824 | ret = i915_vma_bind(vma, cache_level, |
3793 | vma->bound & GLOBAL_BIND); | 3825 | vma->bound & GLOBAL_BIND); |
3826 | if (ret) | ||
3827 | return ret; | ||
3828 | } | ||
3794 | } | 3829 | } |
3795 | 3830 | ||
3796 | list_for_each_entry(vma, &obj->vma_list, vma_link) | 3831 | list_for_each_entry(vma, &obj->vma_list, vma_link) |
3797 | vma->node.color = cache_level; | 3832 | vma->node.color = cache_level; |
3798 | obj->cache_level = cache_level; | 3833 | obj->cache_level = cache_level; |
3799 | 3834 | ||
3800 | if (cpu_write_needs_clflush(obj)) { | 3835 | if (obj->cache_dirty && |
3801 | u32 old_read_domains, old_write_domain; | 3836 | obj->base.write_domain != I915_GEM_DOMAIN_CPU && |
3802 | 3837 | cpu_write_needs_clflush(obj)) { | |
3803 | /* If we're coming from LLC cached, then we haven't | 3838 | if (i915_gem_clflush_object(obj, true)) |
3804 | * actually been tracking whether the data is in the | 3839 | i915_gem_chipset_flush(obj->base.dev); |
3805 | * CPU cache or not, since we only allow one bit set | ||
3806 | * in obj->write_domain and have been skipping the clflushes. | ||
3807 | * Just set it to the CPU cache for now. | ||
3808 | */ | ||
3809 | i915_gem_object_retire(obj); | ||
3810 | WARN_ON(obj->base.write_domain & ~I915_GEM_DOMAIN_CPU); | ||
3811 | |||
3812 | old_read_domains = obj->base.read_domains; | ||
3813 | old_write_domain = obj->base.write_domain; | ||
3814 | |||
3815 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; | ||
3816 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; | ||
3817 | |||
3818 | trace_i915_gem_object_change_domain(obj, | ||
3819 | old_read_domains, | ||
3820 | old_write_domain); | ||
3821 | } | 3840 | } |
3822 | 3841 | ||
3823 | return 0; | 3842 | return 0; |
@@ -3909,18 +3928,14 @@ static bool is_pin_display(struct drm_i915_gem_object *obj) | |||
3909 | if (!vma) | 3928 | if (!vma) |
3910 | return false; | 3929 | return false; |
3911 | 3930 | ||
3912 | /* There are 3 sources that pin objects: | 3931 | /* There are 2 sources that pin objects: |
3913 | * 1. The display engine (scanouts, sprites, cursors); | 3932 | * 1. The display engine (scanouts, sprites, cursors); |
3914 | * 2. Reservations for execbuffer; | 3933 | * 2. Reservations for execbuffer; |
3915 | * 3. The user. | ||
3916 | * | 3934 | * |
3917 | * We can ignore reservations as we hold the struct_mutex and | 3935 | * We can ignore reservations as we hold the struct_mutex and |
3918 | * are only called outside of the reservation path. The user | 3936 | * are only called outside of the reservation path. |
3919 | * can only increment pin_count once, and so if after | ||
3920 | * subtracting the potential reference by the user, any pin_count | ||
3921 | * remains, it must be due to another use by the display engine. | ||
3922 | */ | 3937 | */ |
3923 | return vma->pin_count - !!obj->user_pin_count; | 3938 | return vma->pin_count; |
3924 | } | 3939 | } |
3925 | 3940 | ||
3926 | /* | 3941 | /* |
@@ -3937,7 +3952,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, | |||
3937 | bool was_pin_display; | 3952 | bool was_pin_display; |
3938 | int ret; | 3953 | int ret; |
3939 | 3954 | ||
3940 | if (pipelined != obj->ring) { | 3955 | if (pipelined != i915_gem_request_get_ring(obj->last_read_req)) { |
3941 | ret = i915_gem_object_sync(obj, pipelined); | 3956 | ret = i915_gem_object_sync(obj, pipelined); |
3942 | if (ret) | 3957 | if (ret) |
3943 | return ret; | 3958 | return ret; |
@@ -3971,7 +3986,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, | |||
3971 | if (ret) | 3986 | if (ret) |
3972 | goto err_unpin_display; | 3987 | goto err_unpin_display; |
3973 | 3988 | ||
3974 | i915_gem_object_flush_cpu_write_domain(obj, true); | 3989 | i915_gem_object_flush_cpu_write_domain(obj); |
3975 | 3990 | ||
3976 | old_write_domain = obj->base.write_domain; | 3991 | old_write_domain = obj->base.write_domain; |
3977 | old_read_domains = obj->base.read_domains; | 3992 | old_read_domains = obj->base.read_domains; |
@@ -4089,10 +4104,8 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) | |||
4089 | struct drm_i915_private *dev_priv = dev->dev_private; | 4104 | struct drm_i915_private *dev_priv = dev->dev_private; |
4090 | struct drm_i915_file_private *file_priv = file->driver_priv; | 4105 | struct drm_i915_file_private *file_priv = file->driver_priv; |
4091 | unsigned long recent_enough = jiffies - msecs_to_jiffies(20); | 4106 | unsigned long recent_enough = jiffies - msecs_to_jiffies(20); |
4092 | struct drm_i915_gem_request *request; | 4107 | struct drm_i915_gem_request *request, *target = NULL; |
4093 | struct intel_engine_cs *ring = NULL; | ||
4094 | unsigned reset_counter; | 4108 | unsigned reset_counter; |
4095 | u32 seqno = 0; | ||
4096 | int ret; | 4109 | int ret; |
4097 | 4110 | ||
4098 | ret = i915_gem_wait_for_error(&dev_priv->gpu_error); | 4111 | ret = i915_gem_wait_for_error(&dev_priv->gpu_error); |
@@ -4108,19 +4121,24 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) | |||
4108 | if (time_after_eq(request->emitted_jiffies, recent_enough)) | 4121 | if (time_after_eq(request->emitted_jiffies, recent_enough)) |
4109 | break; | 4122 | break; |
4110 | 4123 | ||
4111 | ring = request->ring; | 4124 | target = request; |
4112 | seqno = request->seqno; | ||
4113 | } | 4125 | } |
4114 | reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); | 4126 | reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); |
4127 | if (target) | ||
4128 | i915_gem_request_reference(target); | ||
4115 | spin_unlock(&file_priv->mm.lock); | 4129 | spin_unlock(&file_priv->mm.lock); |
4116 | 4130 | ||
4117 | if (seqno == 0) | 4131 | if (target == NULL) |
4118 | return 0; | 4132 | return 0; |
4119 | 4133 | ||
4120 | ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL, NULL); | 4134 | ret = __i915_wait_request(target, reset_counter, true, NULL, NULL); |
4121 | if (ret == 0) | 4135 | if (ret == 0) |
4122 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); | 4136 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); |
4123 | 4137 | ||
4138 | mutex_lock(&dev->struct_mutex); | ||
4139 | i915_gem_request_unreference(target); | ||
4140 | mutex_unlock(&dev->struct_mutex); | ||
4141 | |||
4124 | return ret; | 4142 | return ret; |
4125 | } | 4143 | } |
4126 | 4144 | ||
@@ -4144,10 +4162,11 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags) | |||
4144 | } | 4162 | } |
4145 | 4163 | ||
4146 | int | 4164 | int |
4147 | i915_gem_object_pin(struct drm_i915_gem_object *obj, | 4165 | i915_gem_object_pin_view(struct drm_i915_gem_object *obj, |
4148 | struct i915_address_space *vm, | 4166 | struct i915_address_space *vm, |
4149 | uint32_t alignment, | 4167 | uint32_t alignment, |
4150 | uint64_t flags) | 4168 | uint64_t flags, |
4169 | const struct i915_ggtt_view *view) | ||
4151 | { | 4170 | { |
4152 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | 4171 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; |
4153 | struct i915_vma *vma; | 4172 | struct i915_vma *vma; |
@@ -4163,7 +4182,7 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, | |||
4163 | if (WARN_ON((flags & (PIN_MAPPABLE | PIN_GLOBAL)) == PIN_MAPPABLE)) | 4182 | if (WARN_ON((flags & (PIN_MAPPABLE | PIN_GLOBAL)) == PIN_MAPPABLE)) |
4164 | return -EINVAL; | 4183 | return -EINVAL; |
4165 | 4184 | ||
4166 | vma = i915_gem_obj_to_vma(obj, vm); | 4185 | vma = i915_gem_obj_to_vma_view(obj, vm, view); |
4167 | if (vma) { | 4186 | if (vma) { |
4168 | if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) | 4187 | if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) |
4169 | return -EBUSY; | 4188 | return -EBUSY; |
@@ -4173,7 +4192,8 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, | |||
4173 | "bo is already pinned with incorrect alignment:" | 4192 | "bo is already pinned with incorrect alignment:" |
4174 | " offset=%lx, req.alignment=%x, req.map_and_fenceable=%d," | 4193 | " offset=%lx, req.alignment=%x, req.map_and_fenceable=%d," |
4175 | " obj->map_and_fenceable=%d\n", | 4194 | " obj->map_and_fenceable=%d\n", |
4176 | i915_gem_obj_offset(obj, vm), alignment, | 4195 | i915_gem_obj_offset_view(obj, vm, view->type), |
4196 | alignment, | ||
4177 | !!(flags & PIN_MAPPABLE), | 4197 | !!(flags & PIN_MAPPABLE), |
4178 | obj->map_and_fenceable); | 4198 | obj->map_and_fenceable); |
4179 | ret = i915_vma_unbind(vma); | 4199 | ret = i915_vma_unbind(vma); |
@@ -4186,13 +4206,17 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, | |||
4186 | 4206 | ||
4187 | bound = vma ? vma->bound : 0; | 4207 | bound = vma ? vma->bound : 0; |
4188 | if (vma == NULL || !drm_mm_node_allocated(&vma->node)) { | 4208 | if (vma == NULL || !drm_mm_node_allocated(&vma->node)) { |
4189 | vma = i915_gem_object_bind_to_vm(obj, vm, alignment, flags); | 4209 | vma = i915_gem_object_bind_to_vm(obj, vm, alignment, |
4210 | flags, view); | ||
4190 | if (IS_ERR(vma)) | 4211 | if (IS_ERR(vma)) |
4191 | return PTR_ERR(vma); | 4212 | return PTR_ERR(vma); |
4192 | } | 4213 | } |
4193 | 4214 | ||
4194 | if (flags & PIN_GLOBAL && !(vma->bound & GLOBAL_BIND)) | 4215 | if (flags & PIN_GLOBAL && !(vma->bound & GLOBAL_BIND)) { |
4195 | vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND); | 4216 | ret = i915_vma_bind(vma, obj->cache_level, GLOBAL_BIND); |
4217 | if (ret) | ||
4218 | return ret; | ||
4219 | } | ||
4196 | 4220 | ||
4197 | if ((bound ^ vma->bound) & GLOBAL_BIND) { | 4221 | if ((bound ^ vma->bound) & GLOBAL_BIND) { |
4198 | bool mappable, fenceable; | 4222 | bool mappable, fenceable; |
@@ -4264,102 +4288,6 @@ i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) | |||
4264 | } | 4288 | } |
4265 | 4289 | ||
4266 | int | 4290 | int |
4267 | i915_gem_pin_ioctl(struct drm_device *dev, void *data, | ||
4268 | struct drm_file *file) | ||
4269 | { | ||
4270 | struct drm_i915_gem_pin *args = data; | ||
4271 | struct drm_i915_gem_object *obj; | ||
4272 | int ret; | ||
4273 | |||
4274 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
4275 | return -ENODEV; | ||
4276 | |||
4277 | ret = i915_mutex_lock_interruptible(dev); | ||
4278 | if (ret) | ||
4279 | return ret; | ||
4280 | |||
4281 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); | ||
4282 | if (&obj->base == NULL) { | ||
4283 | ret = -ENOENT; | ||
4284 | goto unlock; | ||
4285 | } | ||
4286 | |||
4287 | if (obj->madv != I915_MADV_WILLNEED) { | ||
4288 | DRM_DEBUG("Attempting to pin a purgeable buffer\n"); | ||
4289 | ret = -EFAULT; | ||
4290 | goto out; | ||
4291 | } | ||
4292 | |||
4293 | if (obj->pin_filp != NULL && obj->pin_filp != file) { | ||
4294 | DRM_DEBUG("Already pinned in i915_gem_pin_ioctl(): %d\n", | ||
4295 | args->handle); | ||
4296 | ret = -EINVAL; | ||
4297 | goto out; | ||
4298 | } | ||
4299 | |||
4300 | if (obj->user_pin_count == ULONG_MAX) { | ||
4301 | ret = -EBUSY; | ||
4302 | goto out; | ||
4303 | } | ||
4304 | |||
4305 | if (obj->user_pin_count == 0) { | ||
4306 | ret = i915_gem_obj_ggtt_pin(obj, args->alignment, PIN_MAPPABLE); | ||
4307 | if (ret) | ||
4308 | goto out; | ||
4309 | } | ||
4310 | |||
4311 | obj->user_pin_count++; | ||
4312 | obj->pin_filp = file; | ||
4313 | |||
4314 | args->offset = i915_gem_obj_ggtt_offset(obj); | ||
4315 | out: | ||
4316 | drm_gem_object_unreference(&obj->base); | ||
4317 | unlock: | ||
4318 | mutex_unlock(&dev->struct_mutex); | ||
4319 | return ret; | ||
4320 | } | ||
4321 | |||
4322 | int | ||
4323 | i915_gem_unpin_ioctl(struct drm_device *dev, void *data, | ||
4324 | struct drm_file *file) | ||
4325 | { | ||
4326 | struct drm_i915_gem_pin *args = data; | ||
4327 | struct drm_i915_gem_object *obj; | ||
4328 | int ret; | ||
4329 | |||
4330 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
4331 | return -ENODEV; | ||
4332 | |||
4333 | ret = i915_mutex_lock_interruptible(dev); | ||
4334 | if (ret) | ||
4335 | return ret; | ||
4336 | |||
4337 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); | ||
4338 | if (&obj->base == NULL) { | ||
4339 | ret = -ENOENT; | ||
4340 | goto unlock; | ||
4341 | } | ||
4342 | |||
4343 | if (obj->pin_filp != file) { | ||
4344 | DRM_DEBUG("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", | ||
4345 | args->handle); | ||
4346 | ret = -EINVAL; | ||
4347 | goto out; | ||
4348 | } | ||
4349 | obj->user_pin_count--; | ||
4350 | if (obj->user_pin_count == 0) { | ||
4351 | obj->pin_filp = NULL; | ||
4352 | i915_gem_object_ggtt_unpin(obj); | ||
4353 | } | ||
4354 | |||
4355 | out: | ||
4356 | drm_gem_object_unreference(&obj->base); | ||
4357 | unlock: | ||
4358 | mutex_unlock(&dev->struct_mutex); | ||
4359 | return ret; | ||
4360 | } | ||
4361 | |||
4362 | int | ||
4363 | i915_gem_busy_ioctl(struct drm_device *dev, void *data, | 4291 | i915_gem_busy_ioctl(struct drm_device *dev, void *data, |
4364 | struct drm_file *file) | 4292 | struct drm_file *file) |
4365 | { | 4293 | { |
@@ -4385,9 +4313,11 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
4385 | ret = i915_gem_object_flush_active(obj); | 4313 | ret = i915_gem_object_flush_active(obj); |
4386 | 4314 | ||
4387 | args->busy = obj->active; | 4315 | args->busy = obj->active; |
4388 | if (obj->ring) { | 4316 | if (obj->last_read_req) { |
4317 | struct intel_engine_cs *ring; | ||
4389 | BUILD_BUG_ON(I915_NUM_RINGS > 16); | 4318 | BUILD_BUG_ON(I915_NUM_RINGS > 16); |
4390 | args->busy |= intel_ring_flag(obj->ring) << 16; | 4319 | ring = i915_gem_request_get_ring(obj->last_read_req); |
4320 | args->busy |= intel_ring_flag(ring) << 16; | ||
4391 | } | 4321 | } |
4392 | 4322 | ||
4393 | drm_gem_object_unreference(&obj->base); | 4323 | drm_gem_object_unreference(&obj->base); |
@@ -4467,6 +4397,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, | |||
4467 | INIT_LIST_HEAD(&obj->ring_list); | 4397 | INIT_LIST_HEAD(&obj->ring_list); |
4468 | INIT_LIST_HEAD(&obj->obj_exec_link); | 4398 | INIT_LIST_HEAD(&obj->obj_exec_link); |
4469 | INIT_LIST_HEAD(&obj->vma_list); | 4399 | INIT_LIST_HEAD(&obj->vma_list); |
4400 | INIT_LIST_HEAD(&obj->batch_pool_list); | ||
4470 | 4401 | ||
4471 | obj->ops = ops; | 4402 | obj->ops = ops; |
4472 | 4403 | ||
@@ -4622,12 +4553,13 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) | |||
4622 | intel_runtime_pm_put(dev_priv); | 4553 | intel_runtime_pm_put(dev_priv); |
4623 | } | 4554 | } |
4624 | 4555 | ||
4625 | struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, | 4556 | struct i915_vma *i915_gem_obj_to_vma_view(struct drm_i915_gem_object *obj, |
4626 | struct i915_address_space *vm) | 4557 | struct i915_address_space *vm, |
4558 | const struct i915_ggtt_view *view) | ||
4627 | { | 4559 | { |
4628 | struct i915_vma *vma; | 4560 | struct i915_vma *vma; |
4629 | list_for_each_entry(vma, &obj->vma_list, vma_link) | 4561 | list_for_each_entry(vma, &obj->vma_list, vma_link) |
4630 | if (vma->vm == vm) | 4562 | if (vma->vm == vm && vma->ggtt_view.type == view->type) |
4631 | return vma; | 4563 | return vma; |
4632 | 4564 | ||
4633 | return NULL; | 4565 | return NULL; |
@@ -4683,10 +4615,15 @@ i915_gem_suspend(struct drm_device *dev) | |||
4683 | i915_gem_stop_ringbuffers(dev); | 4615 | i915_gem_stop_ringbuffers(dev); |
4684 | mutex_unlock(&dev->struct_mutex); | 4616 | mutex_unlock(&dev->struct_mutex); |
4685 | 4617 | ||
4686 | del_timer_sync(&dev_priv->gpu_error.hangcheck_timer); | 4618 | cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); |
4687 | cancel_delayed_work_sync(&dev_priv->mm.retire_work); | 4619 | cancel_delayed_work_sync(&dev_priv->mm.retire_work); |
4688 | flush_delayed_work(&dev_priv->mm.idle_work); | 4620 | flush_delayed_work(&dev_priv->mm.idle_work); |
4689 | 4621 | ||
4622 | /* Assert that we sucessfully flushed all the work and | ||
4623 | * reset the GPU back to its idle, low power state. | ||
4624 | */ | ||
4625 | WARN_ON(dev_priv->mm.busy); | ||
4626 | |||
4690 | return 0; | 4627 | return 0; |
4691 | 4628 | ||
4692 | err: | 4629 | err: |
@@ -4798,14 +4735,6 @@ int i915_gem_init_rings(struct drm_device *dev) | |||
4798 | struct drm_i915_private *dev_priv = dev->dev_private; | 4735 | struct drm_i915_private *dev_priv = dev->dev_private; |
4799 | int ret; | 4736 | int ret; |
4800 | 4737 | ||
4801 | /* | ||
4802 | * At least 830 can leave some of the unused rings | ||
4803 | * "active" (ie. head != tail) after resume which | ||
4804 | * will prevent c3 entry. Makes sure all unused rings | ||
4805 | * are totally idle. | ||
4806 | */ | ||
4807 | init_unused_rings(dev); | ||
4808 | |||
4809 | ret = intel_init_render_ring_buffer(dev); | 4738 | ret = intel_init_render_ring_buffer(dev); |
4810 | if (ret) | 4739 | if (ret) |
4811 | return ret; | 4740 | return ret; |
@@ -4858,6 +4787,7 @@ int | |||
4858 | i915_gem_init_hw(struct drm_device *dev) | 4787 | i915_gem_init_hw(struct drm_device *dev) |
4859 | { | 4788 | { |
4860 | struct drm_i915_private *dev_priv = dev->dev_private; | 4789 | struct drm_i915_private *dev_priv = dev->dev_private; |
4790 | struct intel_engine_cs *ring; | ||
4861 | int ret, i; | 4791 | int ret, i; |
4862 | 4792 | ||
4863 | if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) | 4793 | if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) |
@@ -4884,9 +4814,19 @@ i915_gem_init_hw(struct drm_device *dev) | |||
4884 | 4814 | ||
4885 | i915_gem_init_swizzling(dev); | 4815 | i915_gem_init_swizzling(dev); |
4886 | 4816 | ||
4887 | ret = dev_priv->gt.init_rings(dev); | 4817 | /* |
4888 | if (ret) | 4818 | * At least 830 can leave some of the unused rings |
4889 | return ret; | 4819 | * "active" (ie. head != tail) after resume which |
4820 | * will prevent c3 entry. Makes sure all unused rings | ||
4821 | * are totally idle. | ||
4822 | */ | ||
4823 | init_unused_rings(dev); | ||
4824 | |||
4825 | for_each_ring(ring, dev_priv, i) { | ||
4826 | ret = ring->init_hw(ring); | ||
4827 | if (ret) | ||
4828 | return ret; | ||
4829 | } | ||
4890 | 4830 | ||
4891 | for (i = 0; i < NUM_L3_SLICES(dev); i++) | 4831 | for (i = 0; i < NUM_L3_SLICES(dev); i++) |
4892 | i915_gem_l3_remap(&dev_priv->ring[RCS], i); | 4832 | i915_gem_l3_remap(&dev_priv->ring[RCS], i); |
@@ -4939,18 +4879,18 @@ int i915_gem_init(struct drm_device *dev) | |||
4939 | } | 4879 | } |
4940 | 4880 | ||
4941 | ret = i915_gem_init_userptr(dev); | 4881 | ret = i915_gem_init_userptr(dev); |
4942 | if (ret) { | 4882 | if (ret) |
4943 | mutex_unlock(&dev->struct_mutex); | 4883 | goto out_unlock; |
4944 | return ret; | ||
4945 | } | ||
4946 | 4884 | ||
4947 | i915_gem_init_global_gtt(dev); | 4885 | i915_gem_init_global_gtt(dev); |
4948 | 4886 | ||
4949 | ret = i915_gem_context_init(dev); | 4887 | ret = i915_gem_context_init(dev); |
4950 | if (ret) { | 4888 | if (ret) |
4951 | mutex_unlock(&dev->struct_mutex); | 4889 | goto out_unlock; |
4952 | return ret; | 4890 | |
4953 | } | 4891 | ret = dev_priv->gt.init_rings(dev); |
4892 | if (ret) | ||
4893 | goto out_unlock; | ||
4954 | 4894 | ||
4955 | ret = i915_gem_init_hw(dev); | 4895 | ret = i915_gem_init_hw(dev); |
4956 | if (ret == -EIO) { | 4896 | if (ret == -EIO) { |
@@ -4962,6 +4902,8 @@ int i915_gem_init(struct drm_device *dev) | |||
4962 | atomic_set_mask(I915_WEDGED, &dev_priv->gpu_error.reset_counter); | 4902 | atomic_set_mask(I915_WEDGED, &dev_priv->gpu_error.reset_counter); |
4963 | ret = 0; | 4903 | ret = 0; |
4964 | } | 4904 | } |
4905 | |||
4906 | out_unlock: | ||
4965 | mutex_unlock(&dev->struct_mutex); | 4907 | mutex_unlock(&dev->struct_mutex); |
4966 | 4908 | ||
4967 | return ret; | 4909 | return ret; |
@@ -5062,6 +5004,8 @@ i915_gem_load(struct drm_device *dev) | |||
5062 | dev_priv->mm.oom_notifier.notifier_call = i915_gem_shrinker_oom; | 5004 | dev_priv->mm.oom_notifier.notifier_call = i915_gem_shrinker_oom; |
5063 | register_oom_notifier(&dev_priv->mm.oom_notifier); | 5005 | register_oom_notifier(&dev_priv->mm.oom_notifier); |
5064 | 5006 | ||
5007 | i915_gem_batch_pool_init(dev, &dev_priv->mm.batch_pool); | ||
5008 | |||
5065 | mutex_init(&dev_priv->fb_tracking.lock); | 5009 | mutex_init(&dev_priv->fb_tracking.lock); |
5066 | } | 5010 | } |
5067 | 5011 | ||
@@ -5155,7 +5099,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) | |||
5155 | if (!mutex_is_locked(mutex)) | 5099 | if (!mutex_is_locked(mutex)) |
5156 | return false; | 5100 | return false; |
5157 | 5101 | ||
5158 | #if defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES) | 5102 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES) |
5159 | return mutex->owner == task; | 5103 | return mutex->owner == task; |
5160 | #else | 5104 | #else |
5161 | /* Since UP may be pre-empted, we cannot assume that we own the lock */ | 5105 | /* Since UP may be pre-empted, we cannot assume that we own the lock */ |
@@ -5222,8 +5166,9 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) | |||
5222 | } | 5166 | } |
5223 | 5167 | ||
5224 | /* All the new VM stuff */ | 5168 | /* All the new VM stuff */ |
5225 | unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o, | 5169 | unsigned long i915_gem_obj_offset_view(struct drm_i915_gem_object *o, |
5226 | struct i915_address_space *vm) | 5170 | struct i915_address_space *vm, |
5171 | enum i915_ggtt_view_type view) | ||
5227 | { | 5172 | { |
5228 | struct drm_i915_private *dev_priv = o->base.dev->dev_private; | 5173 | struct drm_i915_private *dev_priv = o->base.dev->dev_private; |
5229 | struct i915_vma *vma; | 5174 | struct i915_vma *vma; |
@@ -5231,7 +5176,7 @@ unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o, | |||
5231 | WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base); | 5176 | WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base); |
5232 | 5177 | ||
5233 | list_for_each_entry(vma, &o->vma_list, vma_link) { | 5178 | list_for_each_entry(vma, &o->vma_list, vma_link) { |
5234 | if (vma->vm == vm) | 5179 | if (vma->vm == vm && vma->ggtt_view.type == view) |
5235 | return vma->node.start; | 5180 | return vma->node.start; |
5236 | 5181 | ||
5237 | } | 5182 | } |
@@ -5240,13 +5185,16 @@ unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o, | |||
5240 | return -1; | 5185 | return -1; |
5241 | } | 5186 | } |
5242 | 5187 | ||
5243 | bool i915_gem_obj_bound(struct drm_i915_gem_object *o, | 5188 | bool i915_gem_obj_bound_view(struct drm_i915_gem_object *o, |
5244 | struct i915_address_space *vm) | 5189 | struct i915_address_space *vm, |
5190 | enum i915_ggtt_view_type view) | ||
5245 | { | 5191 | { |
5246 | struct i915_vma *vma; | 5192 | struct i915_vma *vma; |
5247 | 5193 | ||
5248 | list_for_each_entry(vma, &o->vma_list, vma_link) | 5194 | list_for_each_entry(vma, &o->vma_list, vma_link) |
5249 | if (vma->vm == vm && drm_mm_node_allocated(&vma->node)) | 5195 | if (vma->vm == vm && |
5196 | vma->ggtt_view.type == view && | ||
5197 | drm_mm_node_allocated(&vma->node)) | ||
5250 | return true; | 5198 | return true; |
5251 | 5199 | ||
5252 | return false; | 5200 | return false; |
@@ -5378,11 +5326,13 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) | |||
5378 | 5326 | ||
5379 | struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj) | 5327 | struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj) |
5380 | { | 5328 | { |
5329 | struct i915_address_space *ggtt = i915_obj_to_ggtt(obj); | ||
5381 | struct i915_vma *vma; | 5330 | struct i915_vma *vma; |
5382 | 5331 | ||
5383 | vma = list_first_entry(&obj->vma_list, typeof(*vma), vma_link); | 5332 | list_for_each_entry(vma, &obj->vma_list, vma_link) |
5384 | if (vma->vm != i915_obj_to_ggtt(obj)) | 5333 | if (vma->vm == ggtt && |
5385 | return NULL; | 5334 | vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) |
5335 | return vma; | ||
5386 | 5336 | ||
5387 | return vma; | 5337 | return NULL; |
5388 | } | 5338 | } |