aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ras/cec.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c
index 88e4f3ff0cb8..dbfe3e61d2c2 100644
--- a/drivers/ras/cec.c
+++ b/drivers/ras/cec.c
@@ -183,32 +183,38 @@ static void cec_timer_fn(struct timer_list *unused)
183 */ 183 */
184static int __find_elem(struct ce_array *ca, u64 pfn, unsigned int *to) 184static int __find_elem(struct ce_array *ca, u64 pfn, unsigned int *to)
185{ 185{
186 int min = 0, max = ca->n - 1;
186 u64 this_pfn; 187 u64 this_pfn;
187 int min = 0, max = ca->n;
188 188
189 while (min < max) { 189 while (min <= max) {
190 int tmp = (max + min) >> 1; 190 int i = (min + max) >> 1;
191 191
192 this_pfn = PFN(ca->array[tmp]); 192 this_pfn = PFN(ca->array[i]);
193 193
194 if (this_pfn < pfn) 194 if (this_pfn < pfn)
195 min = tmp + 1; 195 min = i + 1;
196 else if (this_pfn > pfn) 196 else if (this_pfn > pfn)
197 max = tmp; 197 max = i - 1;
198 else { 198 else if (this_pfn == pfn) {
199 min = tmp; 199 if (to)
200 break; 200 *to = i;
201
202 return i;
201 } 203 }
202 } 204 }
203 205
206 /*
207 * When the loop terminates without finding @pfn, min has the index of
208 * the element slot where the new @pfn should be inserted. The loop
209 * terminates when min > max, which means the min index points to the
210 * bigger element while the max index to the smaller element, in-between
211 * which the new @pfn belongs to.
212 *
213 * For more details, see exercise 1, Section 6.2.1 in TAOCP, vol. 3.
214 */
204 if (to) 215 if (to)
205 *to = min; 216 *to = min;
206 217
207 this_pfn = PFN(ca->array[min]);
208
209 if (this_pfn == pfn)
210 return min;
211
212 return -ENOKEY; 218 return -ENOKEY;
213} 219}
214 220