// SPDX-License-Identifier: GPL-2.0+ /* * Debugfs tracing for bitstream buffers. This is similar to VA-API's * LIBVA_TRACE_BUFDATA in that the raw bitstream can be dumped as a debugging * aid. * * Produces one file per OUTPUT buffer. Files are automatically cleared on * STREAMOFF unless the module parameter "keep_bitstream_buffers" is set. */ #include #include #include #include #include "visl-debugfs.h" int visl_debugfs_init(struct visl_dev *dev) { dev->debugfs_root = debugfs_create_dir("visl", NULL); INIT_LIST_HEAD(&dev->bitstream_blobs); mutex_init(&dev->bitstream_lock); if (IS_ERR(dev->debugfs_root)) return PTR_ERR(dev->debugfs_root); return visl_debugfs_bitstream_init(dev); } int visl_debugfs_bitstream_init(struct visl_dev *dev) { dev->bitstream_debugfs = debugfs_create_dir("bitstream", dev->debugfs_root); if (IS_ERR(dev->bitstream_debugfs)) return PTR_ERR(dev->bitstream_debugfs); return 0; } void visl_trace_bitstream(struct visl_ctx *ctx, struct visl_run *run) { u8 *vaddr = vb2_plane_vaddr(&run->src->vb2_buf, 0); struct visl_blob *blob; size_t data_sz = vb2_get_plane_payload(&run->src->vb2_buf, 0); struct dentry *dentry; char name[32]; blob = kzalloc(sizeof(*blob), GFP_KERNEL); if (!blob) return; blob->blob.data = vzalloc(data_sz); if (!blob->blob.data) goto err_vmalloc; blob->blob.size = data_sz; snprintf(name, 32, "bitstream%d", run->src->sequence); memcpy(blob->blob.data, vaddr, data_sz); dentry = debugfs_create_blob(name, 0444, ctx->dev->bitstream_debugfs, &blob->blob); if (IS_ERR(dentry)) goto err_debugfs; blob->dentry = dentry; mutex_lock(&ctx->dev->bitstream_lock); list_add_tail(&blob->list, &ctx->dev->bitstream_blobs); mutex_unlock(&ctx->dev->bitstream_lock); return; err_debugfs: vfree(blob->blob.data); err_vmalloc: kfree(blob); } void visl_debugfs_clear_bitstream(struct visl_dev *dev) { struct visl_blob *blob; struct visl_blob *tmp; mutex_lock(&dev->bitstream_lock); if (list_empty(&dev->bitstream_blobs)) goto unlock; list_for_each_entry_safe(blob, tmp, &dev->bitstream_blobs, list) { list_del(&blob->list); debugfs_remove(blob->dentry); vfree(blob->blob.data); kfree(blob); } unlock: mutex_unlock(&dev->bitstream_lock); } void visl_debugfs_bitstream_deinit(struct visl_dev *dev) { visl_debugfs_clear_bitstream(dev); debugfs_remove_recursive(dev->bitstream_debugfs); dev->bitstream_debugfs = NULL; } void visl_debugfs_deinit(struct visl_dev *dev) { visl_debugfs_bitstream_deinit(dev); debugfs_remove_recursive(dev->debugfs_root); dev->debugfs_root = NULL; }