From 8670b06523d1fc05b0290ce0e250986660e66ac6 Mon Sep 17 00:00:00 2001 From: Pengyuan Jiao Date: Mon, 7 Aug 2017 01:09:12 +0800 Subject: [PATCH 1/3] webui: add new ctx_mode menu on the webui For profiling counters in per-vGPU mode, this menu requests for vgpu_id and hw_id of each vGPU when vGPUs are created Signed-off-by: Pengyuan Jiao --- gputop-client/gputop.js | 21 ++++++++++ gputop-data/gputop.proto | 7 ++++ gputop-server/gputop-server.c | 70 +++++++++++++++++++++++++++++++++- gputop-webui/ajax/metrics.html | 6 +++ gputop-webui/gputop-ui.js | 46 ++++++++++++++++++++++ 5 files changed, 149 insertions(+), 1 deletion(-) diff --git a/gputop-client/gputop.js b/gputop-client/gputop.js index 17302a1c..9f6ba5c5 100644 --- a/gputop-client/gputop.js +++ b/gputop-client/gputop.js @@ -30,6 +30,11 @@ var is_nodejs = false; var using_emscripten = true; +var ctx_hw_id_ = []; +var vgpu_id_ = []; +var ctx_mode=['Global']; +var map_vgpuID_hwID = [0]; + if (typeof module !== 'undefined' && module.exports) { var WebSocket = require('ws'); @@ -737,6 +742,7 @@ Gputop.prototype.set_demo_architecture = function(architecture) { this.demo_architecture = architecture; this.is_connected_ = true; + this.request_hw_id_map(); this.request_features(); } @@ -1383,6 +1389,16 @@ Gputop.prototype.rpc_request = function(method, value, closure) { } } +Gputop.prototype.request_hw_id_map = function() { + if (!this.is_demo()) { + if (this.socket_.readyState == is_nodejs ? 1 : WebSocket.OPEN) { + this.rpc_request('get_hw_id_map', true); + } else { + this.log("Can't request context hardware ID map while not connected", this.ERROR); + } + } +} + Gputop.prototype.request_features = function() { if (!this.is_demo()) { if (this.socket_.readyState == is_nodejs ? 1 : WebSocket.OPEN) { @@ -1671,6 +1687,9 @@ function gputop_socket_on_message(evt) { stream.dispatchEvent(ev); } break; + case 'hw_id': + this.update_vgpuID_hwID(msg.hw_id); + break; } if (msg.reply_uuid in this.rpc_closures_) { @@ -1824,6 +1843,7 @@ Gputop.prototype.connect = function(address, onopen, onclose, onerror) { this.log('Connecting to ' + websocket_url); this.socket_ = this.connect_web_socket(websocket_url, () => { //onopen this.is_connected_ = true; + this.request_hw_id_map(); this.request_features(); var ev = { type: "open" }; @@ -1839,6 +1859,7 @@ Gputop.prototype.connect = function(address, onopen, onclose, onerror) { }); } else { this.is_connected_ = true; + this.request_hw_id_map(); this.request_features(); var ev = { type: "open" }; diff --git a/gputop-data/gputop.proto b/gputop-data/gputop.proto index b071d1aa..2912028b 100644 --- a/gputop-data/gputop.proto +++ b/gputop-data/gputop.proto @@ -134,6 +134,11 @@ message TracepointInfo required string sample_format = 2; } +message HW_ID +{ + repeated uint64 ctx_hw_id = 1; + repeated uint64 vgpu_id = 2; +} message Message { @@ -149,6 +154,7 @@ message Message ProcessInfo process_info = 8; CpuStatsSet cpu_stats = 9; TracepointInfo tracepoint_info = 10; + HW_ID hw_id = 11; } } @@ -210,5 +216,6 @@ message Request uint32 get_process_info = 5; string test_log=6; string get_tracepoint_info = 7; + bool get_hw_id_map = 8; } } diff --git a/gputop-server/gputop-server.c b/gputop-server/gputop-server.c index a7453117..c3bda8de 100644 --- a/gputop-server/gputop-server.c +++ b/gputop-server/gputop-server.c @@ -69,7 +69,6 @@ static uv_timer_t timer; static bool update_queued; static uv_idle_t update_idle; - enum { WS_MESSAGE_PERF = 1, WS_MESSAGE_PROTOBUF, @@ -973,6 +972,71 @@ gputop_get_cmd_line_pid(uint32_t pid, char *buf, int len) return res; } +void handle_update_hw_id_map(uint64_t *vgpu_id, + uint64_t *ctx_hw_id, + int *current_vgpu_num) +{ + int i = 0; + int UUID_length = 36; + DIR *vgpu_dir; + char *vgpu_path="/sys/bus/pci/devices/0000:00:02.0"; + char *vgpu_id_path, *hw_id_path; + struct dirent *entry; + bool success_vgpu_id, success_hw_id; + + vgpu_dir=opendir(vgpu_path); + if (vgpu_dir == NULL) { + fprintf(stderr, "The path %s doesn't exist!\n", vgpu_path); + return; + } + + while (entry = readdir(vgpu_dir)) { + if (entry->d_type == DT_DIR && (strlen(entry->d_name)==UUID_length)) { + int ret_vgpu_id_path = asprintf(&vgpu_id_path, "%s/%s/intel_vgpu/vgpu_id", vgpu_path, entry->d_name); + assert(ret_vgpu_id_path != -1); + int ret_hw_id_path = asprintf(&hw_id_path, "%s/%s/intel_vgpu/hw_id", vgpu_path, entry->d_name); + assert(hw_id_path != -1); + success_vgpu_id = gputop_read_file_uint64(vgpu_id_path, vgpu_id); + free(vgpu_id_path); + vgpu_id++; + success_hw_id = gputop_read_file_uint64(hw_id_path, ctx_hw_id); + free(hw_id_path); + ctx_hw_id++; + i++; + } + } + + closedir(vgpu_dir); + *current_vgpu_num = i; +} + +static +void handle_get_hw_id_map(h2o_websocket_conn_t *conn, + Gputop__Request *request) +{ + int i = 0, max_vgpu_num = 7; + int current_vgpu_num = 0; + uint64_t ctx_hw_id[max_vgpu_num]; + uint64_t vgpu_id[max_vgpu_num]; + + handle_update_hw_id_map(vgpu_id, ctx_hw_id, ¤t_vgpu_num); + + Gputop__Message message = GPUTOP__MESSAGE__INIT; + Gputop__HWID hw_id = GPUTOP__HW__ID__INIT; + + message.reply_uuid = request->uuid; + message.cmd_case = GPUTOP__MESSAGE__CMD_HW_ID; + + hw_id.n_ctx_hw_id = current_vgpu_num; + hw_id.ctx_hw_id = ctx_hw_id; + + hw_id.n_vgpu_id = current_vgpu_num; + hw_id.vgpu_id = vgpu_id; + + message.hw_id = &hw_id; + send_pb_message(conn, &message.base); +} + static void handle_get_process_info(h2o_websocket_conn_t *conn, Gputop__Request *request) @@ -1330,6 +1394,10 @@ static void on_ws_message(h2o_websocket_conn_t *conn, case GPUTOP__REQUEST__REQ_TEST_LOG: fprintf(stderr, "TEST LOG: %s\n", request->test_log); break; + case GPUTOP__REQUEST__REQ_GET_HW_ID_MAP: + fprintf(stderr, "Get HW_ID_MAP request received\n"); + handle_get_hw_id_map(conn, request); + break; case GPUTOP__REQUEST__REQ__NOT_SET: assert(0); } diff --git a/gputop-webui/ajax/metrics.html b/gputop-webui/ajax/metrics.html index 278e4131..e6c3aeed 100644 --- a/gputop-webui/ajax/metrics.html +++ b/gputop-webui/ajax/metrics.html @@ -3,6 +3,12 @@
+