Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/lima: add error sysfs to export error task dump

Export /sys/class/drm/cardX/device/error sysfs for user read out
error task dump file.

Tested-by: Andreas Baierl <ichgeh@imkreisrum.de>
Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200222024210.18697-5-yuq825@gmail.com

Qiang Yu 57b517ce b78edd46

+94
+94
drivers/gpu/drm/lima/lima_drv.c
··· 276 276 .gem_prime_mmap = drm_gem_prime_mmap, 277 277 }; 278 278 279 + struct lima_block_reader { 280 + void *dst; 281 + size_t base; 282 + size_t count; 283 + size_t off; 284 + ssize_t read; 285 + }; 286 + 287 + static bool lima_read_block(struct lima_block_reader *reader, 288 + void *src, size_t src_size) 289 + { 290 + size_t max_off = reader->base + src_size; 291 + 292 + if (reader->off < max_off) { 293 + size_t size = min_t(size_t, max_off - reader->off, 294 + reader->count); 295 + 296 + memcpy(reader->dst, src + (reader->off - reader->base), size); 297 + 298 + reader->dst += size; 299 + reader->off += size; 300 + reader->read += size; 301 + reader->count -= size; 302 + } 303 + 304 + reader->base = max_off; 305 + 306 + return !!reader->count; 307 + } 308 + 309 + static ssize_t lima_error_state_read(struct file *filp, struct kobject *kobj, 310 + struct bin_attribute *attr, char *buf, 311 + loff_t off, size_t count) 312 + { 313 + struct device *dev = kobj_to_dev(kobj); 314 + struct lima_device *ldev = dev_get_drvdata(dev); 315 + struct lima_sched_error_task *et; 316 + struct lima_block_reader reader = { 317 + .dst = buf, 318 + .count = count, 319 + .off = off, 320 + }; 321 + 322 + mutex_lock(&ldev->error_task_list_lock); 323 + 324 + if (lima_read_block(&reader, &ldev->dump, sizeof(ldev->dump))) { 325 + list_for_each_entry(et, &ldev->error_task_list, list) { 326 + if (!lima_read_block(&reader, et->data, et->size)) 327 + break; 328 + } 329 + } 330 + 331 + mutex_unlock(&ldev->error_task_list_lock); 332 + return reader.read; 333 + } 334 + 335 + static ssize_t lima_error_state_write(struct file *file, struct kobject *kobj, 336 + struct bin_attribute *attr, char *buf, 337 + loff_t off, size_t count) 338 + { 339 + struct device *dev = kobj_to_dev(kobj); 340 + struct lima_device *ldev = dev_get_drvdata(dev); 341 + struct lima_sched_error_task *et, *tmp; 342 + 343 + mutex_lock(&ldev->error_task_list_lock); 344 + 345 + list_for_each_entry_safe(et, tmp, &ldev->error_task_list, list) { 346 + list_del(&et->list); 347 + kvfree(et); 348 + } 349 + 350 + ldev->dump.size = 0; 351 + ldev->dump.num_tasks = 0; 352 + 353 + mutex_unlock(&ldev->error_task_list_lock); 354 + 355 + return count; 356 + } 357 + 358 + static const struct bin_attribute lima_error_state_attr = { 359 + .attr.name = "error", 360 + .attr.mode = 0600, 361 + .size = 0, 362 + .read = lima_error_state_read, 363 + .write = lima_error_state_write, 364 + }; 365 + 279 366 static int lima_pdev_probe(struct platform_device *pdev) 280 367 { 281 368 struct lima_device *ldev; ··· 405 318 if (err < 0) 406 319 goto err_out2; 407 320 321 + platform_set_drvdata(pdev, ldev); 322 + 323 + if (sysfs_create_bin_file(&ldev->dev->kobj, &lima_error_state_attr)) 324 + dev_warn(ldev->dev, "fail to create error state sysfs\n"); 325 + 408 326 return 0; 409 327 410 328 err_out2: ··· 426 334 struct lima_device *ldev = platform_get_drvdata(pdev); 427 335 struct drm_device *ddev = ldev->ddev; 428 336 337 + sysfs_remove_bin_file(&ldev->dev->kobj, &lima_error_state_attr); 338 + platform_set_drvdata(pdev, NULL); 429 339 drm_dev_unregister(ddev); 430 340 lima_device_fini(ldev); 431 341 drm_dev_put(ddev);