| @@ -1,41 +1,41 @@ | | | @@ -1,41 +1,41 @@ |
1 | /* $NetBSD: intel_engine_cs.c,v 1.3 2021/12/19 01:21:53 riastradh Exp $ */ | | 1 | /* $NetBSD: intel_engine_cs.c,v 1.4 2021/12/19 11:08:40 riastradh Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright © 2016 Intel Corporation | | 4 | * Copyright © 2016 Intel Corporation |
5 | * | | 5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a | | 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
7 | * copy of this software and associated documentation files (the "Software"), | | 7 | * copy of this software and associated documentation files (the "Software"), |
8 | * to deal in the Software without restriction, including without limitation | | 8 | * to deal in the Software without restriction, including without limitation |
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | | 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
10 | * and/or sell copies of the Software, and to permit persons to whom the | | 10 | * and/or sell copies of the Software, and to permit persons to whom the |
11 | * Software is furnished to do so, subject to the following conditions: | | 11 | * Software is furnished to do so, subject to the following conditions: |
12 | * | | 12 | * |
13 | * The above copyright notice and this permission notice (including the next | | 13 | * The above copyright notice and this permission notice (including the next |
14 | * paragraph) shall be included in all copies or substantial portions of the | | 14 | * paragraph) shall be included in all copies or substantial portions of the |
15 | * Software. | | 15 | * Software. |
16 | * | | 16 | * |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | | 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | | 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | | 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | | 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | | 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | | 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
23 | * IN THE SOFTWARE. | | 23 | * IN THE SOFTWARE. |
24 | * | | 24 | * |
25 | */ | | 25 | */ |
26 | | | 26 | |
27 | #include <sys/cdefs.h> | | 27 | #include <sys/cdefs.h> |
28 | __KERNEL_RCSID(0, "$NetBSD: intel_engine_cs.c,v 1.3 2021/12/19 01:21:53 riastradh Exp $"); | | 28 | __KERNEL_RCSID(0, "$NetBSD: intel_engine_cs.c,v 1.4 2021/12/19 11:08:40 riastradh Exp $"); |
29 | | | 29 | |
30 | #include <drm/drm_print.h> | | 30 | #include <drm/drm_print.h> |
31 | | | 31 | |
32 | #include "gem/i915_gem_context.h" | | 32 | #include "gem/i915_gem_context.h" |
33 | | | 33 | |
34 | #include "i915_drv.h" | | 34 | #include "i915_drv.h" |
35 | | | 35 | |
36 | #include "intel_context.h" | | 36 | #include "intel_context.h" |
37 | #include "intel_engine.h" | | 37 | #include "intel_engine.h" |
38 | #include "intel_engine_pm.h" | | 38 | #include "intel_engine_pm.h" |
39 | #include "intel_engine_pool.h" | | 39 | #include "intel_engine_pool.h" |
40 | #include "intel_engine_user.h" | | 40 | #include "intel_engine_user.h" |
41 | #include "intel_gt.h" | | 41 | #include "intel_gt.h" |
| @@ -1335,27 +1335,31 @@ static void intel_engine_print_registers | | | @@ -1335,27 +1335,31 @@ static void intel_engine_print_registers |
1335 | | | 1335 | |
1336 | if (read >= num_entries) | | 1336 | if (read >= num_entries) |
1337 | read = 0; | | 1337 | read = 0; |
1338 | if (write >= num_entries) | | 1338 | if (write >= num_entries) |
1339 | write = 0; | | 1339 | write = 0; |
1340 | if (read > write) | | 1340 | if (read > write) |
1341 | write += num_entries; | | 1341 | write += num_entries; |
1342 | while (read < write) { | | 1342 | while (read < write) { |
1343 | idx = ++read % num_entries; | | 1343 | idx = ++read % num_entries; |
1344 | drm_printf(m, "\tExeclist CSB[%d]: 0x%08x, context: %d\n", | | 1344 | drm_printf(m, "\tExeclist CSB[%d]: 0x%08x, context: %d\n", |
1345 | idx, hws[idx * 2], hws[idx * 2 + 1]); | | 1345 | idx, hws[idx * 2], hws[idx * 2 + 1]); |
1346 | } | | 1346 | } |
1347 | | | 1347 | |
| | | 1348 | #ifdef __linux__ |
1348 | execlists_active_lock_bh(execlists); | | 1349 | execlists_active_lock_bh(execlists); |
| | | 1350 | #else |
| | | 1351 | int s = execlists_active_lock_bh(execlists); |
| | | 1352 | #endif |
1349 | rcu_read_lock(); | | 1353 | rcu_read_lock(); |
1350 | for (port = execlists->active; (rq = *port); port++) { | | 1354 | for (port = execlists->active; (rq = *port); port++) { |
1351 | char hdr[80]; | | 1355 | char hdr[80]; |
1352 | int len; | | 1356 | int len; |
1353 | | | 1357 | |
1354 | len = snprintf(hdr, sizeof(hdr), | | 1358 | len = snprintf(hdr, sizeof(hdr), |
1355 | "\t\tActive[%d]: ", | | 1359 | "\t\tActive[%d]: ", |
1356 | (int)(port - execlists->active)); | | 1360 | (int)(port - execlists->active)); |
1357 | if (!i915_request_signaled(rq)) { | | 1361 | if (!i915_request_signaled(rq)) { |
1358 | struct intel_timeline *tl = get_timeline(rq); | | 1362 | struct intel_timeline *tl = get_timeline(rq); |
1359 | | | 1363 | |
1360 | len += snprintf(hdr + len, sizeof(hdr) - len, | | 1364 | len += snprintf(hdr + len, sizeof(hdr) - len, |
1361 | "ring:{start:%08x, hwsp:%08x, seqno:%08x}, ", | | 1365 | "ring:{start:%08x, hwsp:%08x, seqno:%08x}, ", |
| @@ -1375,27 +1379,31 @@ static void intel_engine_print_registers | | | @@ -1375,27 +1379,31 @@ static void intel_engine_print_registers |
1375 | | | 1379 | |
1376 | snprintf(hdr, sizeof(hdr), | | 1380 | snprintf(hdr, sizeof(hdr), |
1377 | "\t\tPending[%d] ring:{start:%08x, hwsp:%08x, seqno:%08x}, rq: ", | | 1381 | "\t\tPending[%d] ring:{start:%08x, hwsp:%08x, seqno:%08x}, rq: ", |
1378 | (int)(port - execlists->pending), | | 1382 | (int)(port - execlists->pending), |
1379 | i915_ggtt_offset(rq->ring->vma), | | 1383 | i915_ggtt_offset(rq->ring->vma), |
1380 | tl ? tl->hwsp_offset : 0, | | 1384 | tl ? tl->hwsp_offset : 0, |
1381 | hwsp_seqno(rq)); | | 1385 | hwsp_seqno(rq)); |
1382 | print_request(m, rq, hdr); | | 1386 | print_request(m, rq, hdr); |
1383 | | | 1387 | |
1384 | if (tl) | | 1388 | if (tl) |
1385 | intel_timeline_put(tl); | | 1389 | intel_timeline_put(tl); |
1386 | } | | 1390 | } |
1387 | rcu_read_unlock(); | | 1391 | rcu_read_unlock(); |
| | | 1392 | #ifdef __linux__ |
1388 | execlists_active_unlock_bh(execlists); | | 1393 | execlists_active_unlock_bh(execlists); |
| | | 1394 | #else |
| | | 1395 | execlists_active_unlock_bh(execlists, s); |
| | | 1396 | #endif |
1389 | } else if (INTEL_GEN(dev_priv) > 6) { | | 1397 | } else if (INTEL_GEN(dev_priv) > 6) { |
1390 | drm_printf(m, "\tPP_DIR_BASE: 0x%08x\n", | | 1398 | drm_printf(m, "\tPP_DIR_BASE: 0x%08x\n", |
1391 | ENGINE_READ(engine, RING_PP_DIR_BASE)); | | 1399 | ENGINE_READ(engine, RING_PP_DIR_BASE)); |
1392 | drm_printf(m, "\tPP_DIR_BASE_READ: 0x%08x\n", | | 1400 | drm_printf(m, "\tPP_DIR_BASE_READ: 0x%08x\n", |
1393 | ENGINE_READ(engine, RING_PP_DIR_BASE_READ)); | | 1401 | ENGINE_READ(engine, RING_PP_DIR_BASE_READ)); |
1394 | drm_printf(m, "\tPP_DIR_DCLV: 0x%08x\n", | | 1402 | drm_printf(m, "\tPP_DIR_DCLV: 0x%08x\n", |
1395 | ENGINE_READ(engine, RING_PP_DIR_DCLV)); | | 1403 | ENGINE_READ(engine, RING_PP_DIR_DCLV)); |
1396 | } | | 1404 | } |
1397 | } | | 1405 | } |
1398 | | | 1406 | |
1399 | static void print_request_ring(struct drm_printer *m, struct i915_request *rq) | | 1407 | static void print_request_ring(struct drm_printer *m, struct i915_request *rq) |
1400 | { | | 1408 | { |
1401 | void *ring; | | 1409 | void *ring; |
| @@ -1538,27 +1546,31 @@ void intel_engine_dump(struct intel_engi | | | @@ -1538,27 +1546,31 @@ void intel_engine_dump(struct intel_engi |
1538 | * Start collecting the engine busyness data for @engine. | | 1546 | * Start collecting the engine busyness data for @engine. |
1539 | * | | 1547 | * |
1540 | * Returns 0 on success or a negative error code. | | 1548 | * Returns 0 on success or a negative error code. |
1541 | */ | | 1549 | */ |
1542 | int intel_enable_engine_stats(struct intel_engine_cs *engine) | | 1550 | int intel_enable_engine_stats(struct intel_engine_cs *engine) |
1543 | { | | 1551 | { |
1544 | struct intel_engine_execlists *execlists = &engine->execlists; | | 1552 | struct intel_engine_execlists *execlists = &engine->execlists; |
1545 | unsigned long flags; | | 1553 | unsigned long flags; |
1546 | int err = 0; | | 1554 | int err = 0; |
1547 | | | 1555 | |
1548 | if (!intel_engine_supports_stats(engine)) | | 1556 | if (!intel_engine_supports_stats(engine)) |
1549 | return -ENODEV; | | 1557 | return -ENODEV; |
1550 | | | 1558 | |
| | | 1559 | #ifdef __linux__ |
1551 | execlists_active_lock_bh(execlists); | | 1560 | execlists_active_lock_bh(execlists); |
| | | 1561 | #else |
| | | 1562 | int s = execlists_active_lock_bh(execlists); |
| | | 1563 | #endif |
1552 | write_seqlock_irqsave(&engine->stats.lock, flags); | | 1564 | write_seqlock_irqsave(&engine->stats.lock, flags); |
1553 | | | 1565 | |
1554 | if (unlikely(engine->stats.enabled == ~0)) { | | 1566 | if (unlikely(engine->stats.enabled == ~0)) { |
1555 | err = -EBUSY; | | 1567 | err = -EBUSY; |
1556 | goto unlock; | | 1568 | goto unlock; |
1557 | } | | 1569 | } |
1558 | | | 1570 | |
1559 | if (engine->stats.enabled++ == 0) { | | 1571 | if (engine->stats.enabled++ == 0) { |
1560 | struct i915_request * const *port; | | 1572 | struct i915_request * const *port; |
1561 | struct i915_request *rq; | | 1573 | struct i915_request *rq; |
1562 | | | 1574 | |
1563 | engine->stats.enabled_at = ktime_get(); | | 1575 | engine->stats.enabled_at = ktime_get(); |
1564 | | | 1576 | |
| @@ -1568,27 +1580,31 @@ int intel_enable_engine_stats(struct int | | | @@ -1568,27 +1580,31 @@ int intel_enable_engine_stats(struct int |
1568 | | | 1580 | |
1569 | for (port = execlists->pending; (rq = *port); port++) { | | 1581 | for (port = execlists->pending; (rq = *port); port++) { |
1570 | /* Exclude any contexts already counted in active */ | | 1582 | /* Exclude any contexts already counted in active */ |
1571 | if (!intel_context_inflight_count(rq->context)) | | 1583 | if (!intel_context_inflight_count(rq->context)) |
1572 | engine->stats.active++; | | 1584 | engine->stats.active++; |
1573 | } | | 1585 | } |
1574 | | | 1586 | |
1575 | if (engine->stats.active) | | 1587 | if (engine->stats.active) |
1576 | engine->stats.start = engine->stats.enabled_at; | | 1588 | engine->stats.start = engine->stats.enabled_at; |
1577 | } | | 1589 | } |
1578 | | | 1590 | |
1579 | unlock: | | 1591 | unlock: |
1580 | write_sequnlock_irqrestore(&engine->stats.lock, flags); | | 1592 | write_sequnlock_irqrestore(&engine->stats.lock, flags); |
| | | 1593 | #ifdef __linux__ |
1581 | execlists_active_unlock_bh(execlists); | | 1594 | execlists_active_unlock_bh(execlists); |
| | | 1595 | #else |
| | | 1596 | execlists_active_unlock_bh(execlists, s); |
| | | 1597 | #endif |
1582 | | | 1598 | |
1583 | return err; | | 1599 | return err; |
1584 | } | | 1600 | } |
1585 | | | 1601 | |
1586 | static ktime_t __intel_engine_get_busy_time(struct intel_engine_cs *engine) | | 1602 | static ktime_t __intel_engine_get_busy_time(struct intel_engine_cs *engine) |
1587 | { | | 1603 | { |
1588 | ktime_t total = engine->stats.total; | | 1604 | ktime_t total = engine->stats.total; |
1589 | | | 1605 | |
1590 | /* | | 1606 | /* |
1591 | * If the engine is executing something at the moment | | 1607 | * If the engine is executing something at the moment |
1592 | * add it to the total. | | 1608 | * add it to the total. |
1593 | */ | | 1609 | */ |
1594 | if (engine->stats.active) | | 1610 | if (engine->stats.active) |