From ed53a79cf81b13e9c16517c70713a926d49a5fe6 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Tue, 2 Oct 2018 09:07:31 +0200 Subject: [PATCH] virgl: Negotiate version with vtest server Check if server supports version negotation by sending a PING_PROTOCOL_VERSION message right before a dummy RESOURCE_BUSY_WAIT. If we don't get a reply for the first, we know the server doesn't support it. If it does support it, we can query the max protocol version supported by the server and fall back if needed. v2: - Send a new message to negotiate the protocol version, checking if the server supports this message by immediately sending a busy wait message. (Dave Airlie) v3: - Send a zero-arg command PING_PROTOCOL_VERSION so we actually keep compatibility with older servers. (Code by Dave Airlie) Signed-off-by: Tomeu Vizoso Reviewed-by: Gurchetan Singh --- .../winsys/virgl/vtest/virgl_vtest_socket.c | 52 +++++++++++++++++++ .../winsys/virgl/vtest/virgl_vtest_winsys.h | 2 + .../winsys/virgl/vtest/vtest_protocol.h | 10 ++++ 3 files changed, 64 insertions(+) diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c b/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c index d25f9a3bd9e..4d20a63ad64 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c @@ -101,6 +101,57 @@ static int virgl_vtest_send_init(struct virgl_vtest_winsys *vws) return 0; } +static int virgl_vtest_negotiate_version(struct virgl_vtest_winsys *vws) +{ + uint32_t vtest_hdr[VTEST_HDR_SIZE]; + uint32_t version_buf[VCMD_PROTOCOL_VERSION_SIZE]; + uint32_t busy_wait_buf[VCMD_BUSY_WAIT_SIZE]; + uint32_t busy_wait_result[1]; + int ret; + + vtest_hdr[VTEST_CMD_LEN] = VCMD_PING_PROTOCOL_VERSION_SIZE; + vtest_hdr[VTEST_CMD_ID] = VCMD_PING_PROTOCOL_VERSION; + virgl_block_write(vws->sock_fd, &vtest_hdr, sizeof(vtest_hdr)); + + vtest_hdr[VTEST_CMD_LEN] = VCMD_BUSY_WAIT_SIZE; + vtest_hdr[VTEST_CMD_ID] = VCMD_RESOURCE_BUSY_WAIT; + busy_wait_buf[VCMD_BUSY_WAIT_HANDLE] = 0; + busy_wait_buf[VCMD_BUSY_WAIT_FLAGS] = 0; + virgl_block_write(vws->sock_fd, &vtest_hdr, sizeof(vtest_hdr)); + virgl_block_write(vws->sock_fd, &busy_wait_buf, sizeof(busy_wait_buf)); + + ret = virgl_block_read(vws->sock_fd, vtest_hdr, sizeof(vtest_hdr)); + assert(ret); + + if (vtest_hdr[VTEST_CMD_ID] == VCMD_PING_PROTOCOL_VERSION) { + /* Read dummy busy_wait response */ + ret = virgl_block_read(vws->sock_fd, vtest_hdr, sizeof(vtest_hdr)); + assert(ret); + ret = virgl_block_read(vws->sock_fd, busy_wait_result, sizeof(busy_wait_result)); + assert(ret); + + vtest_hdr[VTEST_CMD_LEN] = VCMD_PROTOCOL_VERSION_SIZE; + vtest_hdr[VTEST_CMD_ID] = VCMD_PROTOCOL_VERSION; + version_buf[VCMD_PROTOCOL_VERSION_VERSION] = VTEST_PROTOCOL_VERSION; + virgl_block_write(vws->sock_fd, &vtest_hdr, sizeof(vtest_hdr)); + virgl_block_write(vws->sock_fd, &version_buf, sizeof(version_buf)); + + ret = virgl_block_read(vws->sock_fd, vtest_hdr, sizeof(vtest_hdr)); + assert(ret); + ret = virgl_block_read(vws->sock_fd, version_buf, sizeof(version_buf)); + assert(ret); + return version_buf[VCMD_PROTOCOL_VERSION_VERSION]; + } + + /* Read dummy busy_wait response */ + assert(vtest_hdr[VTEST_CMD_ID] == VCMD_RESOURCE_BUSY_WAIT); + ret = virgl_block_read(vws->sock_fd, busy_wait_result, sizeof(busy_wait_result)); + assert(ret); + + /* Old server, return version 0 */ + return 0; +} + int virgl_vtest_connect(struct virgl_vtest_winsys *vws) { struct sockaddr_un un; @@ -123,6 +174,7 @@ int virgl_vtest_connect(struct virgl_vtest_winsys *vws) vws->sock_fd = sock; virgl_vtest_send_init(vws); + vws->protocol_version = virgl_vtest_negotiate_version(vws); return 0; } diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.h b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.h index 031037b6b5f..3628c746444 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.h +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.h @@ -49,6 +49,8 @@ struct virgl_vtest_winsys { int num_delayed; unsigned usecs; mtx_t mutex; + + unsigned protocol_version; }; struct virgl_hw_res { diff --git a/src/gallium/winsys/virgl/vtest/vtest_protocol.h b/src/gallium/winsys/virgl/vtest/vtest_protocol.h index 95bd8c1d0bd..8eb904e73f6 100644 --- a/src/gallium/winsys/virgl/vtest/vtest_protocol.h +++ b/src/gallium/winsys/virgl/vtest/vtest_protocol.h @@ -24,6 +24,7 @@ #define VTEST_PROTOCOL #define VTEST_DEFAULT_SOCKET_NAME "/tmp/.virgl_test" +#define VTEST_PROTOCOL_VERSION 1 /* 32-bit length field */ /* 32-bit cmd field */ @@ -53,6 +54,10 @@ /* 0 length cmd */ /* resp VCMD_GET_CAPS + caps */ +#define VCMD_PING_PROTOCOL_VERSION 10 + +#define VCMD_PROTOCOL_VERSION 11 + #define VCMD_RES_CREATE_SIZE 10 #define VCMD_RES_CREATE_RES_HANDLE 0 #define VCMD_RES_CREATE_TARGET 1 @@ -87,4 +92,9 @@ #define VCMD_BUSY_WAIT_HANDLE 0 #define VCMD_BUSY_WAIT_FLAGS 1 +#define VCMD_PING_PROTOCOL_VERSION_SIZE 1 + +#define VCMD_PROTOCOL_VERSION_SIZE 1 +#define VCMD_PROTOCOL_VERSION_VERSION 0 + #endif -- 2.30.2