17ec681f3Smrg/* 27ec681f3Smrg * Copyright 2019 Google LLC 37ec681f3Smrg * SPDX-License-Identifier: MIT 47ec681f3Smrg * 57ec681f3Smrg * based in part on anv and radv which are: 67ec681f3Smrg * Copyright © 2015 Intel Corporation 77ec681f3Smrg * Copyright © 2016 Red Hat. 87ec681f3Smrg * Copyright © 2016 Bas Nieuwenhuizen 97ec681f3Smrg */ 107ec681f3Smrg 117ec681f3Smrg#include "vn_common.h" 127ec681f3Smrg 137ec681f3Smrg#include <stdarg.h> 147ec681f3Smrg 157ec681f3Smrg#include "util/debug.h" 167ec681f3Smrg#include "util/log.h" 177ec681f3Smrg#include "util/os_misc.h" 187ec681f3Smrg#include "vk_enum_to_str.h" 197ec681f3Smrg 207ec681f3Smrgstatic const struct debug_control vn_debug_options[] = { 217ec681f3Smrg { "init", VN_DEBUG_INIT }, 227ec681f3Smrg { "result", VN_DEBUG_RESULT }, 237ec681f3Smrg { "vtest", VN_DEBUG_VTEST }, 247ec681f3Smrg { "wsi", VN_DEBUG_WSI }, 257ec681f3Smrg { NULL, 0 }, 267ec681f3Smrg}; 277ec681f3Smrg 287ec681f3Smrguint64_t vn_debug; 297ec681f3Smrg 307ec681f3Smrgstatic void 317ec681f3Smrgvn_debug_init_once(void) 327ec681f3Smrg{ 337ec681f3Smrg vn_debug = parse_debug_string(os_get_option("VN_DEBUG"), vn_debug_options); 347ec681f3Smrg} 357ec681f3Smrg 367ec681f3Smrgvoid 377ec681f3Smrgvn_debug_init(void) 387ec681f3Smrg{ 397ec681f3Smrg static once_flag once = ONCE_FLAG_INIT; 407ec681f3Smrg call_once(&once, vn_debug_init_once); 417ec681f3Smrg} 427ec681f3Smrg 437ec681f3Smrgvoid 447ec681f3Smrgvn_trace_init(void) 457ec681f3Smrg{ 467ec681f3Smrg#ifdef ANDROID 477ec681f3Smrg atrace_init(); 487ec681f3Smrg#endif 497ec681f3Smrg} 507ec681f3Smrg 517ec681f3Smrgvoid 527ec681f3Smrgvn_log(struct vn_instance *instance, const char *format, ...) 537ec681f3Smrg{ 547ec681f3Smrg va_list ap; 557ec681f3Smrg 567ec681f3Smrg va_start(ap, format); 577ec681f3Smrg mesa_log_v(MESA_LOG_DEBUG, "MESA-VIRTIO", format, ap); 587ec681f3Smrg va_end(ap); 597ec681f3Smrg 607ec681f3Smrg /* instance may be NULL or partially initialized */ 617ec681f3Smrg} 627ec681f3Smrg 637ec681f3SmrgVkResult 647ec681f3Smrgvn_log_result(struct vn_instance *instance, 657ec681f3Smrg VkResult result, 667ec681f3Smrg const char *where) 677ec681f3Smrg{ 687ec681f3Smrg vn_log(instance, "%s: %s", where, vk_Result_to_str(result)); 697ec681f3Smrg return result; 707ec681f3Smrg} 717ec681f3Smrg 727ec681f3Smrgvoid 737ec681f3Smrgvn_relax(uint32_t *iter, const char *reason) 747ec681f3Smrg{ 757ec681f3Smrg /* Yield for the first 2^busy_wait_order times and then sleep for 767ec681f3Smrg * base_sleep_us microseconds for the same number of times. After that, 777ec681f3Smrg * keep doubling both sleep length and count. 787ec681f3Smrg */ 797ec681f3Smrg const uint32_t busy_wait_order = 4; 807ec681f3Smrg const uint32_t base_sleep_us = 10; 817ec681f3Smrg const uint32_t warn_order = 12; 827ec681f3Smrg 837ec681f3Smrg (*iter)++; 847ec681f3Smrg if (*iter < (1 << busy_wait_order)) { 857ec681f3Smrg thrd_yield(); 867ec681f3Smrg return; 877ec681f3Smrg } 887ec681f3Smrg 897ec681f3Smrg /* warn occasionally if we have slept at least 1.28ms for 2048 times (plus 907ec681f3Smrg * another 2047 shorter sleeps) 917ec681f3Smrg */ 927ec681f3Smrg if (unlikely(*iter % (1 << warn_order) == 0)) 937ec681f3Smrg vn_log(NULL, "stuck in %s wait with iter at %d", reason, *iter); 947ec681f3Smrg 957ec681f3Smrg const uint32_t shift = util_last_bit(*iter) - busy_wait_order - 1; 967ec681f3Smrg os_time_sleep(base_sleep_us << shift); 977ec681f3Smrg} 98