linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Achatz <erazor_de@users.sourceforge.net>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Jiri Kosina <jkosina@suse.cz>,
	Jussi Kivilinna <jussi.kivilinna@mbnet.fi>,
	wylda@volny.cz, Pavel Machek <pavel@suse.cz>,
	Alessandro Guido <ag@alessandroguido.name>,
	Tomas Hanak <tomas.hanak@gmail.com>,
	Jason Noble <nobleja@polezero.com>,
	simon.windows@gmail.com,
	Sean Hildebrand <silverwraithii@gmail.com>,
	Sid Boyce <sboyce@blueyonder.co.uk>,
	Henning Glawe <glaweh@debian.org>,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 4/4] Added locks for sysfs attributes and internal data.
Date: Sat, 13 Mar 2010 12:19:27 +0100	[thread overview]
Message-ID: <201003131219.27482.erazor_de@users.sourceforge.net> (raw)
In-Reply-To: <20100309074155.GA17288@core.coreip.homeip.net>

Hello,
I have some more questions regarding the work on my driver:

1. binary vs text sysfs attributes
As I found little information about binary sysfs attributes I used the normal 
sysfs attributes to transfer binary data because they are also easier to use. 
The transfered data is far less than the 4096 bytes minimum page size.
So, is there a significant difference in these two variants that should force 
me to use the binary variant?

2. memory footprint
I'm thinking about a redesign of my sysfs attributes to reduce io and simplify 
the use of binary sysfs attributes (if needed, see above). This would 
increase the memory footprint of hid_drvdata to around 5kbytes.
Is it allowed for a driver to constantly alloc such an amount of data or 
should I stick with more complicated code and more io?

3. grow up of driver
I see my work is not quite ready for kernel inclusion. Maybe I'm wrong in this 
list and should bug other people. Would the linuxdriverproject.org be a 
better place to raise my work to adulthood?

Thanks in advance
Stefan Achatz

