]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/meta-ti-glsdk.git/blob - recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.2/0037-SCSI-mpt2sas-Fix-for-memory-allocation-error-for-lar.patch
linux-ti33x-psp 3.2: update to 3.2.5
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-ti33x-psp-3.2 / 3.2.2 / 0037-SCSI-mpt2sas-Fix-for-memory-allocation-error-for-lar.patch
1 From fe5907648567469336c06cf215932adac76a8e11 Mon Sep 17 00:00:00 2001
2 From: "nagalakshmi.nandigama@lsi.com" <nagalakshmi.nandigama@lsi.com>
3 Date: Thu, 1 Dec 2011 07:53:08 +0530
4 Subject: [PATCH 037/130] SCSI: mpt2sas : Fix for memory allocation error for
5  large host credits
7 commit aff132d95ffe14eca96cab90597cdd010b457af7 upstream.
9 The amount of memory required for tracking chain buffers is rather
10 large, and when the host credit count is big, memory allocation
11 failure occurs inside __get_free_pages.
13 The fix is to limit the number of chains to 100,000.  In addition,
14 the number of host credits is limited to 30,000 IOs. However this
15 limitation can be overridden this using the command line option
16 max_queue_depth.  The algorithm for calculating the
17 reply_post_queue_depth is changed so that it is equal to
18 (reply_free_queue_depth + 16), previously it was (reply_free_queue_depth * 2).
20 Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com>
21 Signed-off-by: James Bottomley <JBottomley@Parallels.com>
22 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
23 ---
24  drivers/scsi/mpt2sas/mpt2sas_base.c  |   83 +++++++++++-----------------------
25  drivers/scsi/mpt2sas/mpt2sas_scsih.c |    4 +-
26  2 files changed, 29 insertions(+), 58 deletions(-)
28 diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
29 index beda04a..0794c72 100644
30 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c
31 +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
32 @@ -65,6 +65,8 @@ static MPT_CALLBACK   mpt_callbacks[MPT_MAX_CALLBACKS];
33  
34  #define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
35  
36 +#define MAX_HBA_QUEUE_DEPTH    30000
37 +#define MAX_CHAIN_DEPTH                100000
38  static int max_queue_depth = -1;
39  module_param(max_queue_depth, int, 0);
40  MODULE_PARM_DESC(max_queue_depth, " max controller queue depth ");
41 @@ -2311,8 +2313,6 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
42                 }
43                 if (ioc->chain_dma_pool)
44                         pci_pool_destroy(ioc->chain_dma_pool);
45 -       }
46 -       if (ioc->chain_lookup) {
47                 free_pages((ulong)ioc->chain_lookup, ioc->chain_pages);
48                 ioc->chain_lookup = NULL;
49         }
50 @@ -2330,9 +2330,7 @@ static int
51  _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
52  {
53         struct mpt2sas_facts *facts;
54 -       u32 queue_size, queue_diff;
55         u16 max_sge_elements;
56 -       u16 num_of_reply_frames;
57         u16 chains_needed_per_io;
58         u32 sz, total_sz, reply_post_free_sz;
59         u32 retry_sz;
60 @@ -2359,7 +2357,8 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
61                 max_request_credit = (max_queue_depth < facts->RequestCredit)
62                     ? max_queue_depth : facts->RequestCredit;
63         else
64 -               max_request_credit = facts->RequestCredit;
65 +               max_request_credit = min_t(u16, facts->RequestCredit,
66 +                   MAX_HBA_QUEUE_DEPTH);
67  
68         ioc->hba_queue_depth = max_request_credit;
69         ioc->hi_priority_depth = facts->HighPriorityCredit;
70 @@ -2400,50 +2399,25 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
71         }
72         ioc->chains_needed_per_io = chains_needed_per_io;
73  
74 -       /* reply free queue sizing - taking into account for events */
75 -       num_of_reply_frames = ioc->hba_queue_depth + 32;
76 -
77 -       /* number of replies frames can't be a multiple of 16 */
78 -       /* decrease number of reply frames by 1 */
79 -       if (!(num_of_reply_frames % 16))
80 -               num_of_reply_frames--;
81 -
82 -       /* calculate number of reply free queue entries
83 -        *  (must be multiple of 16)
84 -        */
85 -
86 -       /* (we know reply_free_queue_depth is not a multiple of 16) */
87 -       queue_size = num_of_reply_frames;
88 -       queue_size += 16 - (queue_size % 16);
89 -       ioc->reply_free_queue_depth = queue_size;
90 -
91 -       /* reply descriptor post queue sizing */
92 -       /* this size should be the number of request frames + number of reply
93 -        * frames
94 -        */
95 -
96 -       queue_size = ioc->hba_queue_depth + num_of_reply_frames + 1;
97 -       /* round up to 16 byte boundary */
98 -       if (queue_size % 16)
99 -               queue_size += 16 - (queue_size % 16);
101 -       /* check against IOC maximum reply post queue depth */
102 -       if (queue_size > facts->MaxReplyDescriptorPostQueueDepth) {
103 -               queue_diff = queue_size -
104 -                   facts->MaxReplyDescriptorPostQueueDepth;
105 +       /* reply free queue sizing - taking into account for 64 FW events */
106 +       ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64;
107  
108 -               /* round queue_diff up to multiple of 16 */
109 -               if (queue_diff % 16)
110 -                       queue_diff += 16 - (queue_diff % 16);
112 -               /* adjust hba_queue_depth, reply_free_queue_depth,
113 -                * and queue_size
114 -                */
115 -               ioc->hba_queue_depth -= (queue_diff / 2);
116 -               ioc->reply_free_queue_depth -= (queue_diff / 2);
117 -               queue_size = facts->MaxReplyDescriptorPostQueueDepth;
118 +       /* align the reply post queue on the next 16 count boundary */
119 +       if (!ioc->reply_free_queue_depth % 16)
120 +               ioc->reply_post_queue_depth = ioc->reply_free_queue_depth + 16;
121 +       else
122 +               ioc->reply_post_queue_depth = ioc->reply_free_queue_depth +
123 +                               32 - (ioc->reply_free_queue_depth % 16);
124 +       if (ioc->reply_post_queue_depth >
125 +           facts->MaxReplyDescriptorPostQueueDepth) {
126 +               ioc->reply_post_queue_depth = min_t(u16,
127 +                   (facts->MaxReplyDescriptorPostQueueDepth -
128 +                   (facts->MaxReplyDescriptorPostQueueDepth % 16)),
129 +                   (ioc->hba_queue_depth - (ioc->hba_queue_depth % 16)));
130 +               ioc->reply_free_queue_depth = ioc->reply_post_queue_depth - 16;
131 +               ioc->hba_queue_depth = ioc->reply_free_queue_depth - 64;
132         }
133 -       ioc->reply_post_queue_depth = queue_size;
135  
136         dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: "
137             "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), "
138 @@ -2529,15 +2503,12 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
139             "depth(%d)\n", ioc->name, ioc->request,
140             ioc->scsiio_depth));
141  
142 -       /* loop till the allocation succeeds */
143 -       do {
144 -               sz = ioc->chain_depth * sizeof(struct chain_tracker);
145 -               ioc->chain_pages = get_order(sz);
146 -               ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
147 -                   GFP_KERNEL, ioc->chain_pages);
148 -               if (ioc->chain_lookup == NULL)
149 -                       ioc->chain_depth -= 100;
150 -       } while (ioc->chain_lookup == NULL);
151 +       ioc->chain_depth = min_t(u32, ioc->chain_depth, MAX_CHAIN_DEPTH);
152 +       sz = ioc->chain_depth * sizeof(struct chain_tracker);
153 +       ioc->chain_pages = get_order(sz);
155 +       ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
156 +           GFP_KERNEL, ioc->chain_pages);
157         ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev,
158             ioc->request_sz, 16, 0);
159         if (!ioc->chain_dma_pool) {
160 diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
161 index 3a4f666..9bc6fb2 100644
162 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
163 +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
164 @@ -1007,8 +1007,8 @@ _scsih_get_chain_buffer_tracker(struct MPT2SAS_ADAPTER *ioc, u16 smid)
165         spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
166         if (list_empty(&ioc->free_chain_list)) {
167                 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
168 -               printk(MPT2SAS_WARN_FMT "chain buffers not available\n",
169 -                   ioc->name);
170 +               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT "chain buffers not "
171 +                       "available\n", ioc->name));
172                 return NULL;
173         }
174         chain_req = list_entry(ioc->free_chain_list.next,
175 -- 
176 1.7.7.4