Skip to contentSkip to conversation

Make all it87 drivers SMP safe

PATCH Superseded Nat Gurumoorthy 7 participants 15 messages Apr 12, 2011 – Apr 14, 2011

Subsystems (3)

v5 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v5 cover Make all it87 drivers SMP safe

There are 3 different drivers that touch the it87 hardware registers. The 3 drivers have been written independently and access the it87 hardware registers assuming they are the only driver accessing it. This change attempts to serialize access to the hardware by using "request_muxed_region" macro defined by Alan Cox. Call to this macro will hold off the requestor if the resource is currently busy. The use of the above macro makes it possible to get rid of spinlocks in it8712f_wdt.c and it87_wdt.c watchdog drivers. This also greatly simplifies the implementation of it87_wdt.c driver.

01 - Changes to it87 watchdog driver to use "request_muxed_region"
drivers/watchdog/it8712f_wdt.c drivers/watchdog/it87_wdt.c

02 - Chages to hwmon it87 driver to use "request_muxed_region"
drivers/hwmon/it87.c

 drivers/hwmon/it87.c           |    6 +++++
 drivers/watchdog/it8712f_wdt.c |   11 +++++----
 drivers/watchdog/it87_wdt.c    |   41 +++++----------------------------------
 3 files changed, 18 insertions(+), 40 deletions(-)

Patch History:
v5:
- Remove unnecessary while from superio_enter.

v4:
- Remove extra braces in superio_enter routines.

v3:
- Totally abandon the spinlock based approach and use "request_muxed_region" to hold off requestors if the resource is busy.

v2:
- More verbose patch headers. Add In-Reply-To: field.

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

#1 lore raw

PATCH v5 1/2 Use "request_muxed_region" in it87 watchdog drivers

01 - Changes to it87 watchdog driver to use "request_muxed_region" Serialize access to the hardware by using "request_muxed_region" macro defined by Alan Cox. Call to this macro will hold off the requestor if the resource is currently busy.

The use of the above macro makes it possible to get rid of spinlocks in it8712f_wdt.c and it87_wdt.c watchdog drivers. This also greatly simplifies the implementation of it87_wdt.c driver.

---

drivers/watchdog/it8712f_wdt.c +6 -5
index 6143f52..51bfbc0 100644
@@ -51,7 +51,6 @@ MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
 
 static unsigned long wdt_open;
 static unsigned expect_close;
-static spinlock_t io_lock;
 static unsigned char revision;
 
 /* Dog Food address - We use the game port address */
