aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-08-11 23:30:25 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-24 09:20:37 -0400
commit6fe1108f14f4f9581af97cab752f37dc8fa9fdec (patch)
tree88484ab0733ed38cf09526f9d47e4c52d8ac0430 /drivers/edac
parent39300e7143f8ef81b07cee3d8b86880bc4311ea0 (diff)
edac_core: Do a better job with node removal
Make sure we remove groups at the right order Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/edac_mc.c1
-rw-r--r--drivers/edac/edac_mc_sysfs.c71
2 files changed, 43 insertions, 29 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 6b7e723e46be..b10b45cc7870 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -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
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index aacffe5d0f33..5a5734c1f6a5 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -791,6 +791,7 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
791 debugf1("%s()\n", __func__); 791 debugf1("%s()\n", __func__);
792 792
793 while (sysfs_attrib) { 793 while (sysfs_attrib) {
794 debugf1("%s() sysfs_attrib = %p\n",__func__, sysfs_attrib);
794 if (sysfs_attrib->grp) { 795 if (sysfs_attrib->grp) {
795 struct mcidev_sysfs_group_kobj *grp_kobj; 796 struct mcidev_sysfs_group_kobj *grp_kobj;
796 797
@@ -798,10 +799,9 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
798 if (!grp_kobj) 799 if (!grp_kobj)
799 return -ENOMEM; 800 return -ENOMEM;
800 801
801 list_add_tail(&grp_kobj->list, &mci->grp_kobj_list);
802
803 grp_kobj->grp = sysfs_attrib->grp; 802 grp_kobj->grp = sysfs_attrib->grp;
804 grp_kobj->mci = mci; 803 grp_kobj->mci = mci;
804 list_add_tail(&grp_kobj->list, &mci->grp_kobj_list);
805 805
806 debugf0("%s() grp %s, mci %p\n", __func__, 806 debugf0("%s() grp %s, mci %p\n", __func__,
807 sysfs_attrib->grp->name, mci); 807 sysfs_attrib->grp->name, mci);
@@ -810,26 +810,28 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
810 &ktype_inst_grp, 810 &ktype_inst_grp,
811 &mci->edac_mci_kobj, 811 &mci->edac_mci_kobj,
812 sysfs_attrib->grp->name); 812 sysfs_attrib->grp->name);
813 if (err) 813 if (err < 0) {
814 printk(KERN_ERR "kobject_init_and_add failed: %d\n", err);
814 return err; 815 return err;
815 816 }
816 err = edac_create_mci_instance_attributes(mci, 817 err = edac_create_mci_instance_attributes(mci,
817 grp_kobj->grp->mcidev_attr, 818 grp_kobj->grp->mcidev_attr,
818 &grp_kobj->kobj); 819 &grp_kobj->kobj);
819 820
820 if (err) 821 if (err < 0)
821 return err; 822 return err;
822 } else if (sysfs_attrib->attr.name) { 823 } else if (sysfs_attrib->attr.name) {
823 debugf0("%s() file %s\n", __func__, 824 debugf0("%s() file %s\n", __func__,
824 sysfs_attrib->attr.name); 825 sysfs_attrib->attr.name);
825 826
826 err = sysfs_create_file(kobj, &sysfs_attrib->attr); 827 err = sysfs_create_file(kobj, &sysfs_attrib->attr);
828 if (err < 0) {
829 printk(KERN_ERR "sysfs_create_file failed: %d\n", err);
830 return err;
831 }
827 } else 832 } else
828 break; 833 break;
829 834
830 if (err) {
831 return err;
832 }
833 sysfs_attrib++; 835 sysfs_attrib++;
834 } 836 }
835 837
@@ -854,13 +856,24 @@ static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci,
854 * Remove first all the atributes 856 * Remove first all the atributes
855 */ 857 */
856 while (sysfs_attrib) { 858 while (sysfs_attrib) {
859 debugf1("%s() sysfs_attrib = %p\n",__func__, sysfs_attrib);
857 if (sysfs_attrib->grp) { 860 if (sysfs_attrib->grp) {
858 list_for_each_entry(grp_kobj, &mci->grp_kobj_list, 861 debugf1("%s() seeking for group %s\n",
859 list) 862 __func__, sysfs_attrib->grp->name);
860 if (grp_kobj->grp == sysfs_attrib->grp) 863 list_for_each_entry(grp_kobj,
864 &mci->grp_kobj_list, list) {
865 debugf1("%s() grp_kobj->grp = %p\n",__func__, grp_kobj->grp);
866 if (grp_kobj->grp == sysfs_attrib->grp) {
861 edac_remove_mci_instance_attributes(mci, 867 edac_remove_mci_instance_attributes(mci,
862 grp_kobj->grp->mcidev_attr, 868 grp_kobj->grp->mcidev_attr,
863 &grp_kobj->kobj, count + 1); 869 &grp_kobj->kobj, count + 1);
870 debugf0("%s() group %s\n", __func__,
871 sysfs_attrib->grp->name);
872 kobject_put(&grp_kobj->kobj);
873 }
874 }
875 debugf1("%s() end of seeking for group %s\n",
876 __func__, sysfs_attrib->grp->name);
864 } else if (sysfs_attrib->attr.name) { 877 } else if (sysfs_attrib->attr.name) {
865 debugf0("%s() file %s\n", __func__, 878 debugf0("%s() file %s\n", __func__,
866 sysfs_attrib->attr.name); 879 sysfs_attrib->attr.name);
@@ -870,15 +883,14 @@ static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci,
870 sysfs_attrib++; 883 sysfs_attrib++;
871 } 884 }
872 885
873 /* 886 /* Remove the group objects */
874 * Now that all attributes got removed, it is save to remove all groups 887 if (count)
875 */ 888 return;
876 if (!count) 889 list_for_each_entry_safe(grp_kobj, tmp,
877 list_for_each_entry_safe(grp_kobj, tmp, &mci->grp_kobj_list, 890 &mci->grp_kobj_list, list) {
878 list) { 891 list_del(&grp_kobj->list);
879 debugf0("%s() grp %s\n", __func__, grp_kobj->grp->name); 892 kfree(grp_kobj);
880 kobject_put(&grp_kobj->kobj); 893 }
881 }
882} 894}
883 895
884 896
@@ -970,6 +982,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
970 debugf0("%s()\n", __func__); 982 debugf0("%s()\n", __func__);
971 983
972 /* remove all csrow kobjects */ 984 /* remove all csrow kobjects */
985 debugf0("%s() unregister this mci kobj\n", __func__);
973 for (i = 0; i < mci->nr_csrows; i++) { 986 for (i = 0; i < mci->nr_csrows; i++) {
974 if (mci->csrows[i].nr_pages > 0) { 987 if (mci->csrows[i].nr_pages > 0) {
975 debugf0("%s() unreg csrow-%d\n", __func__, i); 988 debugf0("%s() unreg csrow-%d\n", __func__, i);
@@ -977,20 +990,20 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
977 } 990 }
978 } 991 }
979 992
980 debugf0("%s() remove_link\n", __func__); 993 /* remove this mci instance's attribtes */
994 if (mci->mc_driver_sysfs_attributes) {
995 debugf0("%s() unregister mci private attributes\n", __func__);
996 edac_remove_mci_instance_attributes(mci,
997 mci->mc_driver_sysfs_attributes,
998 &mci->edac_mci_kobj, 0);
999 }
981 1000
982 /* remove the symlink */ 1001 /* remove the symlink */
1002 debugf0("%s() remove_link\n", __func__);
983 sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK); 1003 sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK);
984 1004
985 debugf0("%s() remove_mci_instance\n", __func__);
986
987 /* remove this mci instance's attribtes */
988 edac_remove_mci_instance_attributes(mci,
989 mci->mc_driver_sysfs_attributes,
990 &mci->edac_mci_kobj, 0);
991 debugf0("%s() unregister this mci kobj\n", __func__);
992
993 /* unregister this instance's kobject */ 1005 /* unregister this instance's kobject */
1006 debugf0("%s() remove_mci_instance\n", __func__);
994 kobject_put(&mci->edac_mci_kobj); 1007 kobject_put(&mci->edac_mci_kobj);
995} 1008}
996 1009