| From stefanr@s5r6.in-berlin.de Tue Nov 4 13:57:36 2008 |
| From: Stefan Richter <stefanr@s5r6.in-berlin.de> |
| Date: Mon, 27 Oct 2008 23:29:00 +0100 (CET) |
| Subject: firewire: fw-sbp2: delay first login to avoid retries |
| To: stable@kernel.org |
| Cc: linux1394-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org |
| Message-ID: <tkrat.9bc21c3b6a97bebe@s5r6.in-berlin.de> |
| Content-Disposition: INLINE |
| |
| From: Stefan Richter <stefanr@s5r6.in-berlin.de> |
| |
| commit 0dcfeb7e3c8695c5aa3677dda8efb9bef2e7e64d upstream |
| |
| This optimizes firewire-sbp2's device probe for the case that the local |
| node and the SBP-2 node were discovered at the same time. In this case, |
| fw-core's bus management work and fw-sbp2's login and SCSI probe work |
| are scheduled in parallel (in the globally shared workqueue and in |
| fw-sbp2's workqueue, respectively). The bus reset from fw-core may then |
| disturb and extremely delay the login and SCSI probe because the latter |
| fails with several command timeouts and retries and has to be retried |
| from scratch. |
| |
| We avoid this particular situation of sbp2_login() and fw_card_bm_work() |
| running in parallel by delaying the first sbp2_login() a little bit. |
| |
| This is meant to be a short-term fix for |
| https://bugzilla.redhat.com/show_bug.cgi?id=466679. In the long run, |
| the SCSI probe, i.e. fw-sbp2's call of __scsi_add_device(), should be |
| parallelized with sbp2_reconnect(). |
| |
| Problem reported and fix tested and confirmed by Alex Kanavin. |
| |
| Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/firewire/fw-sbp2.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/drivers/firewire/fw-sbp2.c |
| +++ b/drivers/firewire/fw-sbp2.c |
| @@ -1158,7 +1158,7 @@ static int sbp2_probe(struct device *dev |
| |
| /* Do the login in a workqueue so we can easily reschedule retries. */ |
| list_for_each_entry(lu, &tgt->lu_list, link) |
| - sbp2_queue_work(lu, 0); |
| + sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); |
| return 0; |
| |
| fail_tgt_put: |