Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[PATCH] dpt_i2o fix for deadlock condition

Miquel van Smoorenburg <miquels@cistron.nl> forwarded me this fix to
resolve a deadlock condition that occurs due to the API change in
2.6.13+ kernels dropping the host locking when entering the error
handling. They all end up calling adpt_i2o_post_wait(), which if you
call it unlocked, might return with host_lock locked anyway and that
causes a deadlock.

Signed-off-by: Mark Salyzyn <aacraid@adaptec.com>
Cc: James Bottomley <James.Bottomley@steeleye.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Salyzyn, Mark and committed by
Linus Torvalds
e5508c13 87d47d05

+20 -5
+20 -5
drivers/scsi/dpt_i2o.c
··· 660 660 msg[2] = 0; 661 661 msg[3]= 0; 662 662 msg[4] = (u32)cmd; 663 - if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){ 663 + if (pHba->host) 664 + spin_lock_irq(pHba->host->host_lock); 665 + rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER); 666 + if (pHba->host) 667 + spin_unlock_irq(pHba->host->host_lock); 668 + if (rcode != 0) { 664 669 if(rcode == -EOPNOTSUPP ){ 665 670 printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name); 666 671 return FAILED; ··· 702 697 msg[2] = 0; 703 698 msg[3] = 0; 704 699 700 + if (pHba->host) 701 + spin_lock_irq(pHba->host->host_lock); 705 702 old_state = d->state; 706 703 d->state |= DPTI_DEV_RESET; 707 - if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){ 708 - d->state = old_state; 704 + rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER); 705 + d->state = old_state; 706 + if (pHba->host) 707 + spin_unlock_irq(pHba->host->host_lock); 708 + if (rcode != 0) { 709 709 if(rcode == -EOPNOTSUPP ){ 710 710 printk(KERN_INFO"%s: Device reset not supported\n",pHba->name); 711 711 return FAILED; ··· 718 708 printk(KERN_INFO"%s: Device reset failed\n",pHba->name); 719 709 return FAILED; 720 710 } else { 721 - d->state = old_state; 722 711 printk(KERN_INFO"%s: Device reset successful\n",pHba->name); 723 712 return SUCCESS; 724 713 } ··· 730 721 { 731 722 adpt_hba* pHba; 732 723 u32 msg[4]; 724 + u32 rcode; 733 725 734 726 pHba = (adpt_hba*)cmd->device->host->hostdata[0]; 735 727 memset(msg, 0, sizeof(msg)); ··· 739 729 msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid); 740 730 msg[2] = 0; 741 731 msg[3] = 0; 742 - if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){ 732 + if (pHba->host) 733 + spin_lock_irq(pHba->host->host_lock); 734 + rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER); 735 + if (pHba->host) 736 + spin_unlock_irq(pHba->host->host_lock); 737 + if (rcode != 0) { 743 738 printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name); 744 739 return FAILED; 745 740 } else {