From: Chris Wilson <chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH] drm/i915: Cache the error string
Date: Wed, 18 Jul 2018 11:36:50 +0100 [thread overview]
Message-ID: <20180718103650.18423-1-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <20180718102916.8505-1-chris@chris-wilson.co.uk>
Currently, we convert the error state into a string every time we read
from sysfs (and sysfs reads in page size (4KiB) chunks). We do try to
window the string and only capture the portion that is being read, but
that means that we must always convert up to the window to find the
start. For a very large error state bordering on EXEC_OBJECT_CAPTURE
abuse, this is noticeable as it degrades to O(N^2)!
As we do not have a convenient hook for sysfs open(), and we would like
to keep the lazy conversion into a string, do the conversion of the
whole string on the first read and keep the string until the error state
is freed.
v2: Don't double advance simple_read_from_buffer
Reported-by: Jason Ekstrand <jason@jlekstrand.net>
Testcase: igt/gem_exec_capture/many*
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
---
drivers/gpu/drm/i915/i915_debugfs.c | 22 +-
drivers/gpu/drm/i915/i915_gpu_error.c | 309 +++++++++++---------------
drivers/gpu/drm/i915/i915_gpu_error.h | 26 +--
drivers/gpu/drm/i915/i915_sysfs.c | 20 +-
4 files changed, 154 insertions(+), 223 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 54509e44a856..095028894064 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -944,30 +944,18 @@ static ssize_t gpu_state_read(struct file *file, char __user *ubuf,
size_t count, loff_t *pos)
{
struct i915_gpu_state *error = file->private_data;
- struct drm_i915_error_state_buf str;
- ssize_t ret;
- loff_t tmp;
+ const char *error_str;
+ size_t error_len;
+ int ret;
if (!error)
return 0;
- ret = i915_error_state_buf_init(&str, error->i915, count, *pos);
+ ret = i915_error_state_to_str(error, &error_str, &error_len);
if (ret)
return ret;
- ret = i915_error_state_to_str(&str, error);
- if (ret)
- goto out;
-
- tmp = 0;
- ret = simple_read_from_buffer(ubuf, count, &tmp, str.buf, str.bytes);
- if (ret < 0)
- goto out;
-
- *pos = str.start + ret;
-out:
- i915_error_state_buf_release(&str);
- return ret;
+ return simple_read_from_buffer(ubuf, count, pos, error_str, error_len);
}
static int gpu_state_release(struct inode *inode, struct file *file)
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 8c81cf3aa182..4e8f1bbdbb07 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -76,112 +76,78 @@ static const char *purgeable_flag(int purgeable)
return purgeable ? " purgeable" : "";
}
-static bool __i915_error_ok(struct drm_i915_error_state_buf *e)
+static bool __i915_error_grow(struct drm_i915_error_state_buf *e, size_t len)
{
-
- if (!e->err && WARN(e->bytes > (e->size - 1), "overflow")) {
- e->err = -ENOSPC;
- return false;
- }
-
- if (e->bytes == e->size - 1 || e->err)
- return false;
-
- return true;
-}
-
-static bool __i915_error_seek(struct drm_i915_error_state_buf *e,
- unsigned len)
-{
- if (e->pos + len <= e->start) {
- e->pos += len;
+ if (!len)
return false;
- }
-
- /* First vsnprintf needs to fit in its entirety for memmove */
- if (len >= e->size) {
- e->err = -EIO;
- return false;
- }
- return true;
-}
+ if (e->bytes + len + 1 > e->size) {
+ size_t size = PAGE_ALIGN(e->bytes + len + 1);
+ char *buf;
-static void __i915_error_advance(struct drm_i915_error_state_buf *e,
- unsigned len)
-{
- /* If this is first printf in this window, adjust it so that
- * start position matches start of the buffer
- */
+ GEM_BUG_ON(size <= e->size);
- if (e->pos < e->start) {
- const size_t off = e->start - e->pos;
-
- /* Should not happen but be paranoid */
- if (off > len || e->bytes) {
- e->err = -EIO;
- return;
+ buf = kvmalloc(size, GFP_KERNEL);
+ if (!buf) {
+ e->err = -ENOMEM;
+ return false;
}
- memmove(e->buf, e->buf + off, len - off);
- e->bytes = len - off;
- e->pos = e->start;
- return;
+ GEM_BUG_ON(e->bytes > size);
+ memcpy(buf, e->buf, e->bytes);
+ kvfree(e->buf);
+
+ e->buf = buf;
+ e->size = size;
}
- e->bytes += len;
- e->pos += len;
+ return true;
}
__printf(2, 0)
static void i915_error_vprintf(struct drm_i915_error_state_buf *e,
- const char *f, va_list args)
+ const char *fmt, va_list args)
{
- unsigned len;
+ va_list ap;
+ int len;
- if (!__i915_error_ok(e))
+ if (e->err)
return;
- /* Seek the first printf which is hits start position */
- if (e->pos < e->start) {
- va_list tmp;
-
- va_copy(tmp, args);
- len = vsnprintf(NULL, 0, f, tmp);
- va_end(tmp);
-
- if (!__i915_error_seek(e, len))
- return;
+ va_copy(ap, args);
+ len = vsnprintf(NULL, 0, fmt, ap);
+ va_end(ap);
+ if (len <= 0) {
+ e->err = len;
+ return;
}
- len = vsnprintf(e->buf + e->bytes, e->size - e->bytes, f, args);
- if (len >= e->size - e->bytes)
- len = e->size - e->bytes - 1;
+ if (!__i915_error_grow(e, len))
+ return;
- __i915_error_advance(e, len);
+ GEM_BUG_ON(e->bytes >= e->size);
+ len = vscnprintf(e->buf + e->bytes, e->size - e->bytes, fmt, args);
+ if (len < 0) {
+ e->err = len;
+ return;
+ }
+ e->bytes += len;
}
-static void i915_error_puts(struct drm_i915_error_state_buf *e,
- const char *str)
+static void i915_error_puts(struct drm_i915_error_state_buf *e, const char *str)
{
unsigned len;
- if (!__i915_error_ok(e))
+ if (e->err || !str)
return;
len = strlen(str);
+ if (!__i915_error_grow(e, len))
+ return;
- /* Seek the first printf which is hits start position */
- if (e->pos < e->start) {
- if (!__i915_error_seek(e, len))
- return;
- }
-
- if (len >= e->size - e->bytes)
- len = e->size - e->bytes - 1;
+ GEM_BUG_ON(e->bytes + len > e->size);
memcpy(e->buf + e->bytes, str, len);
-
- __i915_error_advance(e, len);
+ e->bytes += len;
}
#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__)
@@ -258,6 +224,8 @@ static int compress_page(struct compress *c,
if (zlib_deflate(zstream, Z_SYNC_FLUSH) != Z_OK)
return -EIO;
+
+ touch_nmi_watchdog();
} while (zstream->avail_in);
/* Fallback to uncompressed if we increase size? */
@@ -623,33 +591,43 @@ static void err_print_uc(struct drm_i915_error_state_buf *m,
print_error_obj(m, NULL, "GuC log buffer", error_uc->guc_log);
}
-int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
- const struct i915_gpu_state *error)
+int i915_error_state_to_str(struct i915_gpu_state *error,
+ const char **str, size_t *len)
{
- struct drm_i915_private *dev_priv = m->i915;
+ struct drm_i915_error_state_buf m;
struct drm_i915_error_object *obj;
struct timespec64 ts;
int i, j;
if (!error) {
- err_printf(m, "No error state collected\n");
+ *str = "No error state collected\n";
+ *len = strlen(*str);
return 0;
}
+ *str = READ_ONCE(error->buf);
+ if (*str) {
+ *len = error->bytes;
+ return 0;
+ }
+
+ memset(&m, 0, sizeof(m));
+ m.i915 = error->i915;
+
if (*error->error_msg)
- err_printf(m, "%s\n", error->error_msg);
- err_printf(m, "Kernel: " UTS_RELEASE "\n");
+ err_printf(&m, "%s\n", error->error_msg);
+ err_printf(&m, "Kernel: " UTS_RELEASE "\n");
ts = ktime_to_timespec64(error->time);
- err_printf(m, "Time: %lld s %ld us\n",
+ err_printf(&m, "Time: %lld s %ld us\n",
(s64)ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC);
ts = ktime_to_timespec64(error->boottime);
- err_printf(m, "Boottime: %lld s %ld us\n",
+ err_printf(&m, "Boottime: %lld s %ld us\n",
(s64)ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC);
ts = ktime_to_timespec64(error->uptime);
- err_printf(m, "Uptime: %lld s %ld us\n",
+ err_printf(&m, "Uptime: %lld s %ld us\n",
(s64)ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC);
- err_printf(m, "Epoch: %lu jiffies (%u HZ)\n", error->epoch, HZ);
- err_printf(m, "Capture: %lu jiffies; %d ms ago, %d ms after epoch\n",
+ err_printf(&m, "Epoch: %lu jiffies (%u HZ)\n", error->epoch, HZ);
+ err_printf(&m, "Capture: %lu jiffies; %d ms ago, %d ms after epoch\n",
error->capture,
jiffies_to_msecs(jiffies - error->capture),
jiffies_to_msecs(error->capture - error->epoch));
@@ -657,63 +635,63 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
for (i = 0; i < ARRAY_SIZE(error->engine); i++) {
if (error->engine[i].hangcheck_stalled &&
error->engine[i].context.pid) {
- err_printf(m, "Active process (on ring %s): %s [%d], score %d%s\n",
- engine_name(m->i915, i),
+ err_printf(&m, "Active process (on ring %s): %s [%d], score %d%s\n",
+ engine_name(m.i915, i),
error->engine[i].context.comm,
error->engine[i].context.pid,
error->engine[i].context.ban_score,
bannable(&error->engine[i].context));
}
}
- err_printf(m, "Reset count: %u\n", error->reset_count);
- err_printf(m, "Suspend count: %u\n", error->suspend_count);
- err_printf(m, "Platform: %s\n", intel_platform_name(error->device_info.platform));
- err_print_pciid(m, error->i915);
+ err_printf(&m, "Reset count: %u\n", error->reset_count);
+ err_printf(&m, "Suspend count: %u\n", error->suspend_count);
+ err_printf(&m, "Platform: %s\n", intel_platform_name(error->device_info.platform));
+ err_print_pciid(&m, m.i915);
- err_printf(m, "IOMMU enabled?: %d\n", error->iommu);
+ err_printf(&m, "IOMMU enabled?: %d\n", error->iommu);
- if (HAS_CSR(dev_priv)) {
- struct intel_csr *csr = &dev_priv->csr;
+ if (HAS_CSR(m.i915)) {
+ struct intel_csr *csr = &m.i915->csr;
- err_printf(m, "DMC loaded: %s\n",
+ err_printf(&m, "DMC loaded: %s\n",
yesno(csr->dmc_payload != NULL));
- err_printf(m, "DMC fw version: %d.%d\n",
+ err_printf(&m, "DMC fw version: %d.%d\n",
CSR_VERSION_MAJOR(csr->version),
CSR_VERSION_MINOR(csr->version));
}
- err_printf(m, "GT awake: %s\n", yesno(error->awake));
- err_printf(m, "RPM wakelock: %s\n", yesno(error->wakelock));
- err_printf(m, "PM suspended: %s\n", yesno(error->suspended));
- err_printf(m, "EIR: 0x%08x\n", error->eir);
- err_printf(m, "IER: 0x%08x\n", error->ier);
+ err_printf(&m, "GT awake: %s\n", yesno(error->awake));
+ err_printf(&m, "RPM wakelock: %s\n", yesno(error->wakelock));
+ err_printf(&m, "PM suspended: %s\n", yesno(error->suspended));
+ err_printf(&m, "EIR: 0x%08x\n", error->eir);
+ err_printf(&m, "IER: 0x%08x\n", error->ier);
for (i = 0; i < error->ngtier; i++)
- err_printf(m, "GTIER[%d]: 0x%08x\n", i, error->gtier[i]);
- err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er);
- err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake);
- err_printf(m, "DERRMR: 0x%08x\n", error->derrmr);
- err_printf(m, "CCID: 0x%08x\n", error->ccid);
- err_printf(m, "Missed interrupts: 0x%08lx\n", dev_priv->gpu_error.missed_irq_rings);
+ err_printf(&m, "GTIER[%d]: 0x%08x\n", i, error->gtier[i]);
+ err_printf(&m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er);
+ err_printf(&m, "FORCEWAKE: 0x%08x\n", error->forcewake);
+ err_printf(&m, "DERRMR: 0x%08x\n", error->derrmr);
+ err_printf(&m, "CCID: 0x%08x\n", error->ccid);
+ err_printf(&m, "Missed interrupts: 0x%08lx\n", m.i915->gpu_error.missed_irq_rings);
for (i = 0; i < error->nfence; i++)
- err_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]);
+ err_printf(&m, " fence[%d] = %08llx\n", i, error->fence[i]);
- if (INTEL_GEN(dev_priv) >= 6) {
- err_printf(m, "ERROR: 0x%08x\n", error->error);
+ if (INTEL_GEN(m.i915) >= 6) {
+ err_printf(&m, "ERROR: 0x%08x\n", error->error);
- if (INTEL_GEN(dev_priv) >= 8)
- err_printf(m, "FAULT_TLB_DATA: 0x%08x 0x%08x\n",
+ if (INTEL_GEN(m.i915) >= 8)
+ err_printf(&m, "FAULT_TLB_DATA: 0x%08x 0x%08x\n",
error->fault_data1, error->fault_data0);
- err_printf(m, "DONE_REG: 0x%08x\n", error->done_reg);
+ err_printf(&m, "DONE_REG: 0x%08x\n", error->done_reg);
}
- if (IS_GEN7(dev_priv))
- err_printf(m, "ERR_INT: 0x%08x\n", error->err_int);
+ if (IS_GEN7(m.i915))
+ err_printf(&m, "ERR_INT: 0x%08x\n", error->err_int);
for (i = 0; i < ARRAY_SIZE(error->engine); i++) {
if (error->engine[i].engine_id != -1)
- error_print_engine(m, &error->engine[i], error->epoch);
+ error_print_engine(&m, &error->engine[i], error->epoch);
}
for (i = 0; i < ARRAY_SIZE(error->active_vm); i++) {
@@ -730,16 +708,16 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
len += scnprintf(buf + len, sizeof(buf), "%s%s",
first ? "" : ", ",
- dev_priv->engine[j]->name);
+ m.i915->engine[j]->name);
first = 0;
}
scnprintf(buf + len, sizeof(buf), ")");
- print_error_buffers(m, buf,
+ print_error_buffers(&m, buf,
error->active_bo[i],
error->active_bo_count[i]);
}
- print_error_buffers(m, "Pinned (global)",
+ print_error_buffers(&m, "Pinned (global)",
error->pinned_bo,
error->pinned_bo_count);
@@ -748,114 +726,90 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
obj = ee->batchbuffer;
if (obj) {
- err_puts(m, dev_priv->engine[i]->name);
+ err_puts(&m, m.i915->engine[i]->name);
if (ee->context.pid)
- err_printf(m, " (submitted by %s [%d], ctx %d [%d], score %d%s)",
+ err_printf(&m, " (submitted by %s [%d], ctx %d [%d], score %d%s)",
ee->context.comm,
ee->context.pid,
ee->context.handle,
ee->context.hw_id,
ee->context.ban_score,
bannable(&ee->context));
- err_printf(m, " --- gtt_offset = 0x%08x %08x\n",
+ err_printf(&m, " --- gtt_offset = 0x%08x %08x\n",
upper_32_bits(obj->gtt_offset),
lower_32_bits(obj->gtt_offset));
- print_error_obj(m, dev_priv->engine[i], NULL, obj);
+ print_error_obj(&m, m.i915->engine[i], NULL, obj);
}
for (j = 0; j < ee->user_bo_count; j++)
- print_error_obj(m, dev_priv->engine[i],
+ print_error_obj(&m, m.i915->engine[i],
"user", ee->user_bo[j]);
if (ee->num_requests) {
- err_printf(m, "%s --- %d requests\n",
- dev_priv->engine[i]->name,
+ err_printf(&m, "%s --- %d requests\n",
+ m.i915->engine[i]->name,
ee->num_requests);
for (j = 0; j < ee->num_requests; j++)
- error_print_request(m, " ",
+ error_print_request(&m, " ",
&ee->requests[j],
error->epoch);
}
if (IS_ERR(ee->waiters)) {
- err_printf(m, "%s --- ? waiters [unable to acquire spinlock]\n",
- dev_priv->engine[i]->name);
+ err_printf(&m, "%s --- ? waiters [unable to acquire spinlock]\n",
+ m.i915->engine[i]->name);
} else if (ee->num_waiters) {
- err_printf(m, "%s --- %d waiters\n",
- dev_priv->engine[i]->name,
+ err_printf(&m, "%s --- %d waiters\n",
+ m.i915->engine[i]->name,
ee->num_waiters);
for (j = 0; j < ee->num_waiters; j++) {
- err_printf(m, " seqno 0x%08x for %s [%d]\n",
+ err_printf(&m, " seqno 0x%08x for %s [%d]\n",
ee->waiters[j].seqno,
ee->waiters[j].comm,
ee->waiters[j].pid);
}
}
- print_error_obj(m, dev_priv->engine[i],
+ print_error_obj(&m, m.i915->engine[i],
"ringbuffer", ee->ringbuffer);
- print_error_obj(m, dev_priv->engine[i],
+ print_error_obj(&m, m.i915->engine[i],
"HW Status", ee->hws_page);
- print_error_obj(m, dev_priv->engine[i],
+ print_error_obj(&m, m.i915->engine[i],
"HW context", ee->ctx);
- print_error_obj(m, dev_priv->engine[i],
+ print_error_obj(&m, m.i915->engine[i],
"WA context", ee->wa_ctx);
- print_error_obj(m, dev_priv->engine[i],
+ print_error_obj(&m, m.i915->engine[i],
"WA batchbuffer", ee->wa_batchbuffer);
- print_error_obj(m, dev_priv->engine[i],
+ print_error_obj(&m, m.i915->engine[i],
"NULL context", ee->default_state);
}
if (error->overlay)
- intel_overlay_print_error_state(m, error->overlay);
+ intel_overlay_print_error_state(&m, error->overlay);
if (error->display)
- intel_display_print_error_state(m, error->display);
-
- err_print_capabilities(m, &error->device_info, &error->driver_caps);
- err_print_params(m, &error->params);
- err_print_uc(m, &error->uc);
+ intel_display_print_error_state(&m, error->display);
- if (m->bytes == 0 && m->err)
- return m->err;
-
- return 0;
-}
-
-int i915_error_state_buf_init(struct drm_i915_error_state_buf *ebuf,
- struct drm_i915_private *i915,
- size_t count, loff_t pos)
-{
- memset(ebuf, 0, sizeof(*ebuf));
- ebuf->i915 = i915;
+ err_print_capabilities(&m, &error->device_info, &error->driver_caps);
+ err_print_params(&m, &error->params);
+ err_print_uc(&m, &error->uc);
- /* We need to have enough room to store any i915_error_state printf
- * so that we can move it to start position.
- */
- ebuf->size = count + 1 > PAGE_SIZE ? count + 1 : PAGE_SIZE;
- ebuf->buf = kmalloc(ebuf->size,
- GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN);
-
- if (ebuf->buf == NULL) {
- ebuf->size = PAGE_SIZE;
- ebuf->buf = kmalloc(ebuf->size, GFP_KERNEL);
- }
-
- if (ebuf->buf == NULL) {
- ebuf->size = 128;
- ebuf->buf = kmalloc(ebuf->size, GFP_KERNEL);
+ if (m.err) {
+ kvfree(m.buf);
+ return m.err;
}
- if (ebuf->buf == NULL)
- return -ENOMEM;
-
- ebuf->start = pos;
+ error->bytes = m.bytes;
+ if (cmpxchg(&error->buf, NULL, m.buf))
+ kvfree(m.buf);
+ *len = error->bytes;
+ *str = error->buf;
return 0;
}
@@ -929,6 +883,7 @@ void __i915_gpu_state_free(struct kref *error_ref)
cleanup_params(error);
cleanup_uc_state(error);
+ kvfree(error->buf);
kfree(error);
}
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h
index f893a4e8b783..aa4e2d8893a1 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.h
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -9,6 +9,7 @@
#include <linux/kref.h>
#include <linux/ktime.h>
+#include <linux/nmi.h>
#include <linux/sched.h>
#include <drm/drm_mm.h>
@@ -191,6 +192,9 @@ struct i915_gpu_state {
} *active_bo[I915_NUM_ENGINES], *pinned_bo;
u32 active_bo_count[I915_NUM_ENGINES], pinned_bo_count;
struct i915_address_space *active_vm[I915_NUM_ENGINES];
+
+ const char *buf;
+ size_t bytes;
};
struct i915_gpu_error {
@@ -297,29 +301,19 @@ struct i915_gpu_error {
struct drm_i915_error_state_buf {
struct drm_i915_private *i915;
- unsigned int bytes;
- unsigned int size;
+ char *buf;
+
+ size_t bytes;
+ size_t size;
int err;
- u8 *buf;
- loff_t start;
- loff_t pos;
};
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
__printf(2, 3)
void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...);
-int i915_error_state_to_str(struct drm_i915_error_state_buf *estr,
- const struct i915_gpu_state *gpu);
-int i915_error_state_buf_init(struct drm_i915_error_state_buf *eb,
- struct drm_i915_private *i915,
- size_t count, loff_t pos);
-
-static inline void
-i915_error_state_buf_release(struct drm_i915_error_state_buf *eb)
-{
- kfree(eb->buf);
-}
+int i915_error_state_to_str(struct i915_gpu_state *error,
+ const char **str, size_t *len);
struct i915_gpu_state *i915_capture_gpu_state(struct drm_i915_private *i915);
void i915_capture_error_state(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index e5e6f6bb2b05..a0d54eb48700 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -516,27 +516,21 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
{
struct device *kdev = kobj_to_dev(kobj);
- struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
- struct drm_i915_error_state_buf error_str;
- struct i915_gpu_state *gpu;
+ struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
+ struct i915_gpu_state *gpu = i915_first_error_state(i915);
+ const char *error_str;
+ size_t error_len;
ssize_t ret;
- ret = i915_error_state_buf_init(&error_str, dev_priv, count, off);
- if (ret)
- return ret;
-
- gpu = i915_first_error_state(dev_priv);
- ret = i915_error_state_to_str(&error_str, gpu);
+ ret = i915_error_state_to_str(gpu, &error_str, &error_len);
if (ret)
goto out;
- ret = count < error_str.bytes ? count : error_str.bytes;
- memcpy(buf, error_str.buf, ret);
+ ret = min_t(size_t, count, error_len - off);
+ memcpy(buf, error_str + off, ret);
out:
i915_gpu_state_put(gpu);
- i915_error_state_buf_release(&error_str);
-
return ret;
}
--
2.18.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2018-07-18 10:37 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-18 10:29 [PATCH] drm/i915: Cache the error string Chris Wilson
2018-07-18 10:36 ` Chris Wilson [this message]
2018-07-18 10:38 ` ✗ Fi.CI.SPARSE: warning for " Patchwork
2018-07-18 10:59 ` ✓ Fi.CI.BAT: success " Patchwork
2018-07-18 11:21 ` ✗ Fi.CI.SPARSE: warning for drm/i915: Cache the error string (rev2) Patchwork
2018-07-18 11:42 ` ✓ Fi.CI.BAT: success " Patchwork
2018-07-18 14:35 ` ✓ Fi.CI.IGT: " Patchwork
2018-07-18 19:59 ` [PATCH v3] drm/i915: Cache the error string Chris Wilson
2018-07-18 20:28 ` ✗ Fi.CI.SPARSE: warning for drm/i915: Cache the error string (rev3) Patchwork
2018-07-18 20:50 ` ✓ Fi.CI.BAT: success " Patchwork
2018-07-18 22:11 ` ✓ Fi.CI.IGT: " Patchwork
2018-07-19 16:52 ` [PATCH v4] drm/i915: Cache the error string Chris Wilson
2018-07-19 17:08 ` ✗ Fi.CI.SPARSE: warning for drm/i915: Cache the error string (rev4) Patchwork
2018-07-19 17:30 ` ✓ Fi.CI.BAT: success " Patchwork
2018-07-19 21:13 ` ✓ Fi.CI.IGT: " Patchwork
-- strict thread matches above, loose matches on Subject: below --
2018-10-03 10:48 [PATCH] drm/i915: Cache the error string Chris Wilson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180718103650.18423-1-chris@chris-wilson.co.uk \
--to=chris@chris-wilson.co.uk \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).