intel_guc_log_debugfs.c (4041B)
1// SPDX-License-Identifier: MIT 2/* 3 * Copyright © 2020 Intel Corporation 4 */ 5 6#include <linux/fs.h> 7#include <drm/drm_print.h> 8 9#include "gt/intel_gt_debugfs.h" 10#include "intel_guc.h" 11#include "intel_guc_log.h" 12#include "intel_guc_log_debugfs.h" 13#include "intel_uc.h" 14 15static u32 obj_to_guc_log_dump_size(struct drm_i915_gem_object *obj) 16{ 17 u32 size; 18 19 if (!obj) 20 return PAGE_SIZE; 21 22 /* "0x%08x 0x%08x 0x%08x 0x%08x\n" => 16 bytes -> 44 chars => x2.75 */ 23 size = ((obj->base.size * 11) + 3) / 4; 24 25 /* Add padding for final blank line, any extra header info, etc. */ 26 size = PAGE_ALIGN(size + PAGE_SIZE); 27 28 return size; 29} 30 31static u32 guc_log_dump_size(struct intel_guc_log *log) 32{ 33 struct intel_guc *guc = log_to_guc(log); 34 35 if (!intel_guc_is_supported(guc)) 36 return PAGE_SIZE; 37 38 if (!log->vma) 39 return PAGE_SIZE; 40 41 return obj_to_guc_log_dump_size(log->vma->obj); 42} 43 44static int guc_log_dump_show(struct seq_file *m, void *data) 45{ 46 struct drm_printer p = drm_seq_file_printer(m); 47 int ret; 48 49 ret = intel_guc_log_dump(m->private, &p, false); 50 51 if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && seq_has_overflowed(m)) 52 pr_warn_once("preallocated size:%zx for %s exceeded\n", 53 m->size, __func__); 54 55 return ret; 56} 57DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(guc_log_dump, guc_log_dump_size); 58 59static u32 guc_load_err_dump_size(struct intel_guc_log *log) 60{ 61 struct intel_guc *guc = log_to_guc(log); 62 struct intel_uc *uc = container_of(guc, struct intel_uc, guc); 63 64 if (!intel_guc_is_supported(guc)) 65 return PAGE_SIZE; 66 67 return obj_to_guc_log_dump_size(uc->load_err_log); 68} 69 70static int guc_load_err_log_dump_show(struct seq_file *m, void *data) 71{ 72 struct drm_printer p = drm_seq_file_printer(m); 73 74 if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && seq_has_overflowed(m)) 75 pr_warn_once("preallocated size:%zx for %s exceeded\n", 76 m->size, __func__); 77 78 return intel_guc_log_dump(m->private, &p, true); 79} 80DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(guc_load_err_log_dump, guc_load_err_dump_size); 81 82static int guc_log_level_get(void *data, u64 *val) 83{ 84 struct intel_guc_log *log = data; 85 86 if (!log->vma) 87 return -ENODEV; 88 89 *val = intel_guc_log_get_level(log); 90 91 return 0; 92} 93 94static int guc_log_level_set(void *data, u64 val) 95{ 96 struct intel_guc_log *log = data; 97 98 if (!log->vma) 99 return -ENODEV; 100 101 return intel_guc_log_set_level(log, val); 102} 103 104DEFINE_SIMPLE_ATTRIBUTE(guc_log_level_fops, 105 guc_log_level_get, guc_log_level_set, 106 "%lld\n"); 107 108static int guc_log_relay_open(struct inode *inode, struct file *file) 109{ 110 struct intel_guc_log *log = inode->i_private; 111 112 if (!intel_guc_is_ready(log_to_guc(log))) 113 return -ENODEV; 114 115 file->private_data = log; 116 117 return intel_guc_log_relay_open(log); 118} 119 120static ssize_t 121guc_log_relay_write(struct file *filp, 122 const char __user *ubuf, 123 size_t cnt, 124 loff_t *ppos) 125{ 126 struct intel_guc_log *log = filp->private_data; 127 int val; 128 int ret; 129 130 ret = kstrtoint_from_user(ubuf, cnt, 0, &val); 131 if (ret < 0) 132 return ret; 133 134 /* 135 * Enable and start the guc log relay on value of 1. 136 * Flush log relay for any other value. 137 */ 138 if (val == 1) 139 ret = intel_guc_log_relay_start(log); 140 else 141 intel_guc_log_relay_flush(log); 142 143 return ret ?: cnt; 144} 145 146static int guc_log_relay_release(struct inode *inode, struct file *file) 147{ 148 struct intel_guc_log *log = inode->i_private; 149 150 intel_guc_log_relay_close(log); 151 return 0; 152} 153 154static const struct file_operations guc_log_relay_fops = { 155 .owner = THIS_MODULE, 156 .open = guc_log_relay_open, 157 .write = guc_log_relay_write, 158 .release = guc_log_relay_release, 159}; 160 161void intel_guc_log_debugfs_register(struct intel_guc_log *log, 162 struct dentry *root) 163{ 164 static const struct intel_gt_debugfs_file files[] = { 165 { "guc_log_dump", &guc_log_dump_fops, NULL }, 166 { "guc_load_err_log_dump", &guc_load_err_log_dump_fops, NULL }, 167 { "guc_log_level", &guc_log_level_fops, NULL }, 168 { "guc_log_relay", &guc_log_relay_fops, NULL }, 169 }; 170 171 if (!intel_guc_is_supported(log_to_guc(log))) 172 return; 173 174 intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), log); 175}