mirror of
				https://github.com/tiagovignatti/intel-gpu-tools.git
				synced 2025-11-04 12:07:12 +00:00 
			
		
		
		
	overlay: Use the new i915 PMU to query GPU busyness
And so avoid having to hold forcewake indefinitely. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
		
							parent
							
								
									5cb8c77d69
								
							
						
					
					
						commit
						2e482a3487
					
				@ -1,8 +1,11 @@
 | 
				
			|||||||
 | 
					#include <linux/perf_event.h>
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <fcntl.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "igfx.h"
 | 
					#include "igfx.h"
 | 
				
			||||||
#include "gpu-top.h"
 | 
					#include "gpu-top.h"
 | 
				
			||||||
@ -14,52 +17,156 @@
 | 
				
			|||||||
#define   RING_WAIT		(1<<11)
 | 
					#define   RING_WAIT		(1<<11)
 | 
				
			||||||
#define   RING_WAIT_SEMAPHORE	(1<<10)
 | 
					#define   RING_WAIT_SEMAPHORE	(1<<10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ring {
 | 
					#define __I915_PERF_RING(n) (4*n)
 | 
				
			||||||
 | 
					#define I915_PERF_RING_BUSY(n) (__I915_PERF_RING(n) + 0)
 | 
				
			||||||
 | 
					#define I915_PERF_RING_WAIT(n) (__I915_PERF_RING(n) + 1)
 | 
				
			||||||
 | 
					#define I915_PERF_RING_SEMA(n) (__I915_PERF_RING(n) + 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					perf_event_open(struct perf_event_attr *attr,
 | 
				
			||||||
 | 
							pid_t pid,
 | 
				
			||||||
 | 
							int cpu,
 | 
				
			||||||
 | 
							int group_fd,
 | 
				
			||||||
 | 
							unsigned long flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifndef __NR_perf_event_open
 | 
				
			||||||
 | 
					#if defined(__i386__)
 | 
				
			||||||
 | 
					#define __NR_perf_event_open 336
 | 
				
			||||||
 | 
					#elif defined(__x86_64__)
 | 
				
			||||||
 | 
					#define __NR_perf_event_open 298
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define __NR_perf_event_open 0
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    attr->size = sizeof(*attr);
 | 
				
			||||||
 | 
					    return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint64_t i915_type_id(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char buf[1024];
 | 
				
			||||||
 | 
						int fd, n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fd = open("/sys/bus/event_source/devices/i915/type", 0);
 | 
				
			||||||
 | 
						if (fd < 0)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						n = read(fd, buf, sizeof(buf)-1);
 | 
				
			||||||
 | 
						close(fd);
 | 
				
			||||||
 | 
						if (n < 0)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buf[n] = '\0';
 | 
				
			||||||
 | 
						return strtoull(buf, 0, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int perf_i915_open(int config, int group)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct perf_event_attr attr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&attr, 0, sizeof (attr));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr.type = i915_type_id();
 | 
				
			||||||
 | 
						if (attr.type == 0)
 | 
				
			||||||
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
						attr.config = config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr.freq = 1;
 | 
				
			||||||
 | 
						attr.sample_freq = 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED;
 | 
				
			||||||
 | 
						if (group == -1)
 | 
				
			||||||
 | 
							attr.read_format |= PERF_FORMAT_GROUP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return perf_event_open(&attr, -1, 0, group, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int perf_init(struct gpu_top *gt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char *names[] = {
 | 
				
			||||||
 | 
							"render",
 | 
				
			||||||
 | 
							"bitstream",
 | 
				
			||||||
 | 
							"bliter",
 | 
				
			||||||
 | 
							NULL,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						int n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gt->fd = perf_i915_open(I915_PERF_RING_BUSY(0), -1);
 | 
				
			||||||
 | 
						if (gt->fd < 0)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (perf_i915_open(I915_PERF_RING_WAIT(0), gt->fd) >= 0)
 | 
				
			||||||
 | 
							gt->have_wait = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (perf_i915_open(I915_PERF_RING_SEMA(0), gt->fd) >= 0)
 | 
				
			||||||
 | 
							gt->have_sema = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gt->ring[0].name = names[0];
 | 
				
			||||||
 | 
						gt->num_rings = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (n = 1; names[n]; n++) {
 | 
				
			||||||
 | 
							if (perf_i915_open(I915_PERF_RING_BUSY(n), gt->fd) >= 0) {
 | 
				
			||||||
 | 
								if (gt->have_wait &&
 | 
				
			||||||
 | 
								    perf_i915_open(I915_PERF_RING_WAIT(n), gt->fd) < 0)
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (gt->have_sema &&
 | 
				
			||||||
 | 
								    perf_i915_open(I915_PERF_RING_SEMA(n), gt->fd) < 0)
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								gt->ring[gt->num_rings++].name = names[n];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mmio_ring {
 | 
				
			||||||
	int id;
 | 
						int id;
 | 
				
			||||||
	uint32_t mmio;
 | 
						uint32_t base;
 | 
				
			||||||
 | 
						void *mmio;
 | 
				
			||||||
	int idle, wait, sema;
 | 
						int idle, wait, sema;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void *mmio;
 | 
					static uint32_t mmio_ring_read(struct mmio_ring *ring, uint32_t reg)
 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint32_t ring_read(struct ring *ring, uint32_t reg)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return igfx_read(mmio, ring->mmio + reg);
 | 
						return igfx_read(ring->mmio, reg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ring_init(struct ring *ring)
 | 
					static void mmio_ring_init(struct mmio_ring *ring, void *mmio)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t ctl;
 | 
						uint32_t ctl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctl = ring_read(ring, RING_CTL);
 | 
						ring->mmio = (char *)mmio + ring->base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctl = mmio_ring_read(ring, RING_CTL);
 | 
				
			||||||
	if ((ctl & 1) == 0)
 | 
						if ((ctl & 1) == 0)
 | 
				
			||||||
		ring->id = -1;
 | 
							ring->id = -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ring_reset(struct ring *ring)
 | 
					static void mmio_ring_reset(struct mmio_ring *ring)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ring->idle = 0;
 | 
						ring->idle = 0;
 | 
				
			||||||
	ring->wait = 0;
 | 
						ring->wait = 0;
 | 
				
			||||||
	ring->sema = 0;
 | 
						ring->sema = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ring_sample(struct ring *ring)
 | 
					static void mmio_ring_sample(struct mmio_ring *ring)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t head, tail, ctl;
 | 
						uint32_t head, tail, ctl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ring->id == -1)
 | 
						if (ring->id == -1)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	head = ring_read(ring, RING_HEAD) & ADDR_MASK;
 | 
						head = mmio_ring_read(ring, RING_HEAD) & ADDR_MASK;
 | 
				
			||||||
	tail = ring_read(ring, RING_TAIL) & ADDR_MASK;
 | 
						tail = mmio_ring_read(ring, RING_TAIL) & ADDR_MASK;
 | 
				
			||||||
	ring->idle += head == tail;
 | 
						ring->idle += head == tail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctl = ring_read(ring, RING_CTL);
 | 
						ctl = mmio_ring_read(ring, RING_CTL);
 | 
				
			||||||
	ring->wait += !!(ctl & RING_WAIT);
 | 
						ring->wait += !!(ctl & RING_WAIT);
 | 
				
			||||||
	ring->sema += !!(ctl & RING_WAIT_SEMAPHORE);
 | 
						ring->sema += !!(ctl & RING_WAIT_SEMAPHORE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ring_emit(struct ring *ring, int samples, union gpu_top_payload *payload)
 | 
					static void mmio_ring_emit(struct mmio_ring *ring, int samples, union gpu_top_payload *payload)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (ring->id == -1)
 | 
						if (ring->id == -1)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
@ -69,28 +176,26 @@ static void ring_emit(struct ring *ring, int samples, union gpu_top_payload *pay
 | 
				
			|||||||
	payload[ring->id].u.sema = 100 * ring->sema / samples;
 | 
						payload[ring->id].u.sema = 100 * ring->sema / samples;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void gpu_top_init(struct gpu_top *gt)
 | 
					static void mmio_init(struct gpu_top *gt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ring render_ring = {
 | 
						struct mmio_ring render_ring = {
 | 
				
			||||||
		.mmio = 0x2030,
 | 
							.base = 0x2030,
 | 
				
			||||||
		.id = 0,
 | 
							.id = 0,
 | 
				
			||||||
	}, bsd_ring = {
 | 
						}, bsd_ring = {
 | 
				
			||||||
		.mmio = 0x4030,
 | 
							.base = 0x4030,
 | 
				
			||||||
		.id = 1,
 | 
							.id = 1,
 | 
				
			||||||
	}, bsd6_ring = {
 | 
						}, bsd6_ring = {
 | 
				
			||||||
		.mmio = 0x12030,
 | 
							.base = 0x12030,
 | 
				
			||||||
		.id = 1,
 | 
							.id = 1,
 | 
				
			||||||
	}, blt_ring = {
 | 
						}, blt_ring = {
 | 
				
			||||||
		.mmio = 0x22030,
 | 
							.base = 0x22030,
 | 
				
			||||||
		.id = 2,
 | 
							.id = 2,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	const struct igfx_info *info;
 | 
						const struct igfx_info *info;
 | 
				
			||||||
	struct pci_device *igfx;
 | 
						struct pci_device *igfx;
 | 
				
			||||||
 | 
						void *mmio;
 | 
				
			||||||
	int fd[2], i;
 | 
						int fd[2], i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(gt, 0, sizeof(*gt));
 | 
					 | 
				
			||||||
	gt->fd = -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	igfx = igfx_get();
 | 
						igfx = igfx_get();
 | 
				
			||||||
	if (!igfx)
 | 
						if (!igfx)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
@ -105,6 +210,7 @@ void gpu_top_init(struct gpu_top *gt)
 | 
				
			|||||||
	default:
 | 
						default:
 | 
				
			||||||
		 fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL) | O_NONBLOCK);
 | 
							 fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL) | O_NONBLOCK);
 | 
				
			||||||
		 gt->fd = fd[0];
 | 
							 gt->fd = fd[0];
 | 
				
			||||||
 | 
							 gt->type = MMIO;
 | 
				
			||||||
		 gt->ring[0].name = "render";
 | 
							 gt->ring[0].name = "render";
 | 
				
			||||||
		 gt->num_rings = 1;
 | 
							 gt->num_rings = 1;
 | 
				
			||||||
		 if (info->gen >= 040) {
 | 
							 if (info->gen >= 040) {
 | 
				
			||||||
@ -124,54 +230,101 @@ void gpu_top_init(struct gpu_top *gt)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	mmio = igfx_get_mmio(igfx);
 | 
						mmio = igfx_get_mmio(igfx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ring_init(&render_ring);
 | 
						mmio_ring_init(&render_ring, mmio);
 | 
				
			||||||
	if (info->gen >= 060) {
 | 
						if (info->gen >= 060) {
 | 
				
			||||||
		ring_init(&bsd6_ring);
 | 
							mmio_ring_init(&bsd6_ring, mmio);
 | 
				
			||||||
		ring_init(&blt_ring);
 | 
							mmio_ring_init(&blt_ring, mmio);
 | 
				
			||||||
	} else if (info->gen >= 040) {
 | 
						} else if (info->gen >= 040) {
 | 
				
			||||||
		ring_init(&bsd_ring);
 | 
							mmio_ring_init(&bsd_ring, mmio);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (;;) {
 | 
						for (;;) {
 | 
				
			||||||
		union gpu_top_payload payload[MAX_RINGS];
 | 
							union gpu_top_payload payload[MAX_RINGS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ring_reset(&render_ring);
 | 
							mmio_ring_reset(&render_ring);
 | 
				
			||||||
		ring_reset(&bsd_ring);
 | 
							mmio_ring_reset(&bsd_ring);
 | 
				
			||||||
		ring_reset(&bsd6_ring);
 | 
							mmio_ring_reset(&bsd6_ring);
 | 
				
			||||||
		ring_reset(&blt_ring);
 | 
							mmio_ring_reset(&blt_ring);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (i = 0; i < 1000; i++) {
 | 
							for (i = 0; i < 1000; i++) {
 | 
				
			||||||
			ring_sample(&render_ring);
 | 
								mmio_ring_sample(&render_ring);
 | 
				
			||||||
			ring_sample(&bsd_ring);
 | 
								mmio_ring_sample(&bsd_ring);
 | 
				
			||||||
			ring_sample(&bsd6_ring);
 | 
								mmio_ring_sample(&bsd6_ring);
 | 
				
			||||||
			ring_sample(&blt_ring);
 | 
								mmio_ring_sample(&blt_ring);
 | 
				
			||||||
			usleep(1000);
 | 
								usleep(1000);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ring_emit(&render_ring, 1000, payload);
 | 
							mmio_ring_emit(&render_ring, 1000, payload);
 | 
				
			||||||
		ring_emit(&bsd_ring, 1000, payload);
 | 
							mmio_ring_emit(&bsd_ring, 1000, payload);
 | 
				
			||||||
		ring_emit(&bsd6_ring, 1000, payload);
 | 
							mmio_ring_emit(&bsd6_ring, 1000, payload);
 | 
				
			||||||
		ring_emit(&blt_ring, 1000, payload);
 | 
							mmio_ring_emit(&blt_ring, 1000, payload);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		write(fd[1], payload, sizeof(payload));
 | 
							write(fd[1], payload, sizeof(payload));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void gpu_top_init(struct gpu_top *gt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						memset(gt, 0, sizeof(*gt));
 | 
				
			||||||
 | 
						gt->fd = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (perf_init(gt) == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mmio_init(gt);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gpu_top_update(struct gpu_top *gt)
 | 
					int gpu_top_update(struct gpu_top *gt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t data[1024];
 | 
						uint32_t data[1024];
 | 
				
			||||||
	int len, update = 0;
 | 
						int update, len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (gt->fd < 0)
 | 
						if (gt->fd < 0)
 | 
				
			||||||
		return update;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gt->type == PERF) {
 | 
				
			||||||
 | 
							struct gpu_top_stat *s = >->stat[gt->count++&1];
 | 
				
			||||||
 | 
							struct gpu_top_stat *d = >->stat[gt->count&1];
 | 
				
			||||||
 | 
							uint64_t *sample, d_time;
 | 
				
			||||||
 | 
							int n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							len = read(gt->fd, data, sizeof(data));
 | 
				
			||||||
 | 
							if (len < 0)
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sample = (uint64_t *)data + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							s->time = *sample++;
 | 
				
			||||||
 | 
							for (n = 0; n < gt->num_rings; n++) {
 | 
				
			||||||
 | 
								s->busy[n] = sample[n];
 | 
				
			||||||
 | 
								if (gt->have_wait)
 | 
				
			||||||
 | 
									s->wait[n] = sample[n];
 | 
				
			||||||
 | 
								if (gt->have_sema)
 | 
				
			||||||
 | 
									s->sema[n] = sample[n];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (gt->count == 1)
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							d_time = s->time - d->time;
 | 
				
			||||||
 | 
							for (n = 0; n < gt->num_rings; n++) {
 | 
				
			||||||
 | 
								gt->ring[n].u.u.busy = 100 * (s->busy[n] - d->busy[n]) / d_time;
 | 
				
			||||||
 | 
								if (gt->have_wait)
 | 
				
			||||||
 | 
									gt->ring[n].u.u.wait = 100 * (s->wait[n] - d->wait[n]) / d_time;
 | 
				
			||||||
 | 
								if (gt->have_sema)
 | 
				
			||||||
 | 
									gt->ring[n].u.u.sema = 100 * (s->sema[n] - d->sema[n]) / d_time;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while ((len = read(gt->fd, data, sizeof(data))) > 0) {
 | 
					 | 
				
			||||||
		uint32_t *ptr = &data[len/sizeof(uint32_t) - MAX_RINGS];
 | 
					 | 
				
			||||||
		gt->ring[0].u.payload = ptr[0];
 | 
					 | 
				
			||||||
		gt->ring[1].u.payload = ptr[1];
 | 
					 | 
				
			||||||
		gt->ring[2].u.payload = ptr[2];
 | 
					 | 
				
			||||||
		gt->ring[3].u.payload = ptr[3];
 | 
					 | 
				
			||||||
		update = 1;
 | 
							update = 1;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							while ((len = read(gt->fd, data, sizeof(data))) > 0) {
 | 
				
			||||||
 | 
								uint32_t *ptr = &data[len/sizeof(uint32_t) - MAX_RINGS];
 | 
				
			||||||
 | 
								gt->ring[0].u.payload = ptr[0];
 | 
				
			||||||
 | 
								gt->ring[1].u.payload = ptr[1];
 | 
				
			||||||
 | 
								gt->ring[2].u.payload = ptr[2];
 | 
				
			||||||
 | 
								gt->ring[3].u.payload = ptr[3];
 | 
				
			||||||
 | 
								update = 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return update;
 | 
						return update;
 | 
				
			||||||
 | 
				
			|||||||
@ -3,8 +3,13 @@
 | 
				
			|||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gpu_top {
 | 
					struct gpu_top {
 | 
				
			||||||
 | 
						enum { PERF, MMIO } type;
 | 
				
			||||||
	int fd;
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int num_rings;
 | 
						int num_rings;
 | 
				
			||||||
 | 
						int have_wait;
 | 
				
			||||||
 | 
						int have_sema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct gpu_top_ring {
 | 
						struct gpu_top_ring {
 | 
				
			||||||
		const char *name;
 | 
							const char *name;
 | 
				
			||||||
		union gpu_top_payload {
 | 
							union gpu_top_payload {
 | 
				
			||||||
@ -16,6 +21,14 @@ struct gpu_top {
 | 
				
			|||||||
			uint32_t payload;
 | 
								uint32_t payload;
 | 
				
			||||||
		} u;
 | 
							} u;
 | 
				
			||||||
	} ring[MAX_RINGS];
 | 
						} ring[MAX_RINGS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct gpu_top_stat {
 | 
				
			||||||
 | 
							uint64_t time;
 | 
				
			||||||
 | 
							uint64_t busy[MAX_RINGS];
 | 
				
			||||||
 | 
							uint64_t wait[MAX_RINGS];
 | 
				
			||||||
 | 
							uint64_t sema[MAX_RINGS];
 | 
				
			||||||
 | 
						} stat[2];
 | 
				
			||||||
 | 
						int count;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void gpu_top_init(struct gpu_top *gt);
 | 
					void gpu_top_init(struct gpu_top *gt);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user