aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVasu Dev <vasu.dev@intel.com>2009-11-03 14:48:00 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:01:09 -0500
commitc46be11a683acc1ccf86883ea906f171b90ff29a (patch)
tree5c9766a2e6f1403acd3b8ceec281ef6803df418c /drivers
parenta7bbc7f40aa01eefef3d367349e1e6e87881a305 (diff)
[SCSI] libfc: reduce can_queue for all FCP frame allocation failures
Currently can_queue is reduced only if frame alloc fails during fc_fcp_send_data but frame alloc can fail at several other places in FCP data path and can_queue needs to be reduced for any FCP frame alloc failure. This patch adds fc_fcp_frame_alloc for all FCP frame allocations and if fc_frame_alloc fails in fc_fcp_frame_alloc then reduce can_queue in fc_fcp_frame_alloc, this will reduce can_queue for all FCP frame alloc failures. This required moving fc_fcp_reduce_can_queue up, to build without adding its prototype. Also renamed fc_fcp_reduce_can_queue to fc_fcp_can_queue_ramp_down. Removes fc_fcp_reduce_can_queue calling from fc_fcp_recv since not needed with added fc_fcp_frame_alloc reducing can_queue. Signed-off-by: Vasu Dev <vasu.dev@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/libfc/fc_fcp.c102
1 files changed, 59 insertions, 43 deletions
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 567eee7b8609..ac5c148d0182 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -327,6 +327,57 @@ static void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp)
327} 327}
328 328
329/** 329/**
330 * fc_fcp_can_queue_ramp_down() - reduces can_queue
331 * @lport: lport to reduce can_queue
332 *
333 * If we are getting memory allocation failures, then we may
334 * be trying to execute too many commands. We let the running
335 * commands complete or timeout, then try again with a reduced
336 * can_queue. Eventually we will hit the point where we run
337 * on all reserved structs.
338 */
339static void fc_fcp_can_queue_ramp_down(struct fc_lport *lport)
340{
341 struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
342 unsigned long flags;
343 int can_queue;
344
345 spin_lock_irqsave(lport->host->host_lock, flags);
346 if (si->throttled)
347 goto done;
348 si->throttled = 1;
349
350 can_queue = lport->host->can_queue;
351 can_queue >>= 1;
352 if (!can_queue)
353 can_queue = 1;
354 lport->host->can_queue = can_queue;
355 shost_printk(KERN_ERR, lport->host, "libfc: Could not allocate frame.\n"
356 "Reducing can_queue to %d.\n", can_queue);
357done:
358 spin_unlock_irqrestore(lport->host->host_lock, flags);
359}
360
361/*
362 * fc_fcp_frame_alloc() - Allocates fc_frame structure and buffer.
363 * @lport: fc lport struct
364 * @len: payload length
365 *
366 * Allocates fc_frame structure and buffer but if fails to allocate
367 * then reduce can_queue.
368 */
369static inline struct fc_frame *fc_fcp_frame_alloc(struct fc_lport *lport,
370 size_t len)
371{
372 struct fc_frame *fp;
373
374 fp = fc_frame_alloc(lport, len);
375 if (!fp)
376 fc_fcp_can_queue_ramp_down(lport);
377 return fp;
378}
379
380/**
330 * fc_fcp_recv_data() - Handler for receiving SCSI-FCP data from a target 381 * fc_fcp_recv_data() - Handler for receiving SCSI-FCP data from a target
331 * @fsp: The FCP packet the data is on 382 * @fsp: The FCP packet the data is on
332 * @fp: The data frame 383 * @fp: The data frame
@@ -616,38 +667,6 @@ static void fc_fcp_abts_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
616} 667}
617 668
618/** 669/**
619 * fc_fcp_reduce_can_queue() - Reduce the can_queue value for a local port
620 * @lport: The local port to reduce can_queue on
621 *
622 * If we are getting memory allocation failures, then we may
623 * be trying to execute too many commands. We let the running
624 * commands complete or timeout, then try again with a reduced
625 * can_queue. Eventually we will hit the point where we run
626 * on all reserved structs.
627 */
628static void fc_fcp_reduce_can_queue(struct fc_lport *lport)
629{
630 struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
631 unsigned long flags;
632 int can_queue;
633
634 spin_lock_irqsave(lport->host->host_lock, flags);
635 if (si->throttled)
636 goto done;
637 si->throttled = 1;
638
639 can_queue = lport->host->can_queue;
640 can_queue >>= 1;
641 if (!can_queue)
642 can_queue = 1;
643 lport->host->can_queue = can_queue;
644 shost_printk(KERN_ERR, lport->host, "libfc: Could not allocate frame.\n"
645 "Reducing can_queue to %d.\n", can_queue);
646done:
647 spin_unlock_irqrestore(lport->host->host_lock, flags);
648}
649
650/**
651 * fc_fcp_recv() - Reveive an FCP frame 670 * fc_fcp_recv() - Reveive an FCP frame
652 * @seq: The sequence the frame is on 671 * @seq: The sequence the frame is on
653 * @fp: The received frame 672 * @fp: The received frame
@@ -665,8 +684,10 @@ static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg)
665 u8 r_ctl; 684 u8 r_ctl;
666 int rc = 0; 685 int rc = 0;
667 686
668 if (IS_ERR(fp)) 687 if (IS_ERR(fp)) {
669 goto errout; 688 fc_fcp_error(fsp, fp);
689 return;
690 }
670 691
671 fh = fc_frame_header_get(fp); 692 fh = fc_frame_header_get(fp);
672 r_ctl = fh->fh_r_ctl; 693 r_ctl = fh->fh_r_ctl;
@@ -720,11 +741,6 @@ unlock:
720 fc_fcp_unlock_pkt(fsp); 741 fc_fcp_unlock_pkt(fsp);
721out: 742out:
722 fc_frame_free(fp); 743 fc_frame_free(fp);
723errout:
724 if (IS_ERR(fp))
725 fc_fcp_error(fsp, fp);
726 else if (rc == -ENOMEM)
727 fc_fcp_reduce_can_queue(lport);
728} 744}
729 745
730/** 746/**
@@ -886,7 +902,7 @@ static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp)
886 struct fc_seq *csp; 902 struct fc_seq *csp;
887 903
888 csp = lport->tt.seq_start_next(seq); 904 csp = lport->tt.seq_start_next(seq);
889 conf_frame = fc_frame_alloc(fsp->lp, 0); 905 conf_frame = fc_fcp_frame_alloc(fsp->lp, 0);
890 if (conf_frame) { 906 if (conf_frame) {
891 f_ctl = FC_FC_SEQ_INIT; 907 f_ctl = FC_FC_SEQ_INIT;
892 f_ctl |= FC_FC_LAST_SEQ | FC_FC_END_SEQ; 908 f_ctl |= FC_FC_LAST_SEQ | FC_FC_END_SEQ;
@@ -1026,7 +1042,7 @@ static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
1026 if (fc_fcp_lock_pkt(fsp)) 1042 if (fc_fcp_lock_pkt(fsp))
1027 return 0; 1043 return 0;
1028 1044
1029 fp = fc_frame_alloc(lport, sizeof(fsp->cdb_cmd)); 1045 fp = fc_fcp_frame_alloc(lport, sizeof(fsp->cdb_cmd));
1030 if (!fp) { 1046 if (!fp) {
1031 rc = -1; 1047 rc = -1;
1032 goto unlock; 1048 goto unlock;
@@ -1306,7 +1322,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
1306 fc_fcp_complete_locked(fsp); 1322 fc_fcp_complete_locked(fsp);
1307 return; 1323 return;
1308 } 1324 }
1309 fp = fc_frame_alloc(lport, sizeof(struct fc_els_rec)); 1325 fp = fc_fcp_frame_alloc(lport, sizeof(struct fc_els_rec));
1310 if (!fp) 1326 if (!fp)
1311 goto retry; 1327 goto retry;
1312 1328
@@ -1557,7 +1573,7 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
1557 if (!(rpriv->flags & FC_RP_FLAGS_RETRY) || 1573 if (!(rpriv->flags & FC_RP_FLAGS_RETRY) ||
1558 rpriv->rp_state != RPORT_ST_READY) 1574 rpriv->rp_state != RPORT_ST_READY)
1559 goto retry; /* shouldn't happen */ 1575 goto retry; /* shouldn't happen */
1560 fp = fc_frame_alloc(lport, sizeof(*srr)); 1576 fp = fc_fcp_frame_alloc(lport, sizeof(*srr));
1561 if (!fp) 1577 if (!fp)
1562 goto retry; 1578 goto retry;
1563 1579