Make all it87 drivers SMP safe
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
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
@@ -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
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.candit87_wdt.cwatchdog drivers. This also greatly simplifies the implementation ofit87_wdt.cdriver.Signed-off-by Nat Gurumoorthy<[email protected]>---
drivers/watchdog/it8712f_wdt.c +0
-1@@ -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
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_regioncan still fail if some other driver has done a none muxedrequest_regionon 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
Re: [lm-sensors] [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers
Quoted 22 lines · Natarajan Gurumoorthy
Hans,
Comments belowQuoted 5 lines · Hans de Goede
You shouldn't (void) this, there is a reason you get a warning otherwise!
request_muxed_regioncan still fail if some other driver has done a none muxedrequest_regionon 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
0x2eand0x2f. When they are done they write a different sequence to these 2 locations. The entry routine issuperio_enterand exit issuperio_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 callssuperio_exitwhich 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.cfunction "__request_region". "request_muxed_region" turns onIORESOURCE_MUXEDbit 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
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/watchdogf71808e_wdt.cit8712f_wdt.cit87_wdt.csch311x_wdt.ciTCO_vendor_support.cibmasr.cw83697hf_wdt.cw83697ug_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 belowQuoted 5 lines · Hans de Goede
You shouldn't (void) this, there is a reason you get a warning otherwise!
request_muxed_regioncan still fail if some other driver has done a none muxedrequest_regionon 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
0x2eand0x2f. When they are done they write a different sequence to these 2 locations. The entry routine issuperio_enterand exit issuperio_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 callssuperio_exitwhich 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.cfunction "__request_region". "request_muxed_region" turns onIORESOURCE_MUXEDbit 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
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 thoughdrivers/hwmon
anddrivers/watchdogI 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/watchdogf71808e_wdt.cit8712f_wdt.cit87_wdt.csch311x_wdt.ciTCO_vendor_support.cibmasr.cw83697hf_wdt.cw83697ug_wdt.c:
drivers/hwmon
dme1737.c:1935:static inline voiddme1737_sio_enter(int sio_cip)f71805f.c:100:superio_enter(int base) f71882fg.c:196:static inline intsuperio_enter(int base); it87.c:112:superio_enter(void)
pc87360.c:1009: /* Nosuperio_enter*/
sch5627.c:118:static inline intsuperio_enter(int base)smsc47b397.c:75:static inline voidsuperio_enter(void)smsc47m1.c:77:superio_enter(void)
vt1211.c:223:static inline voidsuperio_enter(int sio_cip)w83627ehf.c:135:superio_enter(int ioreg) w83627hf.c:134:superio_enter(structw83627hf_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
Re: [lm-sensors] [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers
In reply to Natarajan GurumoorthyQuoted 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
Re: [lm-sensors] [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers
In reply to Hans de GoedeQuoted 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.candit87_wdt.cwatchdog drivers. This also greatly simplifies the implementation ofit87_wdt.cdriver.Signed-off-by Nat Gurumoorthy<[email protected]>---
drivers/watchdog/it8712f_wdt.c +0
-1@@ -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
-1static 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_regioncan still fail if some other driver has done a none muxedrequest_regionon 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
Re: [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers
In reply to Nat GurumoorthyHi 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
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
Re: [PATCH v5 1/2] Use "request_muxed_region" in it87 watchdog drivers
In reply to Wim Van SebroeckReview
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
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
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 therequest_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 howrequest_regionis 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
PATCH v5 2/2 Use "request_muxed_region" in it87 hwmon drivers
In reply to Nat Gurumoorthy02 - 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
@@ -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