@@ -123,7 +122,11 @@ static inline void superio_select(int ldn)
 
 static inline void superio_enter(void)
 {
-	spin_lock(&io_lock);
+	/*
+	 * Reserve REG and REG + 1 for exclusive access.
+	 */
+	(void) request_muxed_region(REG, 2, NAME);
+
 	outb(0x87, REG);
 	outb(0x01, REG);
 	outb(0x55, REG);
@@ -134,7 +137,7 @@ static inline void superio_exit(void)
 {
 	outb(0x02, REG);
 	outb(0x02, VAL);
-	spin_unlock(&io_lock);
+	release_region(REG, 2);
 }
 
 static inline void it8712f_wdt_ping(void)
@@ -382,8 +385,6 @@ static int __init it8712f_wdt_init(void)
 {
 	int err = 0;
 
-	spin_lock_init(&io_lock);
-
 	if (it8712f_wdt_find(&address))
 		return -ENODEV;
 
drivers/watchdog/it87_wdt.c +6 -35

185 lines not on this page · raw message

Signature · 7 lines
1.7.3.1


_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#2 lore raw

Re: [lm-sensors] [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

Hi,

Quoted 25 lines · Nat Gurumoorthy

01 - Changes to it87 watchdog driver to use "request_muxed_region" Serialize access to the hardware by using "request_muxed_region" macro defined by Alan Cox. Call to this macro will hold off the requestor if the resource is currently busy.

The use of the above macro makes it possible to get rid of spinlocks in it8712f_wdt.c and it87_wdt.c watchdog drivers. This also greatly simplifies the implementation of it87_wdt.c driver.

---

drivers/watchdog/it8712f_wdt.c +0 -1
index 6143f52..51bfbc0 100644
@@ -51,7 +51,6 @@ MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
 
  static unsigned long wdt_open;
  static unsigned expect_close;
-static spinlock_t io_lock;
  static unsigned char revision;
 
  /* Dog Food address - We use the game port address */

drivers/watchdog/it8712f_wdt.c static inline void superio_select(int ldn) · line 129

Quoted 9 lines
drivers/watchdog/it8712f_wdt.c +5 -1
@@ -123,7 +122,11 @@ static inline void superio_select(int ldn)
 
  static inline void superio_enter(void)
  {
-	spin_lock(&io_lock);
+	/*
+	 * Reserve REG and REG + 1 for exclusive access.
+	 */
+	(void) request_muxed_region(REG, 2, NAME);
+

You shouldn't (void) this, there is a reason you get a warning otherwise! request_muxed_region can still fail if some other driver has done a none muxed request_region on the same region, and in that case you should not continue with accessing the io-ports.

Regards,

Hans

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

#3 lore raw

Re: [lm-sensors] [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

Hans,
Comments below

Quoted 5 lines · Hans de Goede

You shouldn't (void) this, there is a reason you get a warning otherwise! request_muxed_region can still fail if some other driver has done a none muxed request_region on the same region, and in that case you should not continue with accessing the io-ports.

There are 3 it87 drivers and they all have to do the exact same sequence to put the chip into a mode where they can modify its state. The sequences involve non atomic sequences that write locations 0x2e and 0x2f. When they are done they write a different sequence to these 2 locations. The entry routine is superio_enter and exit is superio_exit. All the it87 drivers reserve these 2 locations before they start manipulating the chip. This macro will hold off requestors if the resource is busy because one of the other drivers is manipulating the chip. Once the an it87 driver is done it calls superio_exit which will release the reservation on those 2 locations letting any other driver on the wait queue to now gain access two locations.

Please read code in kernel/resource.c function "__request_region". "request_muxed_region" turns on IORESOURCE_MUXED bit and that means that only way an it87 driver will get back from a call to "request_muxed_region" is when it gets hold of the region.

The scenario you mention above can never happen.

Regards
Nat

Quoted 5 lines

Regards,

Hans

Signature · 7 lines
Regards
Nat Gurumoorthy AB6SJ

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#4 lore raw

Re: [lm-sensors] [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

Quoted 22 lines · Natarajan Gurumoorthy

Hans,
Comments below

Quoted 5 lines · Hans de Goede

You shouldn't (void) this, there is a reason you get a warning otherwise! request_muxed_region can still fail if some other driver has done a none muxed request_region on the same region, and in that case you should not continue with accessing the io-ports.

There are 3 it87 drivers and they all have to do the exact same sequence to put the chip into a mode where they can modify its state. The sequences involve non atomic sequences that write locations 0x2e and 0x2f. When they are done they write a different sequence to these 2 locations. The entry routine is superio_enter and exit is superio_exit. All the it87 drivers reserve these 2 locations before they start manipulating the chip. This macro will hold off requestors if the resource is busy because one of the other drivers is manipulating the chip. Once the an it87 driver is done it calls superio_exit which will release the reservation on those 2 locations letting any other driver on the wait queue to now gain access two locations.

Quoted 6 lines

Please read code in kernel/resource.c function "__request_region". "request_muxed_region" turns on IORESOURCE_MUXED bit and that means that only way an it87 driver will get back from a call to "request_muxed_region" is when it gets hold of the region.

The scenario you mention above can never happen.

Let me be straight clear, as apparently you have difficulties understanding Hans's simple request:

You do not get to (void) the return of request_muxed_region(), period. This is _not_ negotiable.

What other it87 drivers currently in the tree do or don't do is totally irrelevant. There can be new it87 drivers added later, there can be out-of-tree it87 drivers (including old copies of in-tree ones), and there can be non-it87 drivers accessing the I/O ports (or at least attempting to.) So the scenario mentioned by Hans can very well happen, and you have to deal with it.

Thanks,

Signature · 6 lines
Jean Delvare

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#5 lore raw

Re: [lm-sensors] [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

John,
Unfortunately you are right. After grepping though drivers/hwmon
and drivers/watchdog I realize the ugliness is fairly deep rooted. All of the following drivers need to be cleaned up as far as the "superio_enter" "superio_exit" operation is concerned if we want this stuff to be SMP clean and allow multiple drivers to coexist.

drivers/watchdog
f71808e_wdt.c
it8712f_wdt.c
it87_wdt.c
sch311x_wdt.c
iTCO_vendor_support.c
ibmasr.c
w83697hf_wdt.c
w83697ug_wdt.c:

drivers/hwmon
dme1737.c:1935:static inline void dme1737_sio_enter(int sio_cip) f71805f.c:100:superio_enter(int base) f71882fg.c:196:static inline int superio_enter(int base); it87.c:112:superio_enter(void)
pc87360.c:1009: /* No superio_enter */
sch5627.c:118:static inline int superio_enter(int base) smsc47b397.c:75:static inline void superio_enter(void) smsc47m1.c:77:superio_enter(void)
vt1211.c:223:static inline void superio_enter(int sio_cip) w83627ehf.c:135:superio_enter(int ioreg) w83627hf.c:134:superio_enter(struct w83627hf_sio_data *sio)

Have I missed any other drivers that also need to be cleaned. Even if I got my boss to sign up to clean this I can only test the it8712f drivers and thats it.

Regards
Nat

Quoted 47 lines · Jean Delvare
Quoted 22 lines · Natarajan Gurumoorthy

Hans,
      Comments below

Quoted 5 lines · Hans de Goede

You shouldn't (void) this, there is a reason you get a warning otherwise! request_muxed_region can still fail if some other driver has done a none muxed request_region on the same region, and in that case you should not continue with accessing the io-ports.

There are 3 it87 drivers and they all have to do the exact same sequence to put the chip into a mode where they can modify its state. The sequences involve non atomic sequences that write locations 0x2e and 0x2f. When they are done they write a different sequence to these 2 locations. The entry routine is superio_enter and exit is superio_exit. All the it87 drivers reserve these 2 locations before they start manipulating the chip. This macro will hold off requestors if the resource is busy because one of the other drivers is manipulating the chip. Once the  an it87 driver is done it calls superio_exit which will release the reservation on those 2 locations letting any other driver on the wait queue to now gain access two locations.

Quoted 6 lines

Please read code in kernel/resource.c function "__request_region". "request_muxed_region" turns on IORESOURCE_MUXED bit and that means that only  way an it87 driver will get back from a call to "request_muxed_region" is when it gets hold of the region.

The scenario you mention above can never happen.

Let me be straight clear, as apparently you have difficulties understanding Hans's simple request:

You do not get to (void) the return of request_muxed_region(), period. This is _not_ negotiable.

What other it87 drivers currently in the tree do or don't do is totally irrelevant. There can be new it87 drivers added later, there can be out-of-tree it87 drivers (including old copies of in-tree ones), and there can be non-it87 drivers accessing the I/O ports (or at least attempting to.) So the scenario mentioned by Hans can very well happen, and you have to deal with it.

Thanks,
--
Jean Delvare

Signature · 7 lines
Regards
Nat Gurumoorthy AB6SJ

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#6 lore raw

Re: [lm-sensors] [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

Hi Nat,

Please don't top-post.

Quoted 31 lines · Natarajan Gurumoorthy

John,
Unfortunately you are right. After grepping though drivers/hwmon
and drivers/watchdog I realize the ugliness is fairly deep rooted. All of the following drivers need to be cleaned up as far as the "superio_enter" "superio_exit" operation is concerned if we want this stuff to be SMP clean and allow multiple drivers to coexist.

drivers/watchdog
f71808e_wdt.c
it8712f_wdt.c
it87_wdt.c
sch311x_wdt.c
iTCO_vendor_support.c
ibmasr.c
w83697hf_wdt.c
w83697ug_wdt.c:

drivers/hwmon
dme1737.c:1935:static inline void dme1737_sio_enter(int sio_cip) f71805f.c:100:superio_enter(int base) f71882fg.c:196:static inline int superio_enter(int base); it87.c:112:superio_enter(void)
pc87360.c:1009: /* No superio_enter */
sch5627.c:118:static inline int superio_enter(int base) smsc47b397.c:75:static inline void superio_enter(void) smsc47m1.c:77:superio_enter(void)
vt1211.c:223:static inline void superio_enter(int sio_cip) w83627ehf.c:135:superio_enter(int ioreg) w83627hf.c:134:superio_enter(struct w83627hf_sio_data *sio)

Quoted 1 line

Have I missed any other drivers that also need to be cleaned.

f71882fg and sch5627 already call request_muxed_region() so I think these are safe. OTOH you missed pc87427 at least. And there are probably a few non-watchdog, non-hwmon drivers which need the same fix (for example drivers/parport/parport_pc.c and drivers/net/irda/via-ircc.h are suspect.)

Quoted 3 lines

Even if
I got my boss to sign up to clean this I can only test the it8712f drivers and thats it.

For one thing, you don't have to. Converting just a subset is already a welcomed step in the right direction. But anyway the changes should be fairly easy and not too risky so I wouldn't mind you doing them without testing them all. And we can find testers for most hwmon drivers, I'm sure (I can personally test f71805f and w83627ehf, maybe w83627hf).

Signature · 6 lines
Jean Delvare

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#7 lore raw

Re: [lm-sensors] [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

In reply to Natarajan Gurumoorthy
Quoted 3 lines

Have I missed any other drivers that also need to be cleaned. Even if I got my boss to sign up to clean this I can only test the it8712f drivers and thats it.

I would just fix the it87 drivers. The rest is the problem of the authors/users of the other drivers. Really only they can test it and you've given them a worked reference !

Alan

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

#8 lore raw

Re: [lm-sensors] [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

In reply to Hans de Goede
Quoted 29 lines · Hans de Goede

Hi,

Quoted 26 lines · Nat Gurumoorthy

01 - Changes to it87 watchdog driver to use "request_muxed_region" Serialize access to the hardware by using "request_muxed_region" macro defined by Alan Cox. Call to this macro will hold off the requestor if the resource is currently busy.

The use of the above macro makes it possible to get rid of spinlocks in it8712f_wdt.c and it87_wdt.c watchdog drivers. This also greatly simplifies the implementation of it87_wdt.c driver.

---

drivers/watchdog/it8712f_wdt.c +0 -1
index 6143f52..51bfbc0 100644
@@ -51,7 +51,6 @@ MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
 
  static unsigned long wdt_open;
  static unsigned expect_close;
-static spinlock_t io_lock;
  static unsigned char revision;
 
  /* Dog Food address - We use the game port address */
@@ -123,7 +122,11 @@ static inline void superio_select(int ldn)
 
Quoted 14 lines

drivers/watchdog/it8712f_wdt.c static inline void superio_select(int ldn) · line 129

Quoted 8 lines
drivers/watchdog/it8712f_wdt.c +5 -1
  static inline void superio_enter(void)
  {
-	spin_lock(&io_lock);
+	/*
+	 * Reserve REG and REG + 1 for exclusive access.
+	 */
+	(void) request_muxed_region(REG, 2, NAME);
+

You shouldn't (void) this, there is a reason you get a warning otherwise! request_muxed_region can still fail if some other driver has done a none muxed request_region on the same region, and in that case you should not continue with accessing the io-ports.

Absolutely agree - even if that means adding a return code to superio_enter() and checking it from the calling code.

Guenter

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

#9 lore raw

Re: [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

In reply to Nat Gurumoorthy

Hi Nat,

drivers/watchdog/it8712f_wdt.c static inline void superio_select(int ldn) · line 128

Quoted 1 line
drivers/watchdog/it8712f_wdt.c +1 -0
+	(void) request_muxed_region(REG, 2, NAME);

Why do we need to typecast this? Can't we just use
+ request_muxed_region(REG, 2, NAME);

Kind regards,
Wim.

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

#10 lore raw

Re: [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

Wim,
Old habits die hard. I will get rid of it and ship out a new patch.

Regards
Nat

Quoted 12 lines · Wim Van Sebroeck

Hi Nat,

Quoted 1 line

+     (void) request_muxed_region(REG, 2, NAME);

Why do we need to typecast this? Can't we just use
+       request_muxed_region(REG, 2, NAME);

Kind regards,
Wim.

Signature · 7 lines
Regards
Nat Gurumoorthy AB6SJ

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#11 lore raw

Re: [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

In reply to Wim Van Sebroeck

Review

Quoted 6 lines · On Wed, 13 Apr 2011 09:03:00 +0200 Wim Van Sebroeck <[email protected]> wrote:

Hi Nat,

drivers/watchdog/it8712f_wdt.c static inline void superio_select(int ldn) · line 128

Quoted 1 line
drivers/watchdog/it8712f_wdt.c +1 -0
+	(void) request_muxed_region(REG, 2, NAME);

Why do we need to typecast this? Can't we just use

(quoted diff) +1 -0
+	request_muxed_region(REG, 2, NAME);

We really ought to use

	if ()

in theory the request can fail if someone has hogged the resource and not muxed it. I'm not clear what the right thing to do in that case is - given it should never happen I guess log an error and bail out but that's a rather bigger change and perhaps should be a follow up patch ?

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

#12 lore raw

Re: [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

Quoted 10 lines · Alan Cox
Quoted 6 lines · On Wed, 13 Apr 2011 09:03:00 +0200 Wim Van Sebroeck <[email protected]> wrote:

Hi Nat,

Quoted 1 line

+   (void) request_muxed_region(REG, 2, NAME);

Why do we need to typecast this? Can't we just use
+     request_muxed_region(REG, 2, NAME);

Quoted 9 lines

We really ought to use

       if ()

in theory the request can fail if someone has hogged the resource and not muxed it. I'm not clear what the right thing to do in that case is - given it should never happen I guess log an error and bail out but that's a rather bigger change and perhaps should be a follow up patch ?

request_muxed_region() is sorta gross: it's essentially acting like a lock, meant to be used for short periods of time, but it can fail if someone else decides it should.

Would it make more sense to have drivers that need to use the current request_muxed_region() be able to force a region into a mux-only state at driver init? That would lead to much less contorted code to handle the off-chance that the request_muxed_region() fails.

Ie:

Driver init:

if (!request_muxed_region(base, size, DRV_NAME))
goto cleanup_driver_init_failed;

Driver cleanup

release_muxed_region(base, size); /* returns void */

And then within drivers:

use_muxed_region(base, size); /* sleeps until region is usable -- returns void */
/* Do stuff */
unuse_muxed_region(base, size); /* returns void */

I realize the above example re-uses the 'request_muxed_region()' name, but at least this would be much more consistent with how request_region is used in other drivers.

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

#13 lore raw

Re: [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers

Quoted 3 lines

request_muxed_region() is sorta gross: it's essentially acting like a lock, meant to be used for short periods of time, but it can fail if someone else decides it should.

Which is exactly how the hardware situation works. If some other driver comes along and is rude then the only safe thing to do is to moan a bit.

Quoted 4 lines

Would it make more sense to have drivers that need to use the current request_muxed_region() be able to force a region into a mux-only state at driver init? That would lead to much less contorted code to handle the off-chance that the request_muxed_region() fails.

Send patches

Quoted 3 lines

I realize the above example re-uses the 'request_muxed_region()' name, but at least this would be much more consistent with how request_region is used in other drivers.

I guess you'd need some kind of

r = add_muxed_resource()
removed_muxed_resource(r)

that inserted/removed them from the resource tree ?

I think the basic resource tree code could be extended this way IFF someone does the work, if not the current code actually should work just fine.

Alan

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

#14 lore raw

PATCH v5 2/2 Use "request_muxed_region" in it87 hwmon drivers

In reply to Nat Gurumoorthy

02 - Chages to hwmon it87 driver to use "request_muxed_region" Serialize access to the hardware by using "request_muxed_region" macro defined by Alan Cox. Call to this macro will hold off the requestor if the resource is currently busy.

---

drivers/hwmon/it87.c +6 -0
index 316b648..3945569 100644
@@ -111,6 +111,11 @@ superio_select(int ldn)
 static inline void
 superio_enter(void)
 {
+	/*
+	 * Reserve REG and REG + 1 for exclusive access.
+	 */
+	(void) request_muxed_region(REG, 2, DRVNAME);
+
 	outb(0x87, REG);
 	outb(0x01, REG);
 	outb(0x55, REG);
@@ -122,6 +127,7 @@ superio_exit(void)
 {
 	outb(0x02, REG);
 	outb(0x02, VAL);
+	release_region(REG, 2);
 }
 
 /* Logical device 4 registers */
Signature · 7 lines
1.7.3.1


_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors