2010-08-02 19:41:18

by Stefani Seibold

[permalink] [raw]
Subject: [PATCH] Change struct flchip_shared spinlock locking into mutex

From: Stefani Seibold <[email protected]>

This patch prevent to schedule while atomic by changing the
flchip_shared spinlock into a mutex. This should be save since no atomic
path will use this lock.

This patch is based on linux kernel 2.6.35. Please apply.

It was requested by Arnd Bergmann and Vasiliy Kulikov.

- Stefani

shared->

Signed-off-by: Stefani Seibold <[email protected]>
---
drivers/mtd/chips/cfi_cmdset_0001.c | 20 ++++++++++----------
include/linux/mtd/flashchip.h | 2 +-
2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 62f3ea9..3364061 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -717,7 +717,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
chip = &newcfi->chips[0];
for (i = 0; i < cfi->numchips; i++) {
shared[i].writing = shared[i].erasing = NULL;
- spin_lock_init(&shared[i].lock);
+ mutex_init(&shared[i].lock);
for (j = 0; j < numparts; j++) {
*chip = cfi->chips[i];
chip->start += j << partshift;
@@ -886,7 +886,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
*/
struct flchip_shared *shared = chip->priv;
struct flchip *contender;
- spin_lock(&shared->lock);
+ mutex_lock(&shared->lock);
contender = shared->writing;
if (contender && contender != chip) {
/*
@@ -899,7 +899,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
* get_chip returns success we're clear to go ahead.
*/
ret = mutex_trylock(&contender->mutex);
- spin_unlock(&shared->lock);
+ mutex_unlock(&shared->lock);
if (!ret)
goto retry;
mutex_unlock(&chip->mutex);
@@ -914,7 +914,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
mutex_unlock(&contender->mutex);
return ret;
}
- spin_lock(&shared->lock);
+ mutex_lock(&shared->lock);

/* We should not own chip if it is already
* in FL_SYNCING state. Put contender and retry. */
@@ -930,7 +930,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
* on this chip. Sleep. */
if (mode == FL_ERASING && shared->erasing
&& shared->erasing->oldstate == FL_ERASING) {
- spin_unlock(&shared->lock);
+ mutex_unlock(&shared->lock);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
mutex_unlock(&chip->mutex);
@@ -944,7 +944,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
shared->writing = chip;
if (mode == FL_ERASING)
shared->erasing = chip;
- spin_unlock(&shared->lock);
+ mutex_unlock(&shared->lock);
}
ret = chip_ready(map, chip, adr, mode);
if (ret == -EAGAIN)
@@ -959,7 +959,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad

if (chip->priv) {
struct flchip_shared *shared = chip->priv;
- spin_lock(&shared->lock);
+ mutex_lock(&shared->lock);
if (shared->writing == chip && chip->oldstate == FL_READY) {
/* We own the ability to write, but we're done */
shared->writing = shared->erasing;
@@ -967,7 +967,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
/* give back ownership to who we loaned it from */
struct flchip *loaner = shared->writing;
mutex_lock(&loaner->mutex);
- spin_unlock(&shared->lock);
+ mutex_unlock(&shared->lock);
mutex_unlock(&chip->mutex);
put_chip(map, loaner, loaner->start);
mutex_lock(&chip->mutex);
@@ -985,11 +985,11 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
* Don't let the switch below mess things up since
* we don't have ownership to resume anything.
*/
- spin_unlock(&shared->lock);
+ mutex_unlock(&shared->lock);
wake_up(&chip->wq);
return;
}
- spin_unlock(&shared->lock);
+ mutex_unlock(&shared->lock);
}

switch(chip->oldstate) {
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index f43e9b4..23cc10f 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -92,7 +92,7 @@ struct flchip {
/* This is used to handle contention on write/erase operations
between partitions of the same physical chip. */
struct flchip_shared {
- spinlock_t lock;
+ struct mutex lock;
struct flchip *writing;
struct flchip *erasing;
};
--
1.7.2


2010-08-03 08:25:59

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH] Change struct flchip_shared spinlock locking into mutex

On Monday 02 August 2010, [email protected] wrote:
> From: Stefani Seibold <[email protected]>
>
> This patch prevent to schedule while atomic by changing the
> flchip_shared spinlock into a mutex. This should be save since no atomic
> path will use this lock.

I don't know this code well, but the patch looks correct and seems
to be needed.

Acked-by: Arnd Bergmann <[email protected]>

2010-08-05 04:58:20

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH] Change struct flchip_shared spinlock locking into mutex

On Mon, 2010-08-02 at 21:40 +0200, [email protected] wrote:
> From: Stefani Seibold <[email protected]>
>
> This patch prevent to schedule while atomic by changing the
> flchip_shared spinlock into a mutex. This should be save since no atomic
> path will use this lock.
>
> This patch is based on linux kernel 2.6.35. Please apply.
>
> It was requested by Arnd Bergmann and Vasiliy Kulikov.

Taken to my l2-mtd-2.6.git / master

--
Best Regards,
Artem Bityutskiy (Артём Битюцкий)

2010-08-05 05:30:37

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH] Change struct flchip_shared spinlock locking into mutex

On Thu, 2010-08-05 at 07:58 +0300, Artem Bityutskiy wrote:
> On Mon, 2010-08-02 at 21:40 +0200, [email protected] wrote:
> > From: Stefani Seibold <[email protected]>
> >
> > This patch prevent to schedule while atomic by changing the
> > flchip_shared spinlock into a mutex. This should be save since no atomic
> > path will use this lock.
> >
> > This patch is based on linux kernel 2.6.35. Please apply.
> >
> > It was requested by Arnd Bergmann and Vasiliy Kulikov.
>
> Taken to my l2-mtd-2.6.git / master

This patch causes the following compilation error:

drivers/mtd/lpddr/lpddr_cmds.c: In function ‘lpddr_cmdset’:
drivers/mtd/lpddr/lpddr_cmds.c:101: warning: passing argument 1 of ‘spinlock_check’ from incompatible pointer type
include/linux/spinlock.h:271: note: expected ‘struct spinlock_t *’ but argument is of type ‘struct mutex *’
drivers/mtd/lpddr/lpddr_cmds.c:101: error: ‘struct mutex’ has no member named ‘rlock’
drivers/mtd/lpddr/lpddr_cmds.c: In function ‘get_chip’:
drivers/mtd/lpddr/lpddr_cmds.c:220: warning: passing argument 1 of ‘spin_lock’ from incompatible pointer type
include/linux/spinlock.h:282: note: expected ‘struct spinlock_t *’ but argument is of type ‘struct mutex *’
drivers/mtd/lpddr/lpddr_cmds.c:233: warning: passing argument 1 of ‘spin_unlock’ from incompatible pointer type
include/linux/spinlock.h:322: note: expected ‘struct spinlock_t *’ but argument is of type ‘struct mutex *’
drivers/mtd/lpddr/lpddr_cmds.c:248: warning: passing argument 1 of ‘spin_lock’ from incompatible pointer type
include/linux/spinlock.h:282: note: expected ‘struct spinlock_t *’ but argument is of type ‘struct mutex *’
drivers/mtd/lpddr/lpddr_cmds.c:264: warning: passing argument 1 of ‘spin_unlock’ from incompatible pointer type
include/linux/spinlock.h:322: note: expected ‘struct spinlock_t *’ but argument is of type ‘struct mutex *’
drivers/mtd/lpddr/lpddr_cmds.c:278: warning: passing argument 1 of ‘spin_unlock’ from incompatible pointer type
include/linux/spinlock.h:322: note: expected ‘struct spinlock_t *’ but argument is of type ‘struct mutex *’
drivers/mtd/lpddr/lpddr_cmds.c: In function ‘put_chip’:
drivers/mtd/lpddr/lpddr_cmds.c:351: warning: passing argument 1 of ‘spin_lock’ from incompatible pointer type
include/linux/spinlock.h:282: note: expected ‘struct spinlock_t *’ but argument is of type ‘struct mutex *’
drivers/mtd/lpddr/lpddr_cmds.c:359: warning: passing argument 1 of ‘spin_unlock’ from incompatible pointer type
include/linux/spinlock.h:322: note: expected ‘struct spinlock_t *’ but argument is of type ‘struct mutex *’
drivers/mtd/lpddr/lpddr_cmds.c:377: warning: passing argument 1 of ‘spin_unlock’ from incompatible pointer type
include/linux/spinlock.h:322: note: expected ‘struct spinlock_t *’ but argument is of type ‘struct mutex *’
drivers/mtd/lpddr/lpddr_cmds.c:381: warning: passing argument 1 of ‘spin_unlock’ from incompatible pointer type
include/linux/spinlock.h:322: note: expected ‘struct spinlock_t *’ but argument is of type ‘struct mutex *’

Removed from my tree.

--
Best Regards,
Artem Bityutskiy (Артём Битюцкий)