Hi Anssi, On Sun, Jun 15, 2008 at 10:01:55PM +0300, Anssi Hannula wrote: > Hi all! > > It seems a new spinlock input_dev->event_lock has been added [1] to the > input subsystem since the force feedback support was reworked. > > However, the force feedback subsystem sleeps on events in multiple > places, e.g. ff-core.c uses a mutex, and hid-pidff driver waits for hid > io (otherwise commands were lost, IIRC; if necessary I'll test again). > > ff_device->mutex is used to shield effects[], so it is locked when > handling EV_FF events, on flushes, and on effect upload and erase ioctls. > > Maybe we should make EV_FF handling atomic? For effect uploading we > could either make it completely atomic, or lock only for reserving the > effect slot, then release the lock, and mark it as ready after upload is > complete. > Making even the upload completely atomic would mean that no force > feedback events/ioctl() would sleep, which AFAIK would be a plus for > userspace ff applications. On the other hand, hid-pidff (device managed > mode) driver doesn't know whether effect upload was successful until it > has received a report from the device, so it wouldn't be able to report > failure immediately. Other drivers would, though. > > What do you think? > I think something the patch below is what is needed. EV_FF handling is already atomic because of event_lock (and it is here to stay), but uploading does not need to be atomic, only installing into effect table needs the lock. Any change you could test the patch? I dont have any FF devices. Thanks! -- Dmitry Signed-off-by: Dmitry Torokhov <dtor@xxxxxxx> --- drivers/input/ff-core.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) Index: linux/drivers/input/ff-core.c =================================================================== --- linux.orig/drivers/input/ff-core.c +++ linux/drivers/input/ff-core.c @@ -166,8 +166,10 @@ int input_ff_upload(struct input_dev *de if (ret) goto out; + spin_lock_irq(&dev->event_lock); ff->effects[id] = *effect; ff->effect_owners[id] = file; + spin_unlock_irq(&dev->event_lock); out: mutex_unlock(&ff->mutex); @@ -189,16 +191,22 @@ static int erase_effect(struct input_dev if (error) return error; + spin_lock_irq(&dev->event_lock); ff->playback(dev, effect_id, 0); + ff->effect_owners[effect_id] = NULL; + spin_unlock_irq(&dev->event_lock); if (ff->erase) { error = ff->erase(dev, effect_id); - if (error) + if (error) { + spin_lock_irq(&dev->event_lock); + ff->effect_owners[effect_id] = file; + spin_unlock_irq(&dev->event_lock); + return error; + } } - ff->effect_owners[effect_id] = NULL; - return 0; } @@ -263,8 +271,6 @@ int input_ff_event(struct input_dev *dev if (type != EV_FF) return 0; - mutex_lock(&ff->mutex); - switch (code) { case FF_GAIN: if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffff) @@ -286,7 +292,6 @@ int input_ff_event(struct input_dev *dev break; } - mutex_unlock(&ff->mutex); return 0; } EXPORT_SYMBOL_GPL(input_ff_event); -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html