svga: enable DRM mks-stats via hooking to the corresponding DRM ioctls

SVGA DRM stat calls were situated but did not actually register with the mks-stats
mechanism due to absence of corresponding ioctls. The employed new ioctls in vmwgfx
are DRM_VMW_MKSSTAT_ADD and DRM_VMW_MKSSTAT_REMOVE, subject to version check.

Reviewed-by: Charmaine Lee <charmainel@vmware.com>
(cherry picked from commit be47c077cc927c27a8c36342b47697aa81719677)
(cherry picked from commit 0388afc67b830f6ab916d0839c33eb1d91d6353f)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12873>
This commit is contained in:
Martin Krastev 2021-01-31 15:34:36 +02:00 committed by Marge Bot
parent b61e9345c1
commit 4feb9c3c47
7 changed files with 548 additions and 13 deletions

View File

@ -30,14 +30,14 @@
#ifdef VMX86_STATS
#define SVGA_STATS_COUNT_INC(_sws, _stat) \
_sws->stats_inc(_stat);
_sws->stats_inc(_sws, _stat);
#define SVGA_STATS_TIME_PUSH(_sws, _stat) \
struct svga_winsys_stats_timeframe timeFrame; \
_sws->stats_time_push(_stat, &timeFrame);
_sws->stats_time_push(_sws, _stat, &timeFrame);
#define SVGA_STATS_TIME_POP(_sws) \
_sws->stats_time_pop();
_sws->stats_time_pop(_sws);
#else

View File