> Hi Stefan,
>
> On Mon, Mar 08, 2010 at 05:04:29PM +0100, Stefan Achatz wrote:
> > From 47678162da8e374d6f132db21d89b718ee5cfbd1 Mon Sep 17 00:00:00 2001
> > From: Stefan Achatz <erazor_de@users.sourceforge.net>
> > Date: Mon, 8 Mar 2010 16:54:19 +0100
> > Subject: [PATCH 4/4] Added locks for sysfs attributes and internal data.
> >
> > Added mutex lock to prevent different processes from accessing
> > sysfs attributes at the same time.
> > Added spin lock for internal data.
> > ---
> >  drivers/hid/hid-roccat-kone.c |  246
> > ++++++++++++++++++++++++++++------------ drivers/hid/hid-roccat-kone.h | 
> >   9 +-
> >  2 files changed, 179 insertions(+), 76 deletions(-)
> >
> > diff --git a/drivers/hid/hid-roccat-kone.c
> > b/drivers/hid/hid-roccat-kone.c index 941f5b3..eded7d4 100644
> > --- a/drivers/hid/hid-roccat-kone.c
> > +++ b/drivers/hid/hid-roccat-kone.c
> > @@ -223,11 +223,6 @@ static int kone_get_profile(struct usb_device
> > *usb_dev, if (number < 1 || number > 5)
> >  		return -EINVAL;
> >
> > -	/*
> > -	 * The manufacturer uses a control message of type class with interface
> > -	 * as recipient and provides the profile number as index parameter.
> > -	 * This is prevented in userspace by function check_ctrlrecip.
> > -	 */
> >  	len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
> >  			USB_REQ_CLEAR_FEATURE, USB_TYPE_CLASS
> >
> >  					| USB_RECIP_INTERFACE | USB_DIR_IN,
> >
> > @@ -398,16 +393,18 @@ static int kone_get_firmware_version(struct
> > usb_device *usb_dev, int *result) static ssize_t
> > kone_sysfs_set_settings(struct device *dev,
> >  		struct device_attribute *attr, char const *buf, size_t size)
> >  {
> > -	struct hid_device *hdev = dev_get_drvdata(dev);
> > -	struct kone_device *kone = hid_get_drvdata(hdev);
> > -	struct usb_interface *intf = to_usb_interface(dev);
> > -	struct usb_device *usb_dev = interface_to_usbdev(intf);
> > +	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
> > +	struct usb_device *usb_dev =
> > interface_to_usbdev(to_usb_interface(dev)); int err;
> > +	unsigned long flags;
> >
> >  	if (size != sizeof(struct kone_settings))
> >  		return -EINVAL;
> >
> > +	mutex_lock(&kone->kone_lock);
> >  	err = kone_set_settings(usb_dev, (struct kone_settings const *)buf);
>
> Hmm, this kind of casting tells me that this is binary, not text data
> and thus binary sysfs attribute shoudl be used.
>
> > +	mutex_unlock(&kone->kone_lock);
> > +
> >  	if (err)
> >  		return err;
> >
> > @@ -415,9 +412,10 @@ static ssize_t kone_sysfs_set_settings(struct device
> > *dev, * If we get here, treat buf as okay (apart from checksum) and use
> > value * of startup_profile as its at hand
> >  	 */
> > +	spin_lock_irqsave(&kone->actual_lock, flags);
> >  	kone->act_profile = ((struct kone_settings *)buf)->startup_profile;
> > -	kone->act_profile_valid = 1;
> > -	kone->act_dpi_valid = 0;
> > +	kone->act_dpi = -1;
> > +	spin_unlock_irqrestore(&kone->actual_lock, flags);
>
> You don't really need a spinlock to set one integer.
>
> >  	return sizeof(struct kone_settings);
> >  }
> > @@ -425,10 +423,14 @@ static ssize_t kone_sysfs_set_settings(struct
> > device *dev, static ssize_t kone_sysfs_show_settings(struct device *dev,
> >  		struct device_attribute *attr, char *buf)
> >  {
> > -	struct usb_interface *intf = to_usb_interface(dev);
> > -	struct usb_device *usb_dev = interface_to_usbdev(intf);
> > +	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
> > +	struct usb_device *usb_dev =
> > interface_to_usbdev(to_usb_interface(dev)); int err;
> > +
> > +	mutex_lock(&kone->kone_lock);
> >  	err = kone_get_settings(usb_dev, (struct kone_settings *)buf);
> > +	mutex_unlock(&kone->kone_lock);
> > +
> >  	if (err)
> >  		return err;
> >
> > @@ -437,10 +439,14 @@ static ssize_t kone_sysfs_show_settings(struct
> > device *dev,
> >
> >  static ssize_t kone_sysfs_get_profile(struct device *dev, char *buf, int
> > number) {
> > -	struct usb_interface *intf = to_usb_interface(dev);
> > -	struct usb_device *usb_dev = interface_to_usbdev(intf);
> > +	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
> > +	struct usb_device *usb_dev =
> > interface_to_usbdev(to_usb_interface(dev)); int err;
> > +
> > +	mutex_lock(&kone->kone_lock);
> >  	err = kone_get_profile(usb_dev, (struct kone_profile *)buf, number);
> > +	mutex_unlock(&kone->kone_lock);
> > +
> >  	if (err)
> >  		return err;
> >  	return sizeof(struct kone_profile);
> > @@ -449,15 +455,17 @@ static ssize_t kone_sysfs_get_profile(struct device
> > *dev, char *buf, int number) static ssize_t kone_sysfs_set_profile(struct
> > device *dev, char const *buf, size_t size, int number)
> >  {
> > -	struct usb_interface *intf = to_usb_interface(dev);
> > -	struct usb_device *usb_dev = interface_to_usbdev(intf);
> > -
> > +	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
> > +	struct usb_device *usb_dev =
> > interface_to_usbdev(to_usb_interface(dev)); int err;
> >
> >  	if (size != sizeof(struct kone_profile))
> >  		return -EINVAL;
> >
> > +	mutex_lock(&kone->kone_lock);
> >  	err = kone_set_profile(usb_dev, buf, number);
> > +	mutex_unlock(&kone->kone_lock);
> > +
> >  	if (err)
> >  		return err;
> >
> > @@ -525,32 +533,68 @@ static ssize_t kone_sysfs_set_profile_5(struct
> > device *dev, }
> >
> >  /*
> > - * Helper to fill kone_device structure with actual values
> > - * On success returns 0
> > - * On failure returns errno
> > + * Fills act_profile in kone_device.
> > + * Also writes result in @result.
> > + * Once act_profile is valid, its not getting invalid any more.
> > + * Returns on success 0, on failure errno
> >   */
> > -static int kone_device_set_actual_values(struct kone_device *kone,
> > -		struct device *dev, int both)
> > +static int kone_device_set_actual_profile(struct kone_device *kone,
> > +		struct device *dev, int *result)
> >  {
> > -	struct usb_interface *intf = to_usb_interface(dev);
> > -	struct usb_device *usb_dev = interface_to_usbdev(intf);
> > -	int err;
> > +	struct usb_device *usb_dev =
> > interface_to_usbdev(to_usb_interface(dev)); +	int err, temp;
> > +	unsigned long flags;
> >
> > -	/* first make sure profile is valid */
> > -	if (!kone->act_profile_valid) {
> > -		err = kone_get_startup_profile(usb_dev, &kone->act_profile);
> > +	spin_lock_irqsave(&kone->actual_lock, flags);
> > +	if (kone->act_profile == -1) {
> > +		spin_unlock_irqrestore(&kone->actual_lock, flags);
> > +		err = kone_get_startup_profile(usb_dev, &temp);
> >  		if (err)
> >  			return err;
> > -		kone->act_profile_valid = 1;
> > +		spin_lock_irq(&kone->actual_lock);
> > +		kone->act_profile = temp;
> > +		spin_unlock_irqrestore(&kone->actual_lock, flags);
>
> You shoudl not be mixing _irq/_irqrestore. Also it is probably not
> needed at all. If it is needed then the common style to acquire and
> release locks only once in a function - this makes checking whether
> lock/unlock is balanced easier.
>
> > +		if (result)
> > +			*result = temp;
> > +	} else {
> > +		if (result)
> > +			*result = kone->act_profile;
> > +		spin_unlock_irqrestore(&kone->actual_lock, flags);
> >  	}
> > +	return 0;
> > +}
> > +
> > +/*
> > + * Fills act_dpi in kone_device.
> > + * Also writes result in @result.
> > + * On success returns 0
> > + * On failure returns errno
> > + */
> > +static int kone_device_set_actual_dpi(struct kone_device *kone,
> > +		struct device *dev, int *result)
> > +{
> > +	struct usb_device *usb_dev =
> > interface_to_usbdev(to_usb_interface(dev)); +	int err, temp;
> > +	unsigned long flags;
> > +
> > +	kone_device_set_actual_profile(kone, dev, NULL);
> >
> > -	/* then get startup dpi value */
> > -	if (!kone->act_dpi_valid && both) {
> > +	spin_lock_irqsave(&kone->actual_lock, flags);
> > +	if (kone->act_dpi == -1) {
> > +		spin_unlock_irqrestore(&kone->actual_lock, flags);
>
> So what are we protecting exactly? What if act_dpi will become -1 here
> (after you released the spinlock?
>
> >  		err = kone_get_profile_startup_dpi(usb_dev, kone->act_profile,
> > -				&kone->act_dpi);
> > +				&temp);
>
> Stopped looking - locking obviously is bogus and needs to be redone. You
> need to decide what exactly needs protection and what critical sections
> are.

  reply	other threads:[~2010-03-13 11:19 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-20  8:11 [PATCH] HID: add driver for Roccat Kone gaming mouse Stefan Achatz
2010-02-21  8:13 ` Dmitry Torokhov
     [not found]   ` <201002211750.45618.erazor_de@users.sourceforge.net>
2010-02-22  6:29     ` [PATCH 2/2] HID: documentation additions and elimination of legacy filenames for Roccat Kone driver Dmitry Torokhov
2010-02-22 10:01       ` Jiri Kosina
2010-02-22 18:42         ` [PATCH 3/3] Adding documentation to sysfs attributes of roccat kone driver Stefan Achatz
2010-02-22 23:10           ` Dmitry Torokhov
2010-02-23  8:03           ` Stefan Achatz
2010-02-26  7:44             ` Dmitry Torokhov
2010-03-08 16:04               ` [PATCH 4/4] Added locks for sysfs attributes and internal data Stefan Achatz
2010-03-09  0:05                 ` Jiri Kosina
2010-03-09  7:41                 ` Dmitry Torokhov
2010-03-13 11:19                   ` Stefan Achatz [this message]
2010-03-14  8:42                     ` Dmitry Torokhov
2010-03-15 13:51                       ` Jiri Kosina

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=201003131219.27482.erazor_de@users.sourceforge.net \
    --to=erazor_de@users.sourceforge.net \
    --cc=ag@alessandroguido.name \
    --cc=dmitry.torokhov@gmail.com \
    --cc=glaweh@debian.org \
    --cc=jkosina@suse.cz \
    --cc=jussi.kivilinna@mbnet.fi \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nobleja@polezero.com \
    --cc=pavel@suse.cz \
    --cc=sboyce@blueyonder.co.uk \
    --cc=silverwraithii@gmail.com \
    --cc=simon.windows@gmail.com \
    --cc=tomas.hanak@gmail.com \
    --cc=wylda@volny.cz \
    /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).