Commit 654ede200fe028373852bbca387ab4834ddb7228

Authored by Jason Uhlenkott
Committed by Linus Torvalds
1 parent b113a3f7e8

drivers/edac: mod race fix i82875p

If ERRSTS indicates that there's no error then we don't need to bother reading
the other registers.

In addition to making the common case faster, this actually fixes a small race
where we don't see an error but we clear the error bits anyway, potentially
wiping away info on an error that happened in the interim (or where a CE
arrives between the first and second read of ERRSTS, causing us to falsely
claim "UE overwrote CE").

Signed-off-by: Jason Uhlenkott <juhlenko@akamai.com>
Signed-off-by: Douglas Thompson <dougthompson@xmission.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 7 additions and 6 deletions Side-by-side Diff

drivers/edac/i82875p_edac.c
... ... @@ -198,27 +198,28 @@
198 198 * overwritten by UE.
199 199 */
200 200 pci_read_config_word(pdev, I82875P_ERRSTS, &info->errsts);
  201 +
  202 + if (!(info->errsts & 0x0081))
  203 + return;
  204 +
201 205 pci_read_config_dword(pdev, I82875P_EAP, &info->eap);
202 206 pci_read_config_byte(pdev, I82875P_DES, &info->des);
203 207 pci_read_config_byte(pdev, I82875P_DERRSYN, &info->derrsyn);
204 208 pci_read_config_word(pdev, I82875P_ERRSTS, &info->errsts2);
205 209  
206   - pci_write_bits16(pdev, I82875P_ERRSTS, 0x0081, 0x0081);
207   -
208 210 /*
209 211 * If the error is the same then we can for both reads then
210 212 * the first set of reads is valid. If there is a change then
211 213 * there is a CE no info and the second set of reads is valid
212 214 * and should be UE info.
213 215 */
214   - if (!(info->errsts2 & 0x0081))
215   - return;
216   -
217 216 if ((info->errsts ^ info->errsts2) & 0x0081) {
218 217 pci_read_config_dword(pdev, I82875P_EAP, &info->eap);
219 218 pci_read_config_byte(pdev, I82875P_DES, &info->des);
220 219 pci_read_config_byte(pdev, I82875P_DERRSYN, &info->derrsyn);
221 220 }
  221 +
  222 + pci_write_bits16(pdev, I82875P_ERRSTS, 0x0081, 0x0081);
222 223 }
223 224  
224 225 static int i82875p_process_error_info(struct mem_ctl_info *mci,
... ... @@ -229,7 +230,7 @@
229 230  
230 231 multi_chan = mci->csrows[0].nr_channels - 1;
231 232  
232   - if (!(info->errsts2 & 0x0081))
  233 + if (!(info->errsts & 0x0081))
233 234 return 0;
234 235  
235 236 if (!handle_errors)