@ -99,6 +99,9 @@ struct svga_winsys_stats_timeframe {
uint64 startTime;
uint64 adjustedStartTime;
struct svga_winsys_stats_timeframe *enclosing;
struct svga_winsys_screen *sws;
int32 slot;
};
enum svga_stats_count {
@ -762,19 +765,19 @@ struct svga_winsys_screen
* Increment a statistic counter
*/
void
(*stats_inc)(enum svga_stats_count);
(*stats_inc)(struct svga_winsys_screen *, enum svga_stats_count);
/**
* Push a time frame onto the stack
*/
void
(*stats_time_push)(enum svga_stats_time, struct svga_winsys_stats_timeframe *);
(*stats_time_push)(struct svga_winsys_screen *, enum svga_stats_time, struct svga_winsys_stats_timeframe *);
/**
* Pop a time frame.
*/
void
(*stats_time_pop)();
(*stats_time_pop)(struct svga_winsys_screen *);
/**
* Send a host log message

View File

@ -27,6 +27,8 @@
#include "vmw_screen.h"
#include "vmw_fence.h"
#include "vmw_context.h"
#include "vmwgfx_drm.h"
#include "xf86drm.h"
#include "util/os_file.h"
#include "util/u_memory.h"
@ -41,6 +43,8 @@
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
static struct hash_table *dev_hash = NULL;
@ -55,6 +59,61 @@ static uint32_t vmw_dev_hash(const void *key)
return (major(*(dev_t *) key) << 16) | minor(*(dev_t *) key);
}
#ifdef VMX86_STATS
/**
* Initializes mksstat TLS store.
*/
static void
vmw_winsys_screen_init_mksstat(struct vmw_winsys_screen *vws)
{
size_t i;
for (i = 0; i < ARRAY_SIZE(vws->mksstat_tls); ++i) {
vws->mksstat_tls[i].stat_pages = NULL;
vws->mksstat_tls[i].stat_id = -1UL;
vws->mksstat_tls[i].pid = 0;
}
}
/**
* Deinits mksstat TLS store.
*/
static void
vmw_winsys_screen_deinit_mksstat(struct vmw_winsys_screen *vws)
{
size_t i;
for (i = 0; i < ARRAY_SIZE(vws->mksstat_tls); ++i) {
uint32_t expected = __atomic_load_n(&vws->mksstat_tls[i].pid, __ATOMIC_ACQUIRE);
if (expected == -1U) {
fprintf(stderr, "%s encountered locked mksstat TLS entry at index %lu.\n", __FUNCTION__, i);
continue;
}
if (expected == 0)
continue;
if (__atomic_compare_exchange_n(&vws->mksstat_tls[i].pid, &expected, 0, false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) {
struct drm_vmw_mksstat_remove_arg arg = {
.id = vws->mksstat_tls[i].stat_id
};
assert(vws->mksstat_tls[i].stat_pages);
assert(vws->mksstat_tls[i].stat_id != -1UL);
if (drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_MKSSTAT_REMOVE, &arg, sizeof(arg))) {
fprintf(stderr, "%s could not ioctl: %s\n", __FUNCTION__, strerror(errno));
} else if (munmap(vws->mksstat_tls[i].stat_pages, vmw_svga_winsys_stats_len())) {
fprintf(stderr, "%s could not munmap: %s\n", __FUNCTION__, strerror(errno));
}
} else {
fprintf(stderr, "%s encountered volatile mksstat TLS entry at index %lu.\n", __FUNCTION__, i);
}
}
}
#endif
/* Called from vmw_drm_create_screen(), creates and initializes the
* vmw_winsys_screen structure, which is the main entity in this
* module.
@ -112,6 +171,9 @@ vmw_winsys_create( int fd )
if (!vmw_winsys_screen_init_svga(vws))
goto out_no_svga;
#ifdef VMX86_STATS
vmw_winsys_screen_init_mksstat(vws);
#endif
_mesa_hash_table_insert(dev_hash, &vws->device, vws);
cnd_init(&vws->cs_cond);
@ -139,6 +201,9 @@ vmw_winsys_destroy(struct vmw_winsys_screen *vws)
vmw_pools_cleanup(vws);
vws->fence_ops->destroy(vws->fence_ops);
vmw_ioctl_cleanup(vws);
#ifdef VMX86_STATS
vmw_winsys_screen_deinit_mksstat(vws);
#endif
close(vws->ioctl.drm_fd);
mtx_destroy(&vws->cs_mutex);
cnd_destroy(&vws->cs_cond);

View File

@ -81,6 +81,7 @@ struct vmw_winsys_screen
boolean have_drm_2_16;
boolean have_drm_2_17;
boolean have_drm_2_18;
boolean have_drm_2_19;
} ioctl;
struct {
@ -99,6 +100,17 @@ struct vmw_winsys_screen
struct pb_fence_ops *fence_ops;
#ifdef VMX86_STATS
/*
* mksGuestStats TLS array; length must be power of two
*/
struct {
void * stat_pages;
uint64_t stat_id;
uint32_t pid;
} mksstat_tls[64];
#endif
/*
* Screen instances
*/
@ -257,4 +269,7 @@ void
vmw_svga_winsys_shader_destroy(struct svga_winsys_screen *sws,
struct svga_winsys_gb_shader *shader);
size_t
vmw_svga_winsys_stats_len(void);
#endif /* VMW_SCREEN_H_ */

View File

@ -1003,6 +1003,8 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
(version->version_major == 2 && version->version_minor > 16);
vws->ioctl.have_drm_2_18 = version->version_major > 2 ||
(version->version_major == 2 && version->version_minor > 17);
vws->ioctl.have_drm_2_19 = version->version_major > 2 ||
(version->version_major == 2 && version->version_minor > 18);
vws->ioctl.drm_execbuf_version = vws->ioctl.have_drm_2_9 ? 2 : 1;

View File

@ -33,6 +33,9 @@
*/
#include <libsync.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include "svga_cmd.h"
#include "svga3d_caps.h"
@ -52,7 +55,9 @@
#include "vmw_msg.h"
#include "vmw_shader.h"
#include "vmw_query.h"
#include "vmwgfx_drm.h"
#include "svga3d_surfacedefs.h"
#include "xf86drm.h"
/**
* Try to get a surface backing buffer from the cache
@ -60,6 +65,304 @@
*/
#define VMW_TRY_CACHED_SIZE (2*1024*1024)
#ifdef VMX86_STATS
static const char* const vmw_svga_winsys_stats_count_names[] = {
SVGA_STATS_COUNT_NAMES
};
static const char* const vmw_svga_winsys_stats_time_names[] = {
SVGA_STATS_TIME_NAMES
};
/*
* It's imperative that the above two arrays are const, so that the next
* function can be optimized to a constant.
*/
static inline size_t
vmw_svga_winsys_stats_names_len(void)
{
size_t i, res = 0;
for (i = 0; i < ARRAY_SIZE(vmw_svga_winsys_stats_count_names); ++i)
res += strlen(vmw_svga_winsys_stats_count_names[i]) + 1;
for (i = 0; i < ARRAY_SIZE(vmw_svga_winsys_stats_time_names); ++i)
res += strlen(vmw_svga_winsys_stats_time_names[i]) + 1;
return res;
}
typedef struct Atomic_uint64 {
uint64_t value;
} Atomic_uint64;
typedef struct MKSGuestStatCounter {
Atomic_uint64 count;
} MKSGuestStatCounter;
typedef struct MKSGuestStatCounterTime {
MKSGuestStatCounter counter;
Atomic_uint64 selfCycles;
Atomic_uint64 totalCycles;
} MKSGuestStatCounterTime;
#define MKS_GUEST_STAT_FLAG_NONE 0
#define MKS_GUEST_STAT_FLAG_TIME (1U << 0)
typedef __attribute__((aligned(32))) struct MKSGuestStatInfoEntry {
union {
const char *s;
uint64_t u;
} name;
union {
const char *s;
uint64_t u;
} description;
uint64_t flags;
union {
MKSGuestStatCounter *counter;
MKSGuestStatCounterTime *counterTime;
uint64_t u;
} stat;
} MKSGuestStatInfoEntry;
static __thread struct svga_winsys_stats_timeframe *mksstat_tls_global = NULL;
#define ALIGN(x, power_of_two) (((x) + (power_of_two) - 1) & ~((power_of_two) - 1))
static const size_t mksstat_area_size_info = sizeof(MKSGuestStatInfoEntry) * (SVGA_STATS_COUNT_MAX + SVGA_STATS_TIME_MAX);
static const size_t mksstat_area_size_stat = sizeof(MKSGuestStatCounter) * SVGA_STATS_COUNT_MAX +
sizeof(MKSGuestStatCounterTime) * SVGA_STATS_TIME_MAX;
size_t
vmw_svga_winsys_stats_len(void)
{
const size_t pg_size = getpagesize();
const size_t area_size_stat_pg = ALIGN(mksstat_area_size_stat, pg_size);
const size_t area_size_info_pg = ALIGN(mksstat_area_size_info, pg_size);
const size_t area_size_strs = vmw_svga_winsys_stats_names_len();
const size_t area_size = area_size_stat_pg + area_size_info_pg + area_size_strs;
return area_size;
}
/**
* vmw_mksstat_get_pstat: Computes the address of the MKSGuestStatCounter
* array from the address of the base page.
*
* @page_addr: Pointer to the base page.
* @page_size: Size of page.
* Return: Pointer to the MKSGuestStatCounter array.
*/
static inline MKSGuestStatCounter *
vmw_mksstat_get_pstat(uint8_t *page_addr, size_t page_size)
{
return (MKSGuestStatCounter *)page_addr;
}
/**
* vmw_mksstat_get_pstat_time: Computes the address of the MKSGuestStatCounterTime
* array from the address of the base page.
*
* @page_addr: Pointer to the base page.
* @page_size: Size of page.
* Return: Pointer to the MKSGuestStatCounterTime array.
*/
static inline MKSGuestStatCounterTime *
vmw_mksstat_get_pstat_time(uint8_t *page_addr, size_t page_size)
{
return (MKSGuestStatCounterTime *)(page_addr + sizeof(MKSGuestStatCounter) * SVGA_STATS_COUNT_MAX);
}
/**
* vmw_mksstat_get_pinfo: Computes the address of the MKSGuestStatInfoEntry
* array from the address of the base page.
*
* @page_addr: Pointer to the base page.
* @page_size: Size of page.
* Return: Pointer to the MKSGuestStatInfoEntry array.
*/
static inline MKSGuestStatInfoEntry *
vmw_mksstat_get_pinfo(uint8_t *page_addr, size_t page_size)
{
const size_t area_size_stat_pg = ALIGN(mksstat_area_size_stat, page_size);
return (MKSGuestStatInfoEntry *)(page_addr + area_size_stat_pg);
}
/**
* vmw_mksstat_get_pstrs: Computes the address of the mksGuestStat strings
* sequence from the address of the base page.
*
* @page_addr: Pointer to the base page.
* @page_size: Size of page.
* Return: Pointer to the mksGuestStat strings sequence.
*/
static inline char *
vmw_mksstat_get_pstrs(uint8_t *page_addr, const size_t page_size)
{
const size_t area_size_info_pg = ALIGN(mksstat_area_size_info, page_size);
const size_t area_size_stat_pg = ALIGN(mksstat_area_size_stat, page_size);
return (char *)(page_addr + area_size_info_pg + area_size_stat_pg);
}
/**
* Add all known mksGuestStats counters for tracking by the host.
*/
static int
vmw_svga_winsys_add_stats(struct vmw_winsys_screen *vws, int slot)
{
const size_t pg_size = getpagesize();
const size_t area_size = vmw_svga_winsys_stats_len();
MKSGuestStatInfoEntry *pinfo;
MKSGuestStatCounter *pstat;
MKSGuestStatCounterTime *pstatTime;
char *pstrs;
uint64_t id;
size_t i;
/* Allocate a contiguous area of pages for all info entries, counters and strings. */
void *area = mmap(NULL, area_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0);
if (area == MAP_FAILED) {
fprintf(stderr, "%s could not mmap memory: %s\n", __FUNCTION__, strerror(errno));
return -1;
}
pinfo = vmw_mksstat_get_pinfo(area, pg_size);
pstat = vmw_mksstat_get_pstat(area, pg_size);
pstrs = vmw_mksstat_get_pstrs(area, pg_size);
pstatTime = vmw_mksstat_get_pstat_time(area, pg_size);
if (mlock(area, area_size)) {
fprintf(stderr, "%s could not mlock memory: %s\n", __FUNCTION__, strerror(errno));
goto error;
}
/* Suppress pages copy-on-write; for MAP_SHARED this should not really matter; it would if we go MAP_PRIVATE */
if (madvise(area, area_size, MADV_DONTFORK)) {
fprintf(stderr, "%s could not madvise memory: %s\n", __FUNCTION__, strerror(errno));
goto error;
}
/* Set up regular counters first */
for (i = 0; i < SVGA_STATS_COUNT_MAX; ++i) {
pinfo->name.s = pstrs;
pinfo->description.s = pstrs;
pinfo->flags = MKS_GUEST_STAT_FLAG_NONE;
pinfo->stat.counter = pstat + i;
pinfo++;
memcpy(pstrs, vmw_svga_winsys_stats_count_names[i], strlen(vmw_svga_winsys_stats_count_names[i]));
pstrs += strlen(vmw_svga_winsys_stats_count_names[i]) + 1;
}
/* Set up time counters second */
for (i = 0; i < SVGA_STATS_TIME_MAX; ++i) {
pinfo->name.s = pstrs;
pinfo->description.s = pstrs;
pinfo->flags = MKS_GUEST_STAT_FLAG_TIME;
pinfo->stat.counterTime = pstatTime + i;
pinfo++;
memcpy(pstrs, vmw_svga_winsys_stats_time_names[i], strlen(vmw_svga_winsys_stats_time_names[i]));
pstrs += strlen(vmw_svga_winsys_stats_time_names[i]) + 1;
}
{ /* ioctl(DRM_VMW_MKSSTAT_ADD) */
char desc[64];
snprintf(desc, sizeof(desc) - 1, "vmw_winsys_screen=%p pid=%d", vws, gettid());
struct drm_vmw_mksstat_add_arg arg = {
.stat = (uintptr_t)pstat,
.info = (uintptr_t)vmw_mksstat_get_pinfo(area, pg_size),
.strs = (uintptr_t)vmw_mksstat_get_pstrs(area, pg_size),
.stat_len = mksstat_area_size_stat,
.info_len = mksstat_area_size_info,
.strs_len = vmw_svga_winsys_stats_names_len(),
.description = (uintptr_t)desc,
.id = -1U
};
if (drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_MKSSTAT_ADD, &arg, sizeof(arg))) {
fprintf(stderr, "%s could not ioctl: %s\n", __FUNCTION__, strerror(errno));
goto error;
}
id = arg.id;
}
vws->mksstat_tls[slot].stat_pages = area;
vws->mksstat_tls[slot].stat_id = id;
/* Don't update vws->mksstat_tls[].pid as it's reserved. */
return 0;
error:
munmap(area, area_size);
return -1;
}
/**
* Acquire a mksstat TLS slot making it immutable by other parties.
*/
static inline int
vmw_winsys_screen_mksstat_acq_slot(struct vmw_winsys_screen *vws)
{
const pid_t pid = gettid();
const size_t base = (size_t)pid % ARRAY_SIZE(vws->mksstat_tls);
size_t i;
if (mksstat_tls_global && vmw_winsys_screen(mksstat_tls_global->sws) == vws) {
const size_t slot = mksstat_tls_global->slot;
uint32_t expecpid = pid;
if (__atomic_compare_exchange_n(&vws->mksstat_tls[slot].pid, &expecpid, -1U, false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE))
return (int)slot;
}
for (i = 0; i < ARRAY_SIZE(vws->mksstat_tls); ++i) {
const size_t slot = (i + base) % ARRAY_SIZE(vws->mksstat_tls);
uint32_t expecpid = pid;
uint32_t expected = 0;
/* Check if pid is already present */
if (__atomic_compare_exchange_n(&vws->mksstat_tls[slot].pid, &expecpid, -1U, false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE))
return (int)slot;
/* Try to set up a new mksstat for this pid */
if (__atomic_compare_exchange_n(&vws->mksstat_tls[slot].pid, &expected, -1U, false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) {
const int ret = vmw_svga_winsys_add_stats(vws, slot);
if (!ret)
return (int)slot;
__atomic_store_n(&vws->mksstat_tls[slot].pid, 0, __ATOMIC_RELEASE);
return ret;
}
}
return -1;
}
/**
* Release a mksstat TLS slot -- caller still owns the slot but now it is erasable by other parties.
*/
static inline void
vmw_winsys_screen_mksstat_rel_slot(struct vmw_winsys_screen *vws, int slot)
{
assert(slot < ARRAY_SIZE(vws->mksstat_tls));
__atomic_store_n(&vws->mksstat_tls[slot].pid, gettid(), __ATOMIC_RELEASE);
}
static inline uint64_t
rdtsc(void)
{
uint32_t hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return (uint64_t)lo | ((uint64_t)hi << 32);
}
#endif /* VMX86_STATS */
static struct svga_winsys_buffer *
vmw_svga_winsys_buffer_create(struct svga_winsys_screen *sws,
unsigned alignment,
@ -465,20 +768,110 @@ vmw_svga_winsys_shader_destroy(struct svga_winsys_screen *sws,
vmw_svga_winsys_shader_reference(&d_shader, NULL);
}
#ifdef VMX86_STATS
static void
vmw_svga_winsys_stats_inc(enum svga_stats_count index)
vmw_svga_winsys_stats_inc(struct svga_winsys_screen *sws,
enum svga_stats_count index)
{
struct vmw_winsys_screen *const vws = vmw_winsys_screen(sws);
const int slot = vmw_winsys_screen_mksstat_acq_slot(vws);
assert(index < SVGA_STATS_COUNT_MAX);
if (slot >= 0) {
MKSGuestStatCounter *pstat;
assert(vws->mksstat_tls[slot].stat_pages);
assert(vws->mksstat_tls[slot].stat_id != -1UL);
pstat = vmw_mksstat_get_pstat(vws->mksstat_tls[slot].stat_pages, getpagesize());
__atomic_fetch_add(&pstat[index].count.value, 1, __ATOMIC_ACQ_REL);
vmw_winsys_screen_mksstat_rel_slot(vws, slot);
}
}
static void
vmw_svga_winsys_stats_time_push(enum svga_stats_time index,
vmw_svga_winsys_stats_time_push(struct svga_winsys_screen *sws,
enum svga_stats_time index,
struct svga_winsys_stats_timeframe *tf)
{
struct vmw_winsys_screen *const vws = vmw_winsys_screen(sws);
const int slot = vmw_winsys_screen_mksstat_acq_slot(vws);
if (slot < 0)
return;
assert(vws->mksstat_tls[slot].stat_pages);
assert(vws->mksstat_tls[slot].stat_id != -1UL);
tf->counterTime = vmw_mksstat_get_pstat_time(vws->mksstat_tls[slot].stat_pages, getpagesize()) + index;
vmw_winsys_screen_mksstat_rel_slot(vws, slot);
tf->startTime = rdtsc();
tf->enclosing = mksstat_tls_global;
tf->sws = sws;
tf->slot = slot;
mksstat_tls_global = tf;
}
static void
vmw_svga_winsys_stats_time_pop()
vmw_svga_winsys_stats_time_pop(struct svga_winsys_screen *sws)
{
struct svga_winsys_stats_timeframe *const tf = mksstat_tls_global;
struct vmw_winsys_screen *const vws = vmw_winsys_screen(sws);
const int slot = tf->slot;
uint32_t expected = gettid();
mksstat_tls_global = tf->enclosing;
if (slot < 0)
return;
if (__atomic_compare_exchange_n(&vws->mksstat_tls[slot].pid, &expected, -1U, false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) {
const uint64_t dt = rdtsc() - tf->startTime;
MKSGuestStatCounterTime *const counterTime = tf->counterTime;
assert(vws->mksstat_tls[slot].stat_pages);
assert(vws->mksstat_tls[slot].stat_id != -1UL);
__atomic_fetch_add(&counterTime->counter.count.value, 1, __ATOMIC_ACQ_REL);
__atomic_fetch_add(&counterTime->selfCycles.value, dt, __ATOMIC_ACQ_REL);
__atomic_fetch_add(&counterTime->totalCycles.value, dt, __ATOMIC_ACQ_REL);
if (tf->enclosing) {
MKSGuestStatCounterTime *const counterTime = tf->enclosing->counterTime;
assert(counterTime);
__atomic_fetch_sub(&counterTime->selfCycles.value, dt, __ATOMIC_ACQ_REL);
}
__atomic_store_n(&vws->mksstat_tls[slot].pid, expected, __ATOMIC_RELEASE);
}
}
#endif /* VMX86_STATS */
static void
vmw_svga_winsys_stats_inc_noop(struct svga_winsys_screen *sws,
enum svga_stats_count index)
{
/* noop */
}
static void
vmw_svga_winsys_stats_time_push_noop(struct svga_winsys_screen *sws,
enum svga_stats_time index,
struct svga_winsys_stats_timeframe *tf)
{
/* noop */
}
static void
vmw_svga_winsys_stats_time_pop_noop(struct svga_winsys_screen *sws)
{
/* noop */
}
boolean
@ -511,10 +904,23 @@ vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws)
vws->base.query_destroy = vmw_svga_winsys_query_destroy;
vws->base.query_get_result = vmw_svga_winsys_query_get_result;
vws->base.stats_inc = vmw_svga_winsys_stats_inc;
vws->base.stats_time_push = vmw_svga_winsys_stats_time_push;
vws->base.stats_time_pop = vmw_svga_winsys_stats_time_pop;
#ifdef VMX86_STATS
if (vws->ioctl.have_drm_2_19) {
vws->base.stats_inc = vmw_svga_winsys_stats_inc;
vws->base.stats_time_push = vmw_svga_winsys_stats_time_push;
vws->base.stats_time_pop = vmw_svga_winsys_stats_time_pop;
} else {
vws->base.stats_inc = vmw_svga_winsys_stats_inc_noop;
vws->base.stats_time_push = vmw_svga_winsys_stats_time_push_noop;
vws->base.stats_time_pop = vmw_svga_winsys_stats_time_pop_noop;
}
#else
vws->base.stats_inc = vmw_svga_winsys_stats_inc_noop;
vws->base.stats_time_push = vmw_svga_winsys_stats_time_push_noop;
vws->base.stats_time_pop = vmw_svga_winsys_stats_time_pop_noop;
#endif
vws->base.host_log = vmw_svga_winsys_host_log;
return TRUE;

View File

@ -72,6 +72,9 @@ extern "C" {
#define DRM_VMW_GB_SURFACE_CREATE_EXT 27
#define DRM_VMW_GB_SURFACE_REF_EXT 28
#define DRM_VMW_MSG 29
#define DRM_VMW_MKSSTAT_RESET 30
#define DRM_VMW_MKSSTAT_ADD 31
#define DRM_VMW_MKSSTAT_REMOVE 32
/*************************************************************************/
/**
@ -86,6 +89,9 @@ extern "C" {
*
* DRM_VMW_PARAM_SM4_1
* SM4_1 support is enabled.
*
* DRM_VMW_PARAM_SM5
* SM5 support is enabled.
*/
#define DRM_VMW_PARAM_NUM_STREAMS 0
@ -1134,7 +1140,7 @@ struct drm_vmw_handle_close_arg {
* svga3d surface flags split into 2, upper half and lower half.
*/
enum drm_vmw_surface_version {
drm_vmw_gb_surface_v1
drm_vmw_gb_surface_v1,
};
/**
@ -1233,6 +1239,44 @@ struct drm_vmw_msg_arg {
__u32 receive_len;
};
/**
* struct drm_vmw_mksstat_add_arg
*
* @stat: Pointer to user-space stat-counters array, page-aligned.
* @info: Pointer to user-space counter-infos array, page-aligned.
* @strs: Pointer to user-space stat strings, page-aligned.
* @stat_len: Length in bytes of stat-counters array.
* @info_len: Length in bytes of counter-infos array.
* @strs_len: Length in bytes of the stat strings, terminators included.
* @description: Pointer to instance descriptor string; will be truncated
* to MKS_GUEST_STAT_INSTANCE_DESC_LENGTH chars.
* @id: Output identifier of the produced record; -1 if error.
*
* Argument to the DRM_VMW_MKSSTAT_ADD ioctl.
*/
struct drm_vmw_mksstat_add_arg {
__u64 stat;
__u64 info;
__u64 strs;
__u64 stat_len;
__u64 info_len;
__u64 strs_len;
__u64 description;
__u64 id;
};
/**
* struct drm_vmw_mksstat_remove_arg
*
* @id: Identifier of the record being disposed, originally obtained through
* DRM_VMW_MKSSTAT_ADD ioctl.
*
* Argument to the DRM_VMW_MKSSTAT_REMOVE ioctl.
*/
struct drm_vmw_mksstat_remove_arg {
__u64 id;
};
#if defined(__cplusplus)
}
#endif