diff mbox series

[RFC,2/3] usb, kcov: collect coverage from hub_event

Message ID 1b30d1c9e7f86c25425c5ee53d7facede289608e.1571333592.git.andreyknvl@google.com (mailing list archive)
State Superseded
Headers show
Series kcov: collect coverage from usb and vhost | expand

Commit Message

Andrey Konovalov Oct. 17, 2019, 5:44 p.m. UTC
This patch adds kcov_remote_start/kcov_remote_stop annotations to the
hub_event function, which is responsible for processing events on USB
buses, in particular events that happen during USB device enumeration.
Each USB bus gets a unique id, which can be used to attach a kcov device
to a particular USB bus for coverage collection.

Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
---
 drivers/usb/core/hub.c    | 4 ++++
 include/linux/kcov.h      | 1 +
 include/uapi/linux/kcov.h | 7 +++++++
 3 files changed, 12 insertions(+)

Comments

Greg Kroah-Hartman Oct. 17, 2019, 6:19 p.m. UTC | #1
On Thu, Oct 17, 2019 at 07:44:14PM +0200, Andrey Konovalov wrote:
> This patch adds kcov_remote_start/kcov_remote_stop annotations to the
> hub_event function, which is responsible for processing events on USB
> buses, in particular events that happen during USB device enumeration.
> Each USB bus gets a unique id, which can be used to attach a kcov device
> to a particular USB bus for coverage collection.
> 
> Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
> ---
>  drivers/usb/core/hub.c    | 4 ++++
>  include/linux/kcov.h      | 1 +
>  include/uapi/linux/kcov.h | 7 +++++++
>  3 files changed, 12 insertions(+)
> 
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index 236313f41f4a..03a40e41b099 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -5374,6 +5374,8 @@ static void hub_event(struct work_struct *work)
>  	hub_dev = hub->intfdev;
>  	intf = to_usb_interface(hub_dev);
>  
> +	kcov_remote_start(kcov_remote_handle_usb(hdev->bus->busnum));
> +
>  	dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
>  			hdev->state, hdev->maxchild,
>  			/* NOTE: expects max 15 ports... */
> @@ -5480,6 +5482,8 @@ static void hub_event(struct work_struct *work)
>  	/* Balance the stuff in kick_hub_wq() and allow autosuspend */
>  	usb_autopm_put_interface(intf);
>  	kref_put(&hub->kref, hub_release);
> +
> +	kcov_remote_stop();
>  }
>  
>  static const struct usb_device_id hub_id_table[] = {
> diff --git a/include/linux/kcov.h b/include/linux/kcov.h
> index 702672d98d35..38a47e0b67c2 100644
> --- a/include/linux/kcov.h
> +++ b/include/linux/kcov.h
> @@ -30,6 +30,7 @@ void kcov_task_exit(struct task_struct *t);
>  /*
>   * Reserved handle ranges:
>   * 0000000000000000 - 0000ffffffffffff : common handles
> + * 0001000000000000 - 0001ffffffffffff : USB subsystem handles

So how many bits are you going to have for any in-kernel tasks?  Aren't
you going to run out quickly?


>   */
>  void kcov_remote_start(u64 handle);
>  void kcov_remote_stop(void);
> diff --git a/include/uapi/linux/kcov.h b/include/uapi/linux/kcov.h
> index 46f78f716ca9..45c9ae59cebc 100644
> --- a/include/uapi/linux/kcov.h
> +++ b/include/uapi/linux/kcov.h
> @@ -43,4 +43,11 @@ enum {
>  #define KCOV_CMP_SIZE(n)        ((n) << 1)
>  #define KCOV_CMP_MASK           KCOV_CMP_SIZE(3)
>  
> +#define KCOV_REMOTE_HANDLE_USB  0x0001000000000000ull
> +
> +static inline __u64 kcov_remote_handle_usb(unsigned int bus)
> +{
> +	return KCOV_REMOTE_HANDLE_USB + (__u64)bus;
> +}

Why is this function in a uapi .h file?  What userspace code would call
this?

thanks,

greg k-h
Andrey Konovalov Oct. 17, 2019, 7:06 p.m. UTC | #2
On Thu, Oct 17, 2019 at 8:19 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Thu, Oct 17, 2019 at 07:44:14PM +0200, Andrey Konovalov wrote:
> > This patch adds kcov_remote_start/kcov_remote_stop annotations to the
> > hub_event function, which is responsible for processing events on USB
> > buses, in particular events that happen during USB device enumeration.
> > Each USB bus gets a unique id, which can be used to attach a kcov device
> > to a particular USB bus for coverage collection.
> >
> > Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
> > ---
> >  drivers/usb/core/hub.c    | 4 ++++
> >  include/linux/kcov.h      | 1 +
> >  include/uapi/linux/kcov.h | 7 +++++++
> >  3 files changed, 12 insertions(+)
> >
> > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> > index 236313f41f4a..03a40e41b099 100644
> > --- a/drivers/usb/core/hub.c
> > +++ b/drivers/usb/core/hub.c
> > @@ -5374,6 +5374,8 @@ static void hub_event(struct work_struct *work)
> >       hub_dev = hub->intfdev;
> >       intf = to_usb_interface(hub_dev);
> >
> > +     kcov_remote_start(kcov_remote_handle_usb(hdev->bus->busnum));
> > +
> >       dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
> >                       hdev->state, hdev->maxchild,
> >                       /* NOTE: expects max 15 ports... */
> > @@ -5480,6 +5482,8 @@ static void hub_event(struct work_struct *work)
> >       /* Balance the stuff in kick_hub_wq() and allow autosuspend */
> >       usb_autopm_put_interface(intf);
> >       kref_put(&hub->kref, hub_release);
> > +
> > +     kcov_remote_stop();
> >  }
> >
> >  static const struct usb_device_id hub_id_table[] = {
> > diff --git a/include/linux/kcov.h b/include/linux/kcov.h
> > index 702672d98d35..38a47e0b67c2 100644
> > --- a/include/linux/kcov.h
> > +++ b/include/linux/kcov.h
> > @@ -30,6 +30,7 @@ void kcov_task_exit(struct task_struct *t);
> >  /*
> >   * Reserved handle ranges:
> >   * 0000000000000000 - 0000ffffffffffff : common handles
> > + * 0001000000000000 - 0001ffffffffffff : USB subsystem handles
>
> So how many bits are you going to have for any in-kernel tasks?  Aren't
> you going to run out quickly?

With these patches we only collect coverage from hub_event threads,
and we need one ID per USB bus, the number of which is quite limited.
But then we might want to collect coverage from other parts of the USB
subsystem, so we might need more IDs. I don't expect the number of
different subsystem from which we want to collect coverage to be
large, so the idea here is to use 2 bytes of an ID to denote the
subsystem, and the other 6 to denote different coverage collection
sections within it.

But overall, which encoding scheme to use here is a good question.
Ideas are welcome.

> >   */
> >  void kcov_remote_start(u64 handle);
> >  void kcov_remote_stop(void);
> > diff --git a/include/uapi/linux/kcov.h b/include/uapi/linux/kcov.h
> > index 46f78f716ca9..45c9ae59cebc 100644
> > --- a/include/uapi/linux/kcov.h
> > +++ b/include/uapi/linux/kcov.h
> > @@ -43,4 +43,11 @@ enum {
> >  #define KCOV_CMP_SIZE(n)        ((n) << 1)
> >  #define KCOV_CMP_MASK           KCOV_CMP_SIZE(3)
> >
> > +#define KCOV_REMOTE_HANDLE_USB  0x0001000000000000ull
> > +
> > +static inline __u64 kcov_remote_handle_usb(unsigned int bus)
> > +{
> > +     return KCOV_REMOTE_HANDLE_USB + (__u64)bus;
> > +}
>
> Why is this function in a uapi .h file?  What userspace code would call
> this?

A userspace process that wants to collect coverage from USB bus # N
needs to pass kcov_remote_handle_usb(N) into KCOV_REMOTE_ENABLE ioctl.
Greg Kroah-Hartman Oct. 17, 2019, 8:29 p.m. UTC | #3
On Thu, Oct 17, 2019 at 09:06:56PM +0200, Andrey Konovalov wrote:
> On Thu, Oct 17, 2019 at 8:19 PM Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >
> > On Thu, Oct 17, 2019 at 07:44:14PM +0200, Andrey Konovalov wrote:
> > > This patch adds kcov_remote_start/kcov_remote_stop annotations to the
> > > hub_event function, which is responsible for processing events on USB
> > > buses, in particular events that happen during USB device enumeration.
> > > Each USB bus gets a unique id, which can be used to attach a kcov device
> > > to a particular USB bus for coverage collection.
> > >
> > > Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
> > > ---
> > >  drivers/usb/core/hub.c    | 4 ++++
> > >  include/linux/kcov.h      | 1 +
> > >  include/uapi/linux/kcov.h | 7 +++++++
> > >  3 files changed, 12 insertions(+)
> > >
> > > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> > > index 236313f41f4a..03a40e41b099 100644
> > > --- a/drivers/usb/core/hub.c
> > > +++ b/drivers/usb/core/hub.c
> > > @@ -5374,6 +5374,8 @@ static void hub_event(struct work_struct *work)
> > >       hub_dev = hub->intfdev;
> > >       intf = to_usb_interface(hub_dev);
> > >
> > > +     kcov_remote_start(kcov_remote_handle_usb(hdev->bus->busnum));
> > > +
> > >       dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
> > >                       hdev->state, hdev->maxchild,
> > >                       /* NOTE: expects max 15 ports... */
> > > @@ -5480,6 +5482,8 @@ static void hub_event(struct work_struct *work)
> > >       /* Balance the stuff in kick_hub_wq() and allow autosuspend */
> > >       usb_autopm_put_interface(intf);
> > >       kref_put(&hub->kref, hub_release);
> > > +
> > > +     kcov_remote_stop();
> > >  }
> > >
> > >  static const struct usb_device_id hub_id_table[] = {
> > > diff --git a/include/linux/kcov.h b/include/linux/kcov.h
> > > index 702672d98d35..38a47e0b67c2 100644
> > > --- a/include/linux/kcov.h
> > > +++ b/include/linux/kcov.h
> > > @@ -30,6 +30,7 @@ void kcov_task_exit(struct task_struct *t);
> > >  /*
> > >   * Reserved handle ranges:
> > >   * 0000000000000000 - 0000ffffffffffff : common handles
> > > + * 0001000000000000 - 0001ffffffffffff : USB subsystem handles
> >
> > So how many bits are you going to have for any in-kernel tasks?  Aren't
> > you going to run out quickly?
> 
> With these patches we only collect coverage from hub_event threads,
> and we need one ID per USB bus, the number of which is quite limited.
> But then we might want to collect coverage from other parts of the USB
> subsystem, so we might need more IDs. I don't expect the number of
> different subsystem from which we want to collect coverage to be
> large, so the idea here is to use 2 bytes of an ID to denote the
> subsystem, and the other 6 to denote different coverage collection
> sections within it.
> 
> But overall, which encoding scheme to use here is a good question.
> Ideas are welcome.
> 
> > >   */
> > >  void kcov_remote_start(u64 handle);
> > >  void kcov_remote_stop(void);
> > > diff --git a/include/uapi/linux/kcov.h b/include/uapi/linux/kcov.h
> > > index 46f78f716ca9..45c9ae59cebc 100644
> > > --- a/include/uapi/linux/kcov.h
> > > +++ b/include/uapi/linux/kcov.h
> > > @@ -43,4 +43,11 @@ enum {
> > >  #define KCOV_CMP_SIZE(n)        ((n) << 1)
> > >  #define KCOV_CMP_MASK           KCOV_CMP_SIZE(3)
> > >
> > > +#define KCOV_REMOTE_HANDLE_USB  0x0001000000000000ull
> > > +
> > > +static inline __u64 kcov_remote_handle_usb(unsigned int bus)
> > > +{
> > > +     return KCOV_REMOTE_HANDLE_USB + (__u64)bus;
> > > +}
> >
> > Why is this function in a uapi .h file?  What userspace code would call
> > this?
> 
> A userspace process that wants to collect coverage from USB bus # N
> needs to pass kcov_remote_handle_usb(N) into KCOV_REMOTE_ENABLE ioctl.

Ugh, ok.  Then you should make "unsigned int bus" a __u64 so that this
actually will work on all kernels properly.

thanks,

greg k-h
diff mbox series

Patch

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 236313f41f4a..03a40e41b099 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -5374,6 +5374,8 @@  static void hub_event(struct work_struct *work)
 	hub_dev = hub->intfdev;
 	intf = to_usb_interface(hub_dev);
 
+	kcov_remote_start(kcov_remote_handle_usb(hdev->bus->busnum));
+
 	dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
 			hdev->state, hdev->maxchild,
 			/* NOTE: expects max 15 ports... */
@@ -5480,6 +5482,8 @@  static void hub_event(struct work_struct *work)
 	/* Balance the stuff in kick_hub_wq() and allow autosuspend */
 	usb_autopm_put_interface(intf);
 	kref_put(&hub->kref, hub_release);
+
+	kcov_remote_stop();
 }
 
 static const struct usb_device_id hub_id_table[] = {
diff --git a/include/linux/kcov.h b/include/linux/kcov.h
index 702672d98d35..38a47e0b67c2 100644
--- a/include/linux/kcov.h
+++ b/include/linux/kcov.h
@@ -30,6 +30,7 @@  void kcov_task_exit(struct task_struct *t);
 /*
  * Reserved handle ranges:
  * 0000000000000000 - 0000ffffffffffff : common handles
+ * 0001000000000000 - 0001ffffffffffff : USB subsystem handles
  */
 void kcov_remote_start(u64 handle);
 void kcov_remote_stop(void);
diff --git a/include/uapi/linux/kcov.h b/include/uapi/linux/kcov.h
index 46f78f716ca9..45c9ae59cebc 100644
--- a/include/uapi/linux/kcov.h
+++ b/include/uapi/linux/kcov.h
@@ -43,4 +43,11 @@  enum {
 #define KCOV_CMP_SIZE(n)        ((n) << 1)
 #define KCOV_CMP_MASK           KCOV_CMP_SIZE(3)
 
+#define KCOV_REMOTE_HANDLE_USB  0x0001000000000000ull
+
+static inline __u64 kcov_remote_handle_usb(unsigned int bus)
+{
+	return KCOV_REMOTE_HANDLE_USB + (__u64)bus;
+}
+
 #endif /* _LINUX_KCOV_IOCTLS_H */