aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/phy.c
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2007-09-29 01:42:12 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:53:54 -0400
commit9ff8c68b3c722f732c7a13d6631b149cca8c7091 (patch)
treeec0dd0762f9652d30fff30228406bcd0417f6063 /drivers/net/phy/phy.c
parent1f8f4559f8c5829348a010a9e0bbb423310060d1 (diff)
PHYLIB: Spinlock fixes for softirqs
Use spin_lock_bh()/spin_unlock_bh() for the phydev lock throughout as it is used in phy_timer() that is called as a softirq and all the other operations may happen in the user context. There has been a change recently that did such a conversion for some of the operations on the lock, but some have been left intact. Many of them, perhaps all, may be called in the user context and I was able to trigger recursive spinlock acquisition indeed, so I think for the sake of long-term maintenance it is best to convert them all, even if unnecessarily for one or two -- better safe than sorry. Perhaps one in phy_timer() could actually be skipped as only called as a softirq -- I can send an update if that sounds like a good idea. Checked with checkpatch.pl and at the runtime. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/phy/phy.c')
-rw-r--r--drivers/net/phy/phy.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 17c1e1555d80..4da993dfcfd8 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -424,7 +424,7 @@ int phy_start_aneg(struct phy_device *phydev)
424{ 424{
425 int err; 425 int err;
426 426
427 spin_lock(&phydev->lock); 427 spin_lock_bh(&phydev->lock);
428 428
429 if (AUTONEG_DISABLE == phydev->autoneg) 429 if (AUTONEG_DISABLE == phydev->autoneg)
430 phy_sanitize_settings(phydev); 430 phy_sanitize_settings(phydev);
@@ -445,7 +445,7 @@ int phy_start_aneg(struct phy_device *phydev)
445 } 445 }
446 446
447out_unlock: 447out_unlock:
448 spin_unlock(&phydev->lock); 448 spin_unlock_bh(&phydev->lock);
449 return err; 449 return err;
450} 450}
451EXPORT_SYMBOL(phy_start_aneg); 451EXPORT_SYMBOL(phy_start_aneg);
@@ -490,10 +490,10 @@ void phy_stop_machine(struct phy_device *phydev)
490{ 490{
491 del_timer_sync(&phydev->phy_timer); 491 del_timer_sync(&phydev->phy_timer);
492 492
493 spin_lock(&phydev->lock); 493 spin_lock_bh(&phydev->lock);
494 if (phydev->state > PHY_UP) 494 if (phydev->state > PHY_UP)
495 phydev->state = PHY_UP; 495 phydev->state = PHY_UP;
496 spin_unlock(&phydev->lock); 496 spin_unlock_bh(&phydev->lock);
497 497
498 phydev->adjust_state = NULL; 498 phydev->adjust_state = NULL;
499} 499}
@@ -537,9 +537,9 @@ static void phy_force_reduction(struct phy_device *phydev)
537 */ 537 */
538void phy_error(struct phy_device *phydev) 538void phy_error(struct phy_device *phydev)
539{ 539{
540 spin_lock(&phydev->lock); 540 spin_lock_bh(&phydev->lock);
541 phydev->state = PHY_HALTED; 541 phydev->state = PHY_HALTED;
542 spin_unlock(&phydev->lock); 542 spin_unlock_bh(&phydev->lock);
543} 543}
544 544
545/** 545/**
@@ -690,10 +690,10 @@ static void phy_change(struct work_struct *work)
690 if (err) 690 if (err)
691 goto phy_err; 691 goto phy_err;
692 692
693 spin_lock(&phydev->lock); 693 spin_lock_bh(&phydev->lock);
694 if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state)) 694 if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
695 phydev->state = PHY_CHANGELINK; 695 phydev->state = PHY_CHANGELINK;
696 spin_unlock(&phydev->lock); 696 spin_unlock_bh(&phydev->lock);
697 697
698 enable_irq(phydev->irq); 698 enable_irq(phydev->irq);
699 699
@@ -718,7 +718,7 @@ phy_err:
718 */ 718 */
719void phy_stop(struct phy_device *phydev) 719void phy_stop(struct phy_device *phydev)
720{ 720{
721 spin_lock(&phydev->lock); 721 spin_lock_bh(&phydev->lock);
722 722
723 if (PHY_HALTED == phydev->state) 723 if (PHY_HALTED == phydev->state)
724 goto out_unlock; 724 goto out_unlock;
@@ -734,7 +734,7 @@ void phy_stop(struct phy_device *phydev)
734 } 734 }
735 735
736out_unlock: 736out_unlock:
737 spin_unlock(&phydev->lock); 737 spin_unlock_bh(&phydev->lock);
738 738
739 /* 739 /*
740 * Cannot call flush_scheduled_work() here as desired because 740 * Cannot call flush_scheduled_work() here as desired because
@@ -782,7 +782,7 @@ static void phy_timer(unsigned long data)
782 int needs_aneg = 0; 782 int needs_aneg = 0;
783 int err = 0; 783 int err = 0;
784 784
785 spin_lock(&phydev->lock); 785 spin_lock_bh(&phydev->lock);
786 786
787 if (phydev->adjust_state) 787 if (phydev->adjust_state)
788 phydev->adjust_state(phydev->attached_dev); 788 phydev->adjust_state(phydev->attached_dev);
@@ -948,7 +948,7 @@ static void phy_timer(unsigned long data)
948 break; 948 break;
949 } 949 }
950 950
951 spin_unlock(&phydev->lock); 951 spin_unlock_bh(&phydev->lock);
952 952
953 if (needs_aneg) 953 if (needs_aneg)
954 err = phy_start_aneg(phydev); 954 err = phy_start_aneg(phydev);