Commit 654ede200fe028373852bbca387ab4834ddb7228
Committed by
Linus Torvalds
1 parent
b113a3f7e8
Exists in
master
and in
7 other branches
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) |