Felipe Balbi <felipe.ba...@linux.intel.com> writes:

> Allow for ftrace data to be exported over a USB Gadget
> Controller. With this, we have a potentially very fast pipe for
> transmitting ftrace data to a Host PC for further analysis.
>
> Note that in order to decode the data, one needs access to kernel
> symbols in order to convert binary data into function names and what
> not.
>
> Signed-off-by: Felipe Balbi <felipe.ba...@linux.intel.com>
> ---
>  drivers/usb/gadget/Kconfig            |  15 +
>  drivers/usb/gadget/function/Makefile  |   2 +
>  drivers/usb/gadget/function/f-trace.c | 401 ++++++++++++++++++++++++++
>  3 files changed, 418 insertions(+)
>  create mode 100644 drivers/usb/gadget/function/f-trace.c
>
> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
> index 31cce7805eb2..dfd181e0d717 100644
> --- a/drivers/usb/gadget/Kconfig
> +++ b/drivers/usb/gadget/Kconfig
> @@ -191,6 +191,9 @@ config USB_F_MASS_STORAGE
>  config USB_F_FS
>       tristate
>  
> +config USB_F_TRACE
> +     tristate
> +
>  config USB_F_UAC1
>       tristate
>  
> @@ -368,6 +371,18 @@ config USB_CONFIGFS_F_FS
>         implemented in kernel space (for instance Ethernet, serial or
>         mass storage) and other are implemented in user space.
>  
> +config USB_CONFIGFS_F_TRACE
> +     bool "Linux FTrace Export Over USB"
> +     depends on USB_CONFIGFS
> +     select USB_F_TRACE
> +     help
> +       The Linux FTrace Export Over USB lets one export ftrace buffer
> +       over a USB cable to a host computer for further processing.
> +
> +       If you want support for that, say Y or M here. Otherwise say N.
> +
> +       If unsure, say N.
> +
>  config USB_CONFIGFS_F_UAC1
>       bool "Audio Class 1.0"
>       depends on USB_CONFIGFS
> diff --git a/drivers/usb/gadget/function/Makefile 
> b/drivers/usb/gadget/function/Makefile
> index 5d3a6cf02218..eb851309006c 100644
> --- a/drivers/usb/gadget/function/Makefile
> +++ b/drivers/usb/gadget/function/Makefile
> @@ -50,3 +50,5 @@ usb_f_printer-y                     := f_printer.o
>  obj-$(CONFIG_USB_F_PRINTER)  += usb_f_printer.o
>  usb_f_tcm-y                  := f_tcm.o
>  obj-$(CONFIG_USB_F_TCM)              += usb_f_tcm.o
> +usb_f_trace-y                        := f-trace.o
> +obj-$(CONFIG_USB_F_TRACE)    += usb_f_trace.o
> diff --git a/drivers/usb/gadget/function/f-trace.c 
> b/drivers/usb/gadget/function/f-trace.c
> new file mode 100644
> index 000000000000..b5941df128a0
> --- /dev/null
> +++ b/drivers/usb/gadget/function/f-trace.c
> @@ -0,0 +1,401 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * f_trace.c -- USB FTrace Export
> + *
> + * Copyright (C) 2019 Intel Corporation
> + * Author: Felipe Balbi <felipe.ba...@linux.intel.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License v2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/kernel.h>
> +#include <linux/list.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +#include <linux/trace.h>
> +#include <linux/usb.h>
> +#include <linux/usb/composite.h>
> +#include <linux/usb/gadget.h>
> +#include <linux/workqueue.h>
> +
> +struct usb_ftrace {
> +     struct trace_export ftrace;
> +     struct usb_function function;
> +     struct work_struct queue_work;
> +     spinlock_t lock;
> +
> +     struct list_head list;
> +     struct list_head pending;
> +     struct list_head queued;
> +
> +     struct usb_ep *in;
> +
> +     u8 intf_id;
> +};
> +#define ftrace_to_trace(f)   (container_of((f), struct usb_ftrace, ftrace))
> +#define work_to_trace(w)     (container_of((w), struct usb_ftrace, 
> queue_work))
> +#define to_trace(f)          (container_of((f), struct usb_ftrace, function))
> +
> +#define FTRACE_REQUEST_QUEUE_LENGTH  250
> +
> +static inline struct usb_request *next_request(struct list_head *list)
> +{
> +     return list_first_entry_or_null(list, struct usb_request, list);
> +}
> +
> +struct usb_ftrace_opts {
> +     struct usb_function_instance func_inst;
> +};
> +#define to_opts(fi)  (container_of((fi), struct usb_ftrace_opts, func_inst))
> +
> +static struct usb_interface_descriptor ftrace_intf_desc = {
> +     .bLength                = USB_DT_INTERFACE_SIZE,
> +     .bDescriptorType        = USB_DT_INTERFACE,
> +
> +     .bAlternateSetting      = 0,
> +     .bNumEndpoints          = 1,
> +     .bInterfaceClass        = USB_CLASS_VENDOR_SPEC,
> +     .bInterfaceSubClass     = USB_SUBCLASS_VENDOR_SPEC,

We *may* be able to use the USB_DEBUG_CLASS here with a vendor protocol
which we define to be Linux Ftrace. If folks think it would be best,
then I can go look at the debug class and check whether it would be
feasible.

-- 
balbi

Attachment: signature.asc
Description: PGP signature

Reply via email to