From 820e8d94b9b01dc97d410b02df1d7cdb54c2965f Mon Sep 17 00:00:00 2001 From: beanfacts Date: Thu, 9 May 2024 19:02:55 +0200 Subject: [PATCH] Add basic support for B7 RC / KVMFR 20 This is a minor patch adding partial support for the updated KVMFR version. Support for the RGB 24-in-32 operating mode may not work as expected, but non-compressed modes used in previous versions, such as BGRA/RGBA, should continue to work. Note that the overarching plan for LGProxy is still to overhaul the architecture, as this code is a mess. This is a stop-gap measure so that users can benefit from the new Looking Glass features within LGProxy. Creation of further discussions or issues is welcome, so that new feature additions and bugfixes can be triaged based on user feedback. Changes: - Use upstream Looking Glass again, as I won't maintain the texture compression fork - Remove compressed texture support (see above). If you need texture compression support, use the old version `1ef3453`. - Update copyright short identifier to GPL 2.0 or later - Update help messages - Use the OS name field in KVMFR to display the LGProxy relay version - Update C standard to C11. It should already have been used in practice due to LG using it, but we define it here explicitly now. - Enable optimization. We barely tested LGProxy with optimization, so it might break things. - Enable sleep periods under 1ms and sync mode. This still has a quite a few problems that have to be ironed out, but in theory it will further reduce CPU usage. Specific Recommendations: - For TCP users, we recommend trying the new native TCP provider in Libfabric by updating your Libfabric versions (on both sides) to version 1.18.0 or higher. While this is no alternative to RDMA, it should provide improved performance in TCP mode. --- lgproxy/CMakeLists.txt | 10 +-- lgproxy/common/include/lp_convert.h | 26 ++----- lgproxy/common/include/lp_msg.h | 2 +- lgproxy/common/include/lp_retrieve.h | 2 +- lgproxy/common/include/lp_trf_client.h | 2 +- lgproxy/common/include/lp_trf_server.h | 2 +- lgproxy/common/include/lp_types.h | 15 ++-- lgproxy/common/include/lp_utils.h | 7 +- lgproxy/common/include/lp_write.h | 2 +- lgproxy/common/src/lp_msg.c | 2 +- lgproxy/common/src/lp_retrieve.c | 11 +-- lgproxy/common/src/lp_trf_client.c | 2 +- lgproxy/common/src/lp_trf_server.c | 2 +- lgproxy/common/src/lp_types.c | 2 +- lgproxy/common/src/lp_utils.c | 102 +++++++++++++++++++------ lgproxy/common/src/lp_write.c | 41 ++++++---- lgproxy/sink/lp_sink.c | 66 +++++++++++----- lgproxy/sink/lp_sink.h | 2 +- lgproxy/source/lp_source.c | 42 +++++++--- lgproxy/source/lp_source.h | 2 +- 20 files changed, 222 insertions(+), 120 deletions(-) diff --git a/lgproxy/CMakeLists.txt b/lgproxy/CMakeLists.txt index 5d2dac0..f14559c 100644 --- a/lgproxy/CMakeLists.txt +++ b/lgproxy/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0.0) +cmake_minimum_required(VERSION 3.5.0) project(lgproxy LANGUAGES C) get_filename_component(PROJECT_TOP "${PROJECT_SOURCE_DIR}/.." ABSOLUTE) @@ -50,8 +50,8 @@ add_compile_options( "-ffast-math" "-fdata-sections" "-ffunction-sections" -#"$<$:-O0;-g3;-ggdb>" -"-O0;-g3;-ggdb" +"$<$:-O0;-g3;-ggdb>" +# "-O0;-g3;-ggdb" ) file(COPY "${PROJECT_TOP}/repos/libtrf/libtrf/conf" DESTINATION "./source_build") @@ -80,14 +80,14 @@ set(SINK add_executable(source ${SOURCE}) target_link_libraries(source trf lgmp m lg_common protobuf-c) -set_property(TARGET source PROPERTY C_STANDARD 99) +set_property(TARGET source PROPERTY C_STANDARD 11) set_target_properties(source PROPERTIES RUNTIME_OUTPUT_DIRECTORY "./source_build") add_executable(sink ${SINK}) target_link_libraries(sink trf lgmp m lg_common protobuf-c) -set_property(TARGET sink PROPERTY C_STANDARD 99) +set_property(TARGET sink PROPERTY C_STANDARD 11) set_target_properties(sink PROPERTIES RUNTIME_OUTPUT_DIRECTORY "./sink_build") diff --git a/lgproxy/common/include/lp_convert.h b/lgproxy/common/include/lp_convert.h index b303412..950ae94 100644 --- a/lgproxy/common/include/lp_convert.h +++ b/lgproxy/common/include/lp_convert.h @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy @@ -46,16 +46,10 @@ static inline uint64_t lpLGToTrfFormat(int lg_type) return TRF_TEX_RGBA_1010102; case FRAME_TYPE_RGBA16F: return TRF_TEX_RGBA_16161616F; - case FRAME_TYPE_RGB: + case FRAME_TYPE_RGB_24: return TRF_TEX_RGB_888; - case FRAME_TYPE_DXT1: - return TRF_TEX_DXT1; - case FRAME_TYPE_DXT5: - return TRF_TEX_DXT5; - case FRAME_TYPE_ETC2: - return TRF_TEX_ETC2; - case FRAME_TYPE_ETC2_EAC: - return TRF_TEX_ETC2_EAC; + case FRAME_TYPE_BGR_32: + return TRF_TEX_BGR_32; default: return TRF_TEX_INVALID; } @@ -80,15 +74,9 @@ static inline uint64_t lpTrftoLGFormat(int trf_type) case TRF_TEX_RGBA_16161616F: return FRAME_TYPE_RGBA16F; case TRF_TEX_RGB_888: - return FRAME_TYPE_RGB; - case TRF_TEX_DXT1: - return FRAME_TYPE_DXT1; - case TRF_TEX_DXT5: - return FRAME_TYPE_DXT5; - case TRF_TEX_ETC2: - return FRAME_TYPE_ETC2; - case TRF_TEX_ETC2_EAC: - return FRAME_TYPE_ETC2_EAC; + return FRAME_TYPE_RGB_24; + case TRF_TEX_BGR_32: + return FRAME_TYPE_BGR_32; default: return FRAME_TYPE_INVALID; } diff --git a/lgproxy/common/include/lp_msg.h b/lgproxy/common/include/lp_msg.h index 3e6ac72..5b8613c 100644 --- a/lgproxy/common/include/lp_msg.h +++ b/lgproxy/common/include/lp_msg.h @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy diff --git a/lgproxy/common/include/lp_retrieve.h b/lgproxy/common/include/lp_retrieve.h index 2a6c153..cdf367e 100644 --- a/lgproxy/common/include/lp_retrieve.h +++ b/lgproxy/common/include/lp_retrieve.h @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy diff --git a/lgproxy/common/include/lp_trf_client.h b/lgproxy/common/include/lp_trf_client.h index 9bc45a2..0fad7e9 100644 --- a/lgproxy/common/include/lp_trf_client.h +++ b/lgproxy/common/include/lp_trf_client.h @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy diff --git a/lgproxy/common/include/lp_trf_server.h b/lgproxy/common/include/lp_trf_server.h index a3ab475..06e0d11 100644 --- a/lgproxy/common/include/lp_trf_server.h +++ b/lgproxy/common/include/lp_trf_server.h @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy diff --git a/lgproxy/common/include/lp_types.h b/lgproxy/common/include/lp_types.h index 9a6b4a5..59d68c8 100644 --- a/lgproxy/common/include/lp_types.h +++ b/lgproxy/common/include/lp_types.h @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy @@ -180,15 +180,16 @@ typedef struct { typedef struct { /** - * @brief Libfabric Poll Interval default will be set to 1 millisecond - * + * @brief Libfabric polling interval in nanoseconds. If this is 0 (default), + * then busy waiting will be used. If this is negative, then the program + * will use synchronous mode. */ - int poll_int; + int64_t poll_int; /** - * @brief Delete SHM file on exit default will it will not delete the shm file unless specified - * + * @brief Delete the shared memory file on program exit. By default, this is + * false. */ - bool delete_exit; + bool delete_exit; }LPUserOpts; typedef enum { diff --git a/lgproxy/common/include/lp_utils.h b/lgproxy/common/include/lp_utils.h index 9a83cd3..4796c86 100644 --- a/lgproxy/common/include/lp_utils.h +++ b/lgproxy/common/include/lp_utils.h @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy @@ -36,9 +36,10 @@ * * @param ctx Context to use. * @param msg Message pointer to be set when a message has been received. + * @param timeoutMs Optional timeout for the message in milliseconds. * @return 0 on success, negative error code on failure. */ -int lpPollMsg(PLPContext ctx, TrfMsg__MessageWrapper ** msg); +int lpPollMsg(PLPContext ctx, TrfMsg__MessageWrapper ** msg, int timeoutMs); /** * @brief Parse bytes neede from string passed in to arguments @@ -48,6 +49,8 @@ int lpPollMsg(PLPContext ctx, TrfMsg__MessageWrapper ** msg); */ uint64_t lpParseMemString(char * data); +int64_t lpParsePollString(char * data); + /** * @brief Check if the SHM File needs to be truncated * diff --git a/lgproxy/common/include/lp_write.h b/lgproxy/common/include/lp_write.h index b38e68c..4f12b59 100644 --- a/lgproxy/common/include/lp_write.h +++ b/lgproxy/common/include/lp_write.h @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy diff --git a/lgproxy/common/src/lp_msg.c b/lgproxy/common/src/lp_msg.c index 77b3b4b..5c44a55 100644 --- a/lgproxy/common/src/lp_msg.c +++ b/lgproxy/common/src/lp_msg.c @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy diff --git a/lgproxy/common/src/lp_retrieve.c b/lgproxy/common/src/lp_retrieve.c index 4aa96f7..d19d848 100644 --- a/lgproxy/common/src/lp_retrieve.c +++ b/lgproxy/common/src/lp_retrieve.c @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy @@ -82,7 +82,7 @@ int lpClientInitSession(PLPContext ctx) for (int retry = 0; retry < 20; retry++) { status = lgmpClientSessionInit(ctx->lp_host.lgmp_client, &udataSize, - (uint8_t **) &udata); + (uint8_t **) &udata, NULL); lp__log_trace("lgmpClientSessionInit: %s", lgmpStatusString(status)); switch (status) @@ -257,11 +257,8 @@ int lpGetFrame(PLPContext ctx, KVMFRFrame ** out, FrameBuffer ** fb) } if (frame) - { - lp__log_trace("------------ Frame Received ------------"); - lp__log_trace("Frame size: %d x %d", frame->frameWidth, frame->frameHeight); - lp__log_trace("----------------------------------------"); - } + lp__log_trace("Received frame size: %d x %d", + frame->frameWidth, frame->frameHeight); frameSerial = frame->frameSerial; *out = frame; diff --git a/lgproxy/common/src/lp_trf_client.c b/lgproxy/common/src/lp_trf_client.c index e787b43..3642833 100644 --- a/lgproxy/common/src/lp_trf_client.c +++ b/lgproxy/common/src/lp_trf_client.c @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy diff --git a/lgproxy/common/src/lp_trf_server.c b/lgproxy/common/src/lp_trf_server.c index af5213b..39d7fc0 100644 --- a/lgproxy/common/src/lp_trf_server.c +++ b/lgproxy/common/src/lp_trf_server.c @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy diff --git a/lgproxy/common/src/lp_types.c b/lgproxy/common/src/lp_types.c index c79bd2e..619187b 100644 --- a/lgproxy/common/src/lp_types.c +++ b/lgproxy/common/src/lp_types.c @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy diff --git a/lgproxy/common/src/lp_utils.c b/lgproxy/common/src/lp_utils.c index 4ca2e0e..7467398 100644 --- a/lgproxy/common/src/lp_utils.c +++ b/lgproxy/common/src/lp_utils.c @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy @@ -24,23 +24,47 @@ #include "lp_utils.h" #include "version.h" -int lpPollMsg(PLPContext ctx, TrfMsg__MessageWrapper ** msg) +int lpPollMsg(PLPContext ctx, TrfMsg__MessageWrapper ** msg, int timeoutMs) { struct fi_cq_data_entry de; struct fi_cq_err_entry err; ssize_t ret; - ret = trfFabricPollRecv(ctx->lp_client.client_ctx, &de, &err, 0, 0, NULL, 1); - if (ret == 0 || ret == -EAGAIN) + struct TRFContext * tc = ctx->lp_client.client_ctx; + assert(tc); + + if (timeoutMs > 0) { + struct timespec dl; + ret = trfGetDeadline(&dl, timeoutMs); + if (ret < 0) + { + lp__log_error("Clock error: %s", strerror(-ret)); + return ret; + } + ret = trfFabricPollRecv(ctx->lp_client.client_ctx, &de, &err, + tc->opts->fab_cq_sync, tc->opts->fab_poll_rate, + &dl, 1); + } + else { - return -EAGAIN; + ret = trfFabricPollRecv(ctx->lp_client.client_ctx, &de, &err, 0, 0, + NULL, 1); } - if (ret < 0) + switch (ret) { - lp__log_error("Unable to poll CQ: %s", fi_strerror(-ret)); - return ret; + case 0: + case -EAGAIN: + return -EAGAIN; + case -ETIMEDOUT: + return -ETIMEDOUT; + case 1: + break; + default: + lp__log_error("Unable to poll CQ: %s", fi_strerror(-ret)); + return ret; } - void *msgmem = trfMemPtr(&ctx->lp_client.client_ctx->xfer.fabric->msg_mem); + + void * msgmem = trfMemPtr(&ctx->lp_client.client_ctx->xfer.fabric->msg_mem); ret = trfMsgUnpack(msg, trfMsgGetPackedLength(msgmem), trfMsgGetPayload(msgmem)); @@ -50,6 +74,7 @@ int lpPollMsg(PLPContext ctx, TrfMsg__MessageWrapper ** msg) strerror(-ret)); return ret; } + return 0; } @@ -61,22 +86,49 @@ uint64_t lpParseMemString(char * data) { return b; } - else + + switch (multiplier) { - switch (multiplier) - { - case 'K': - case 'k': - return b * 1024; - case 'M': - case 'm': - return b * 1024 * 1024; - case 'G': - case 'g': - return b * 1024 * 1024 * 1024; - default: - return 0; - } + case 'K': + case 'k': + return b * 1024; + case 'M': + case 'm': + return b * 1024 * 1024; + case 'G': + case 'g': + return b * 1024 * 1024 * 1024; + default: + return 0; + } +} + +int64_t lpParsePollString(char * data) +{ + char multiplier = data[strlen(data)-1]; + int64_t b = atoi(data); + if (multiplier >= '0' && multiplier <= '9') + { + return b * (int64_t) 1000000; + } + + switch (multiplier) + { + case 's': + case 'S': + return b * (int64_t) 1000000000; + case 'm': + case 'M': + return b * (int64_t) 1000000; + case 'u': + case 'U': + return b * (int64_t) 1000; + case 'n': + case 'N': + return b; + default: + lp__log_warn("Invalid polling interval, defaulting to busy wait"); + return 0; } } @@ -103,7 +155,7 @@ bool lpShouldTruncate(PLPContext ctx) int lpSetDefaultOpts(PLPContext ctx) { - ctx->opts.poll_int = 1; + ctx->opts.poll_int = 0; ctx->shm = "/dev/shm/looking-glass"; return 0; } diff --git a/lgproxy/common/src/lp_write.c b/lgproxy/common/src/lp_write.c index 32b660e..324b1d9 100644 --- a/lgproxy/common/src/lp_write.c +++ b/lgproxy/common/src/lp_write.c @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy @@ -53,7 +53,7 @@ static bool appendData(KVMFRUserData * dst, const void * src, const size_t size) return true; } -static bool newKVMFRData(KVMFRUserData * dst) +static bool newKVMFRData(KVMFRUserData * dst, const char * osName) { { KVMFR kvmfr = @@ -101,10 +101,11 @@ static bool newKVMFRData(KVMFRUserData * dst) .os = KVMFR_OS_OTHER }; - const char * osName = "MS DOS Executive 6.22"; + int osNameLen = 1; if (!osName) osName = ""; - const int osNameLen = strlen(osName) + 1; + else + osNameLen = strlen(osName) + 1; KVMFRRecord record = { @@ -142,8 +143,13 @@ int lpInitHost(PLPContext ctx, PTRFDisplay display, bool initShm) lp__log_debug("Creating KVMFR data..."); + char osNameStr[128]; + osNameStr[127] = 0; + snprintf(osNameStr, sizeof(osNameStr) - 1, + "Telescope LGProxy Relay %s", LP_BUILD_VERSION); + KVMFRUserData udata = { 0 }; - if (!newKVMFRData(&udata)) + if (!newKVMFRData(&udata, osNameStr)) { lp__log_error("KVMFR data init failed!"); return -EINVAL; @@ -276,7 +282,7 @@ int lpSignalFrameDone(PLPContext ctx, PTRFDisplay disp) if (!ctx || !disp) return -EINVAL; - FrameBuffer * fb = trfGetFBPtr(disp) - FrameBufferStructSize; + FrameBuffer * fb = trfGetFBPtr(disp) - sizeof(struct stFrameBuffer); framebuffer_set_write_ptr(fb, trfGetDisplayBytes(disp)); return 0; } @@ -328,30 +334,35 @@ int lpRequestFrame(PLPContext ctx, PTRFDisplay disp) uint8_t comp = trfTextureIsCompressed(disp->format); - fi->rotation = FRAME_ROT_0; fi->frameSerial = disp->frame_cntr; fi->formatVer = 1; fi->damageRectsCount = 0; fi->type = lpTrftoLGFormat(disp->format); - fi->frameHeight = disp->height; - fi->screenHeight = disp->height; - fi->offset = trf__GetPageSize() - FrameBufferStructSize; + fi->offset = trf__GetPageSize() - sizeof(struct stFrameBuffer); fi->stride = !comp ? disp->width : 0; fi->pitch = !comp ? trfGetTextureBytes(disp->width, 1, disp->format) : trfGetTextureBytes(disp->width, disp->height, disp->format); + + // Note: this is a quick fix to get some functionality in B7 working in + // the legacy codebase. This will be refactored in the future. + + fi->dataWidth = disp->width; fi->frameWidth = disp->width; fi->screenWidth = disp->width; - fi->flags = 0; + fi->dataHeight = disp->height; + fi->frameHeight = disp->height; + fi->screenHeight = disp->height; + fi->flags = 0; lp__log_trace("Display size received: %d x %d", fi->frameWidth, fi->frameHeight); lp__log_trace("Display Type: %d", lpTrftoLGFormat(disp->format)); disp->fb_offset = ((uint8_t *) fi - (uint8_t *) ctx->ram) + fi->offset - + FrameBufferStructSize; + + sizeof(struct stFrameBuffer); FrameBuffer * fb = (FrameBuffer *) (((uint8_t *) fi) + fi->offset); framebuffer_prepare(fb); @@ -575,13 +586,15 @@ void * lpCursorThread(void * arg) struct fi_cq_data_entry de; struct fi_cq_err_entry err; - ret = trfFabricPollRecv(sc, &de, &err, 0, 0, &dl, 1); + ret = trfFabricPollRecv(sc, &de, &err, sc->opts->fab_cq_sync, + sc->opts->fab_poll_rate, &dl, 1); switch (ret) { case -FI_ETIMEDOUT: case -FI_EAGAIN: case 0: - trfSleep(sc->opts->fab_poll_rate); + if (!sc->opts->fab_cq_sync && sc->opts->fab_poll_rate > 0) + trfNanoSleep(sc->opts->fab_poll_rate); if (trf__HasPassed(CLOCK_MONOTONIC, &dl)) { ret = -ETIMEDOUT; diff --git a/lgproxy/sink/lp_sink.c b/lgproxy/sink/lp_sink.c index 5cf4362..81cd29f 100644 --- a/lgproxy/sink/lp_sink.c +++ b/lgproxy/sink/lp_sink.c @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy @@ -26,21 +26,32 @@ static const char * LP_USAGE_GUIDE_STR = \ "Looking Glass Proxy (LGProxy)\n" \ -"Copyright (c) 2022 Telescope Project Developers\n" \ -"Matthew McMullin (@matthewjmc), Tim Dettmar (@beanfacts)\n" \ +"Copyright (c) 2022 - 2024 Telescope Project Developers\n" \ +"This software is licensed under GPL 2.0 (or later)\n" \ +"Maintainer: Tim Dettmar (@beanfacts)\n" \ "\n" \ "Documentation: https://telescope-proj.github.io/lgproxy\n" \ "Documentation also contains licenses for third party libraries\n" \ "used by this project\n" \ "\n" \ "Options:\n" \ -" -h Hostname or IP address to connect to\n" \ -" -p Port or service name to connect to\n" \ +"\n" \ +" -h Hostname or IP address to listen on\n" \ +"\n" \ +" -p Port or service name to listen on\n" \ +"\n" \ " -f Shared memory or KVMFR file to use\n" \ -" -s Size of the shared memory file - not required unless\n" \ -" the file has not been created\n" \ +"\n" \ +" -s Size of the shared memory file\n" \ +" This must be specified if the file is backed by a DMABUF\n" \ +" region (/dev/kvmfr*), or if the file does not exist,\n" \ +" in which case it will be created with the specified size\n" \ +"\n" \ " -d Delete the shared memory file on exit\n" \ -" -r Polling interval in milliseconds\n" \ +"\n" \ +" -r Polling interval (default unit: ms, default value: 0)\n" \ +" [Experimental] use -1 for sync mode\n" \ +" [Experimental] use n/u/m/s for nano/micro/milli/whole seconds, respectively\n" \ ; volatile int8_t flag = 0; @@ -95,8 +106,8 @@ int main(int argc, char ** argv) ctx->opts.delete_exit = true; break; case 'r': - lp__log_info("Poll Interval: %s", optarg); - ctx->opts.poll_int = atoi(optarg); + lp__log_info("Requested polling interval: %s", optarg); + ctx->opts.poll_int = lpParsePollString(optarg); break; default: case '?': @@ -229,8 +240,20 @@ int main(int argc, char ** argv) // Set Polling Interval - ctx->lp_client.client_ctx->opts->fab_poll_rate = ctx->opts.poll_int; - ctx->lp_client.sub_channel->opts->fab_poll_rate = ctx->opts.poll_int; + struct TRFContext * cc = ctx->lp_client.client_ctx; + if (ctx->opts.poll_int < 0) + { + cc->opts->fab_cq_sync = 1; + cc->opts->fab_poll_rate = 0; + } + else + { + cc->opts->fab_cq_sync = 0; + cc->opts->fab_poll_rate = ctx->opts.poll_int; + } + + struct TRFContext * subc = ctx->lp_client.sub_channel; + subc->opts->fab_poll_rate = ctx->opts.poll_int; #define timespecdiff(_start, _end) \ (((_end).tv_sec - (_start).tv_sec) * 1000000000 + \ @@ -244,13 +267,11 @@ int main(int argc, char ** argv) displays->mem.ptr = ctx->ram; if (ctx->dma_buf) - { - lp__log_warn("DMABUF support in LibTRF and LGProxy is highly unstable!"); - lp__log_warn("Use of /dev/shm regions is recommended at this time."); - } + lp__log_warn("DMABUF in LGProxy is experimental!"); + ctx->mem_state = LP_MEM_REGISTERED_PERM; lp__log_info("Registering memory buffer"); - ret = trfRegDisplayCustom(ctx->lp_client.client_ctx, displays, + ret = trfRegDisplayCustom(cc, displays, ctx->ram_size, 0, FI_WRITE | FI_REMOTE_WRITE); if (ret < 0) { @@ -259,7 +280,6 @@ int main(int argc, char ** argv) return -1; } - while (1) { if (flag) @@ -368,10 +388,16 @@ int main(int argc, char ** argv) return -1; } - ret = lpPollMsg(ctx, &msg); + // We cannot use an infinite timeout, since we need to keep the LGMP + // session alive + if (cc->opts->fab_cq_sync) + ret = lpPollMsg(ctx, &msg, 100); + else + ret = lpPollMsg(ctx, &msg, 0); + if (ret == -EAGAIN) { - trfSleep(ctx->lp_client.client_ctx->opts->fab_poll_rate); + trfNanoSleep(cc->opts->fab_poll_rate); repeatframe = true; continue; } diff --git a/lgproxy/sink/lp_sink.h b/lgproxy/sink/lp_sink.h index e6718ca..23a78d8 100644 --- a/lgproxy/sink/lp_sink.h +++ b/lgproxy/sink/lp_sink.h @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy diff --git a/lgproxy/source/lp_source.c b/lgproxy/source/lp_source.c index 4c01be4..d6b82e8 100644 --- a/lgproxy/source/lp_source.c +++ b/lgproxy/source/lp_source.c @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy @@ -23,22 +23,34 @@ */ #include "lp_source.h" #include "version.h" +#include "module/kvmfr.h" static const char * LP_USAGE_GUIDE_STR = \ "Looking Glass Proxy (LGProxy)\n" \ -"Copyright (c) 2022 Telescope Project Developers\n" \ -"Matthew McMullin (@matthewjmc), Tim Dettmar (@beanfacts)\n" \ +"Copyright (c) 2022 - 2024 Telescope Project Developers\n" \ +"This software is licensed under GPL 2.0 (or later)\n" \ +"Maintainer: Tim Dettmar (@beanfacts)\n" \ "\n" \ "Documentation: https://telescope-proj.github.io/lgproxy\n" \ "Documentation also contains licenses for third party libraries\n" \ "used by this project\n" \ "\n" \ "Options:\n" \ +"\n" \ " -h Hostname or IP address to listen on\n" \ +"\n" \ " -p Port or service name to listen on\n" \ +"\n" \ " -f Shared memory or KVMFR file to use\n" \ -" -s Size of the shared memory file\n"; - +"\n" \ +" -s Size of the shared memory file\n" \ +" This must be specified if the file is backed by a DMABUF\n" \ +" region (/dev/kvmfr*)\n" \ +"\n" \ +" -r Polling interval (default unit: ms, default value: 0)\n" \ +" [Experimental] use -1 for sync mode\n" \ +" [Experimental] use n/u/m/s for nano/micro/milli/whole seconds, respectively\n" \ +; volatile int8_t flag = 0; @@ -86,8 +98,8 @@ int main(int argc, char ** argv) ctx->ram_size = lpParseMemString(optarg); break; case 'r': - lp__log_info("Poll Interval: %s", optarg); - ctx->opts.poll_int = atoi(optarg); + lp__log_info("Requested polling interval: %s", optarg); + ctx->opts.poll_int = lpParsePollString(optarg); break; default: case '?': @@ -182,8 +194,7 @@ int lpHandleClientReq(PLPContext ctx) lp__log_error("Does it exist and have you the appropriate permissions been set?"); goto destroy_ctx; } - - if(fileStat.st_size) + if (fileStat.st_size) { ctx->ram_size = fileStat.st_size; } @@ -340,7 +351,18 @@ int lpHandleClientReq(PLPContext ctx) } // Set Polling Interval - ctx->lp_host.client_ctx->opts->fab_poll_rate = ctx->opts.poll_int; + struct TRFContext * cc = ctx->lp_host.client_ctx; + if (ctx->opts.poll_int < 0) + { + cc->opts->fab_cq_sync = 1; + cc->opts->fab_poll_rate = 0; + } + else + { + cc->opts->fab_cq_sync = 0; + cc->opts->fab_poll_rate = ctx->opts.poll_int; + } + while (1) { diff --git a/lgproxy/source/lp_source.h b/lgproxy/source/lp_source.h index 2448a7b..0ae0ff8 100644 --- a/lgproxy/source/lp_source.h +++ b/lgproxy/source/lp_source.h @@ -1,5 +1,5 @@ /* - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later Telescope Project Looking Glass Proxy