diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-11 23:30:25 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-24 09:20:37 -0400 |
commit | 6fe1108f14f4f9581af97cab752f37dc8fa9fdec (patch) | |
tree | 88484ab0733ed38cf09526f9d47e4c52d8ac0430 /drivers/edac | |
parent | 39300e7143f8ef81b07cee3d8b86880bc4311ea0 (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.c | 1 | ||||
-rw-r--r-- | drivers/edac/edac_mc_sysfs.c | 71 |
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 | ||