diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/edac/edac_mc.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/edac/edac_mc.c')
-rw-r--r-- | drivers/edac/edac_mc.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 6b21e25f7a84..d69144a09043 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -76,6 +76,8 @@ static void edac_mc_dump_mci(struct mem_ctl_info *mci) | |||
76 | debugf3("\tpvt_info = %p\n\n", mci->pvt_info); | 76 | debugf3("\tpvt_info = %p\n\n", mci->pvt_info); |
77 | } | 77 | } |
78 | 78 | ||
79 | #endif /* CONFIG_EDAC_DEBUG */ | ||
80 | |||
79 | /* | 81 | /* |
80 | * keep those in sync with the enum mem_type | 82 | * keep those in sync with the enum mem_type |
81 | */ | 83 | */ |
@@ -100,8 +102,6 @@ const char *edac_mem_types[] = { | |||
100 | }; | 102 | }; |
101 | EXPORT_SYMBOL_GPL(edac_mem_types); | 103 | EXPORT_SYMBOL_GPL(edac_mem_types); |
102 | 104 | ||
103 | #endif /* CONFIG_EDAC_DEBUG */ | ||
104 | |||
105 | /* 'ptr' points to a possibly unaligned item X such that sizeof(X) is 'size'. | 105 | /* 'ptr' points to a possibly unaligned item X such that sizeof(X) is 'size'. |
106 | * Adjust 'ptr' so that its alignment is at least as stringent as what the | 106 | * Adjust 'ptr' so that its alignment is at least as stringent as what the |
107 | * compiler would provide for X and return the aligned result. | 107 | * compiler would provide for X and return the aligned result. |
@@ -207,6 +207,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, | |||
207 | } | 207 | } |
208 | 208 | ||
209 | mci->op_state = OP_ALLOC; | 209 | mci->op_state = OP_ALLOC; |
210 | INIT_LIST_HEAD(&mci->grp_kobj_list); | ||
210 | 211 | ||
211 | /* | 212 | /* |
212 | * Initialize the 'root' kobj for the edac_mc controller | 213 | * Initialize the 'root' kobj for the edac_mc controller |
@@ -234,18 +235,24 @@ EXPORT_SYMBOL_GPL(edac_mc_alloc); | |||
234 | */ | 235 | */ |
235 | void edac_mc_free(struct mem_ctl_info *mci) | 236 | void edac_mc_free(struct mem_ctl_info *mci) |
236 | { | 237 | { |
238 | debugf1("%s()\n", __func__); | ||
239 | |||
237 | edac_mc_unregister_sysfs_main_kobj(mci); | 240 | edac_mc_unregister_sysfs_main_kobj(mci); |
241 | |||
242 | /* free the mci instance memory here */ | ||
243 | kfree(mci); | ||
238 | } | 244 | } |
239 | EXPORT_SYMBOL_GPL(edac_mc_free); | 245 | EXPORT_SYMBOL_GPL(edac_mc_free); |
240 | 246 | ||
241 | 247 | ||
242 | /* | 248 | /** |
243 | * find_mci_by_dev | 249 | * find_mci_by_dev |
244 | * | 250 | * |
245 | * scan list of controllers looking for the one that manages | 251 | * scan list of controllers looking for the one that manages |
246 | * the 'dev' device | 252 | * the 'dev' device |
253 | * @dev: pointer to a struct device related with the MCI | ||
247 | */ | 254 | */ |
248 | static struct mem_ctl_info *find_mci_by_dev(struct device *dev) | 255 | struct mem_ctl_info *find_mci_by_dev(struct device *dev) |
249 | { | 256 | { |
250 | struct mem_ctl_info *mci; | 257 | struct mem_ctl_info *mci; |
251 | struct list_head *item; | 258 | struct list_head *item; |
@@ -261,6 +268,7 @@ static struct mem_ctl_info *find_mci_by_dev(struct device *dev) | |||
261 | 268 | ||
262 | return NULL; | 269 | return NULL; |
263 | } | 270 | } |
271 | EXPORT_SYMBOL_GPL(find_mci_by_dev); | ||
264 | 272 | ||
265 | /* | 273 | /* |
266 | * handler for EDAC to check if NMI type handler has asserted interrupt | 274 | * handler for EDAC to check if NMI type handler has asserted interrupt |
@@ -439,20 +447,16 @@ fail1: | |||
439 | return 1; | 447 | return 1; |
440 | } | 448 | } |
441 | 449 | ||
442 | static void complete_mc_list_del(struct rcu_head *head) | ||
443 | { | ||
444 | struct mem_ctl_info *mci; | ||
445 | |||
446 | mci = container_of(head, struct mem_ctl_info, rcu); | ||
447 | INIT_LIST_HEAD(&mci->link); | ||
448 | } | ||
449 | |||
450 | static void del_mc_from_global_list(struct mem_ctl_info *mci) | 450 | static void del_mc_from_global_list(struct mem_ctl_info *mci) |
451 | { | 451 | { |
452 | atomic_dec(&edac_handlers); | 452 | atomic_dec(&edac_handlers); |
453 | list_del_rcu(&mci->link); | 453 | list_del_rcu(&mci->link); |
454 | call_rcu(&mci->rcu, complete_mc_list_del); | 454 | |
455 | rcu_barrier(); | 455 | /* these are for safe removal of devices from global list while |
456 | * NMI handlers may be traversing list | ||
457 | */ | ||
458 | synchronize_rcu(); | ||
459 | INIT_LIST_HEAD(&mci->link); | ||
456 | } | 460 | } |
457 | 461 | ||
458 | /** | 462 | /** |
@@ -578,14 +582,16 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev) | |||
578 | return NULL; | 582 | return NULL; |
579 | } | 583 | } |
580 | 584 | ||
581 | /* marking MCI offline */ | ||
582 | mci->op_state = OP_OFFLINE; | ||
583 | |||
584 | del_mc_from_global_list(mci); | 585 | del_mc_from_global_list(mci); |
585 | mutex_unlock(&mem_ctls_mutex); | 586 | mutex_unlock(&mem_ctls_mutex); |
586 | 587 | ||
587 | /* flush workq processes and remove sysfs */ | 588 | /* flush workq processes */ |
588 | edac_mc_workq_teardown(mci); | 589 | edac_mc_workq_teardown(mci); |
590 | |||
591 | /* marking MCI offline */ | ||
592 | mci->op_state = OP_OFFLINE; | ||
593 | |||
594 | /* remove from sysfs */ | ||
589 | edac_remove_sysfs_mci_device(mci); | 595 | edac_remove_sysfs_mci_device(mci); |
590 | 596 | ||
591 | edac_printk(KERN_INFO, EDAC_MC, | 597 | edac_printk(KERN_INFO, EDAC_MC, |
@@ -714,7 +720,7 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci, | |||
714 | * Some MC's can remap memory so that it is still available | 720 | * Some MC's can remap memory so that it is still available |
715 | * at a different address when PCI devices map into memory. | 721 | * at a different address when PCI devices map into memory. |
716 | * MC's that can't do this lose the memory where PCI devices | 722 | * MC's that can't do this lose the memory where PCI devices |
717 | * are mapped. This mapping is MC dependant and so we call | 723 | * are mapped. This mapping is MC dependent and so we call |
718 | * back into the MC driver for it to map the MC page to | 724 | * back into the MC driver for it to map the MC page to |
719 | * a physical (CPU) page which can then be mapped to a virtual | 725 | * a physical (CPU) page which can then be mapped to a virtual |
720 | * page - which can then be scrubbed. | 726 | * page - which can then be scrubbed. |