diff options
Diffstat (limited to 'drivers/mtd/ubi/wl.c')
-rw-r--r-- | drivers/mtd/ubi/wl.c | 179 |
1 files changed, 109 insertions, 70 deletions
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 891534f8210d..2b2472300610 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -55,8 +55,8 @@ | |||
55 | * | 55 | * |
56 | * As it was said, for the UBI sub-system all physical eraseblocks are either | 56 | * As it was said, for the UBI sub-system all physical eraseblocks are either |
57 | * "free" or "used". Free eraseblock are kept in the @wl->free RB-tree, while | 57 | * "free" or "used". Free eraseblock are kept in the @wl->free RB-tree, while |
58 | * used eraseblocks are kept in @wl->used or @wl->scrub RB-trees, or | 58 | * used eraseblocks are kept in @wl->used, @wl->erroneous, or @wl->scrub |
59 | * (temporarily) in the @wl->pq queue. | 59 | * RB-trees, as well as (temporarily) in the @wl->pq queue. |
60 | * | 60 | * |
61 | * When the WL sub-system returns a physical eraseblock, the physical | 61 | * When the WL sub-system returns a physical eraseblock, the physical |
62 | * eraseblock is protected from being moved for some "time". For this reason, | 62 | * eraseblock is protected from being moved for some "time". For this reason, |
@@ -83,6 +83,8 @@ | |||
83 | * used. The former state corresponds to the @wl->free tree. The latter state | 83 | * used. The former state corresponds to the @wl->free tree. The latter state |
84 | * is split up on several sub-states: | 84 | * is split up on several sub-states: |
85 | * o the WL movement is allowed (@wl->used tree); | 85 | * o the WL movement is allowed (@wl->used tree); |
86 | * o the WL movement is disallowed (@wl->erroneous) because the PEB is | ||
87 | * erroneous - e.g., there was a read error; | ||
86 | * o the WL movement is temporarily prohibited (@wl->pq queue); | 88 | * o the WL movement is temporarily prohibited (@wl->pq queue); |
87 | * o scrubbing is needed (@wl->scrub tree). | 89 | * o scrubbing is needed (@wl->scrub tree). |
88 | * | 90 | * |
@@ -653,7 +655,8 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, | |||
653 | static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | 655 | static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, |
654 | int cancel) | 656 | int cancel) |
655 | { | 657 | { |
656 | int err, scrubbing = 0, torture = 0; | 658 | int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0; |
659 | int vol_id = -1, uninitialized_var(lnum); | ||
657 | struct ubi_wl_entry *e1, *e2; | 660 | struct ubi_wl_entry *e1, *e2; |
658 | struct ubi_vid_hdr *vid_hdr; | 661 | struct ubi_vid_hdr *vid_hdr; |
659 | 662 | ||
@@ -738,68 +741,78 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
738 | /* | 741 | /* |
739 | * We are trying to move PEB without a VID header. UBI | 742 | * We are trying to move PEB without a VID header. UBI |
740 | * always write VID headers shortly after the PEB was | 743 | * always write VID headers shortly after the PEB was |
741 | * given, so we have a situation when it did not have | 744 | * given, so we have a situation when it has not yet |
742 | * chance to write it down because it was preempted. | 745 | * had a chance to write it, because it was preempted. |
743 | * Just re-schedule the work, so that next time it will | 746 | * So add this PEB to the protection queue so far, |
744 | * likely have the VID header in place. | 747 | * because presumably more data will be written there |
748 | * (including the missing VID header), and then we'll | ||
749 | * move it. | ||
745 | */ | 750 | */ |
746 | dbg_wl("PEB %d has no VID header", e1->pnum); | 751 | dbg_wl("PEB %d has no VID header", e1->pnum); |
752 | protect = 1; | ||
747 | goto out_not_moved; | 753 | goto out_not_moved; |
748 | } | 754 | } |
749 | 755 | ||
750 | ubi_err("error %d while reading VID header from PEB %d", | 756 | ubi_err("error %d while reading VID header from PEB %d", |
751 | err, e1->pnum); | 757 | err, e1->pnum); |
752 | if (err > 0) | ||
753 | err = -EIO; | ||
754 | goto out_error; | 758 | goto out_error; |
755 | } | 759 | } |
756 | 760 | ||
761 | vol_id = be32_to_cpu(vid_hdr->vol_id); | ||
762 | lnum = be32_to_cpu(vid_hdr->lnum); | ||
763 | |||
757 | err = ubi_eba_copy_leb(ubi, e1->pnum, e2->pnum, vid_hdr); | 764 | err = ubi_eba_copy_leb(ubi, e1->pnum, e2->pnum, vid_hdr); |
758 | if (err) { | 765 | if (err) { |
759 | if (err == -EAGAIN) | 766 | if (err == MOVE_CANCEL_RACE) { |
767 | /* | ||
768 | * The LEB has not been moved because the volume is | ||
769 | * being deleted or the PEB has been put meanwhile. We | ||
770 | * should prevent this PEB from being selected for | ||
771 | * wear-leveling movement again, so put it to the | ||
772 | * protection queue. | ||
773 | */ | ||
774 | protect = 1; | ||
760 | goto out_not_moved; | 775 | goto out_not_moved; |
761 | if (err < 0) | 776 | } |
762 | goto out_error; | 777 | |
763 | if (err == 2) { | 778 | if (err == MOVE_CANCEL_BITFLIPS || err == MOVE_TARGET_WR_ERR || |
764 | /* Target PEB write error, torture it */ | 779 | err == MOVE_TARGET_RD_ERR) { |
780 | /* | ||
781 | * Target PEB had bit-flips or write error - torture it. | ||
782 | */ | ||
765 | torture = 1; | 783 | torture = 1; |
766 | goto out_not_moved; | 784 | goto out_not_moved; |
767 | } | 785 | } |
768 | 786 | ||
769 | /* | 787 | if (err == MOVE_SOURCE_RD_ERR) { |
770 | * The LEB has not been moved because the volume is being | 788 | /* |
771 | * deleted or the PEB has been put meanwhile. We should prevent | 789 | * An error happened while reading the source PEB. Do |
772 | * this PEB from being selected for wear-leveling movement | 790 | * not switch to R/O mode in this case, and give the |
773 | * again, so put it to the protection queue. | 791 | * upper layers a possibility to recover from this, |
774 | */ | 792 | * e.g. by unmapping corresponding LEB. Instead, just |
775 | 793 | * put this PEB to the @ubi->erroneous list to prevent | |
776 | dbg_wl("canceled moving PEB %d", e1->pnum); | 794 | * UBI from trying to move it over and over again. |
777 | ubi_assert(err == 1); | 795 | */ |
778 | 796 | if (ubi->erroneous_peb_count > ubi->max_erroneous) { | |
779 | ubi_free_vid_hdr(ubi, vid_hdr); | 797 | ubi_err("too many erroneous eraseblocks (%d)", |
780 | vid_hdr = NULL; | 798 | ubi->erroneous_peb_count); |
781 | 799 | goto out_error; | |
782 | spin_lock(&ubi->wl_lock); | 800 | } |
783 | prot_queue_add(ubi, e1); | 801 | erroneous = 1; |
784 | ubi_assert(!ubi->move_to_put); | 802 | goto out_not_moved; |
785 | ubi->move_from = ubi->move_to = NULL; | 803 | } |
786 | ubi->wl_scheduled = 0; | ||
787 | spin_unlock(&ubi->wl_lock); | ||
788 | 804 | ||
789 | e1 = NULL; | 805 | if (err < 0) |
790 | err = schedule_erase(ubi, e2, 0); | ||
791 | if (err) | ||
792 | goto out_error; | 806 | goto out_error; |
793 | mutex_unlock(&ubi->move_mutex); | 807 | |
794 | return 0; | 808 | ubi_assert(0); |
795 | } | 809 | } |
796 | 810 | ||
797 | /* The PEB has been successfully moved */ | 811 | /* The PEB has been successfully moved */ |
798 | ubi_free_vid_hdr(ubi, vid_hdr); | ||
799 | vid_hdr = NULL; | ||
800 | if (scrubbing) | 812 | if (scrubbing) |
801 | ubi_msg("scrubbed PEB %d, data moved to PEB %d", | 813 | ubi_msg("scrubbed PEB %d (LEB %d:%d), data moved to PEB %d", |
802 | e1->pnum, e2->pnum); | 814 | e1->pnum, vol_id, lnum, e2->pnum); |
815 | ubi_free_vid_hdr(ubi, vid_hdr); | ||
803 | 816 | ||
804 | spin_lock(&ubi->wl_lock); | 817 | spin_lock(&ubi->wl_lock); |
805 | if (!ubi->move_to_put) { | 818 | if (!ubi->move_to_put) { |
@@ -812,8 +825,10 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
812 | 825 | ||
813 | err = schedule_erase(ubi, e1, 0); | 826 | err = schedule_erase(ubi, e1, 0); |
814 | if (err) { | 827 | if (err) { |
815 | e1 = NULL; | 828 | kmem_cache_free(ubi_wl_entry_slab, e1); |
816 | goto out_error; | 829 | if (e2) |
830 | kmem_cache_free(ubi_wl_entry_slab, e2); | ||
831 | goto out_ro; | ||
817 | } | 832 | } |
818 | 833 | ||
819 | if (e2) { | 834 | if (e2) { |
@@ -821,10 +836,13 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
821 | * Well, the target PEB was put meanwhile, schedule it for | 836 | * Well, the target PEB was put meanwhile, schedule it for |
822 | * erasure. | 837 | * erasure. |
823 | */ | 838 | */ |
824 | dbg_wl("PEB %d was put meanwhile, erase", e2->pnum); | 839 | dbg_wl("PEB %d (LEB %d:%d) was put meanwhile, erase", |
840 | e2->pnum, vol_id, lnum); | ||
825 | err = schedule_erase(ubi, e2, 0); | 841 | err = schedule_erase(ubi, e2, 0); |
826 | if (err) | 842 | if (err) { |
827 | goto out_error; | 843 | kmem_cache_free(ubi_wl_entry_slab, e2); |
844 | goto out_ro; | ||
845 | } | ||
828 | } | 846 | } |
829 | 847 | ||
830 | dbg_wl("done"); | 848 | dbg_wl("done"); |
@@ -837,11 +855,19 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
837 | * have been changed, schedule it for erasure. | 855 | * have been changed, schedule it for erasure. |
838 | */ | 856 | */ |
839 | out_not_moved: | 857 | out_not_moved: |
840 | dbg_wl("canceled moving PEB %d", e1->pnum); | 858 | if (vol_id != -1) |
841 | ubi_free_vid_hdr(ubi, vid_hdr); | 859 | dbg_wl("cancel moving PEB %d (LEB %d:%d) to PEB %d (%d)", |
842 | vid_hdr = NULL; | 860 | e1->pnum, vol_id, lnum, e2->pnum, err); |
861 | else | ||
862 | dbg_wl("cancel moving PEB %d to PEB %d (%d)", | ||
863 | e1->pnum, e2->pnum, err); | ||
843 | spin_lock(&ubi->wl_lock); | 864 | spin_lock(&ubi->wl_lock); |
844 | if (scrubbing) | 865 | if (protect) |
866 | prot_queue_add(ubi, e1); | ||
867 | else if (erroneous) { | ||
868 | wl_tree_add(e1, &ubi->erroneous); | ||
869 | ubi->erroneous_peb_count += 1; | ||
870 | } else if (scrubbing) | ||
845 | wl_tree_add(e1, &ubi->scrub); | 871 | wl_tree_add(e1, &ubi->scrub); |
846 | else | 872 | else |
847 | wl_tree_add(e1, &ubi->used); | 873 | wl_tree_add(e1, &ubi->used); |
@@ -850,32 +876,36 @@ out_not_moved: | |||
850 | ubi->wl_scheduled = 0; | 876 | ubi->wl_scheduled = 0; |
851 | spin_unlock(&ubi->wl_lock); | 877 | spin_unlock(&ubi->wl_lock); |
852 | 878 | ||
853 | e1 = NULL; | 879 | ubi_free_vid_hdr(ubi, vid_hdr); |
854 | err = schedule_erase(ubi, e2, torture); | 880 | err = schedule_erase(ubi, e2, torture); |
855 | if (err) | 881 | if (err) { |
856 | goto out_error; | 882 | kmem_cache_free(ubi_wl_entry_slab, e2); |
857 | 883 | goto out_ro; | |
884 | } | ||
858 | mutex_unlock(&ubi->move_mutex); | 885 | mutex_unlock(&ubi->move_mutex); |
859 | return 0; | 886 | return 0; |
860 | 887 | ||
861 | out_error: | 888 | out_error: |
862 | ubi_err("error %d while moving PEB %d to PEB %d", | 889 | if (vol_id != -1) |
863 | err, e1->pnum, e2->pnum); | 890 | ubi_err("error %d while moving PEB %d to PEB %d", |
864 | 891 | err, e1->pnum, e2->pnum); | |
865 | ubi_free_vid_hdr(ubi, vid_hdr); | 892 | else |
893 | ubi_err("error %d while moving PEB %d (LEB %d:%d) to PEB %d", | ||
894 | err, e1->pnum, vol_id, lnum, e2->pnum); | ||
866 | spin_lock(&ubi->wl_lock); | 895 | spin_lock(&ubi->wl_lock); |
867 | ubi->move_from = ubi->move_to = NULL; | 896 | ubi->move_from = ubi->move_to = NULL; |
868 | ubi->move_to_put = ubi->wl_scheduled = 0; | 897 | ubi->move_to_put = ubi->wl_scheduled = 0; |
869 | spin_unlock(&ubi->wl_lock); | 898 | spin_unlock(&ubi->wl_lock); |
870 | 899 | ||
871 | if (e1) | 900 | ubi_free_vid_hdr(ubi, vid_hdr); |
872 | kmem_cache_free(ubi_wl_entry_slab, e1); | 901 | kmem_cache_free(ubi_wl_entry_slab, e1); |
873 | if (e2) | 902 | kmem_cache_free(ubi_wl_entry_slab, e2); |
874 | kmem_cache_free(ubi_wl_entry_slab, e2); | ||
875 | ubi_ro_mode(ubi); | ||
876 | 903 | ||
904 | out_ro: | ||
905 | ubi_ro_mode(ubi); | ||
877 | mutex_unlock(&ubi->move_mutex); | 906 | mutex_unlock(&ubi->move_mutex); |
878 | return err; | 907 | ubi_assert(err != 0); |
908 | return err < 0 ? err : -EIO; | ||
879 | 909 | ||
880 | out_cancel: | 910 | out_cancel: |
881 | ubi->wl_scheduled = 0; | 911 | ubi->wl_scheduled = 0; |
@@ -1015,7 +1045,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
1015 | /* | 1045 | /* |
1016 | * If this is not %-EIO, we have no idea what to do. Scheduling | 1046 | * If this is not %-EIO, we have no idea what to do. Scheduling |
1017 | * this physical eraseblock for erasure again would cause | 1047 | * this physical eraseblock for erasure again would cause |
1018 | * errors again and again. Well, lets switch to RO mode. | 1048 | * errors again and again. Well, lets switch to R/O mode. |
1019 | */ | 1049 | */ |
1020 | goto out_ro; | 1050 | goto out_ro; |
1021 | } | 1051 | } |
@@ -1043,10 +1073,9 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
1043 | ubi_err("no reserved physical eraseblocks"); | 1073 | ubi_err("no reserved physical eraseblocks"); |
1044 | goto out_ro; | 1074 | goto out_ro; |
1045 | } | 1075 | } |
1046 | |||
1047 | spin_unlock(&ubi->volumes_lock); | 1076 | spin_unlock(&ubi->volumes_lock); |
1048 | ubi_msg("mark PEB %d as bad", pnum); | ||
1049 | 1077 | ||
1078 | ubi_msg("mark PEB %d as bad", pnum); | ||
1050 | err = ubi_io_mark_bad(ubi, pnum); | 1079 | err = ubi_io_mark_bad(ubi, pnum); |
1051 | if (err) | 1080 | if (err) |
1052 | goto out_ro; | 1081 | goto out_ro; |
@@ -1056,7 +1085,9 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
1056 | ubi->bad_peb_count += 1; | 1085 | ubi->bad_peb_count += 1; |
1057 | ubi->good_peb_count -= 1; | 1086 | ubi->good_peb_count -= 1; |
1058 | ubi_calculate_reserved(ubi); | 1087 | ubi_calculate_reserved(ubi); |
1059 | if (ubi->beb_rsvd_pebs == 0) | 1088 | if (ubi->beb_rsvd_pebs) |
1089 | ubi_msg("%d PEBs left in the reserve", ubi->beb_rsvd_pebs); | ||
1090 | else | ||
1060 | ubi_warn("last PEB from the reserved pool was used"); | 1091 | ubi_warn("last PEB from the reserved pool was used"); |
1061 | spin_unlock(&ubi->volumes_lock); | 1092 | spin_unlock(&ubi->volumes_lock); |
1062 | 1093 | ||
@@ -1125,6 +1156,13 @@ retry: | |||
1125 | } else if (in_wl_tree(e, &ubi->scrub)) { | 1156 | } else if (in_wl_tree(e, &ubi->scrub)) { |
1126 | paranoid_check_in_wl_tree(e, &ubi->scrub); | 1157 | paranoid_check_in_wl_tree(e, &ubi->scrub); |
1127 | rb_erase(&e->u.rb, &ubi->scrub); | 1158 | rb_erase(&e->u.rb, &ubi->scrub); |
1159 | } else if (in_wl_tree(e, &ubi->erroneous)) { | ||
1160 | paranoid_check_in_wl_tree(e, &ubi->erroneous); | ||
1161 | rb_erase(&e->u.rb, &ubi->erroneous); | ||
1162 | ubi->erroneous_peb_count -= 1; | ||
1163 | ubi_assert(ubi->erroneous_peb_count >= 0); | ||
1164 | /* Erroneous PEBs should be tortured */ | ||
1165 | torture = 1; | ||
1128 | } else { | 1166 | } else { |
1129 | err = prot_queue_del(ubi, e->pnum); | 1167 | err = prot_queue_del(ubi, e->pnum); |
1130 | if (err) { | 1168 | if (err) { |
@@ -1373,7 +1411,7 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
1373 | struct ubi_scan_leb *seb, *tmp; | 1411 | struct ubi_scan_leb *seb, *tmp; |
1374 | struct ubi_wl_entry *e; | 1412 | struct ubi_wl_entry *e; |
1375 | 1413 | ||
1376 | ubi->used = ubi->free = ubi->scrub = RB_ROOT; | 1414 | ubi->used = ubi->erroneous = ubi->free = ubi->scrub = RB_ROOT; |
1377 | spin_lock_init(&ubi->wl_lock); | 1415 | spin_lock_init(&ubi->wl_lock); |
1378 | mutex_init(&ubi->move_mutex); | 1416 | mutex_init(&ubi->move_mutex); |
1379 | init_rwsem(&ubi->work_sem); | 1417 | init_rwsem(&ubi->work_sem); |
@@ -1511,6 +1549,7 @@ void ubi_wl_close(struct ubi_device *ubi) | |||
1511 | cancel_pending(ubi); | 1549 | cancel_pending(ubi); |
1512 | protection_queue_destroy(ubi); | 1550 | protection_queue_destroy(ubi); |
1513 | tree_destroy(&ubi->used); | 1551 | tree_destroy(&ubi->used); |
1552 | tree_destroy(&ubi->erroneous); | ||
1514 | tree_destroy(&ubi->free); | 1553 | tree_destroy(&ubi->free); |
1515 | tree_destroy(&ubi->scrub); | 1554 | tree_destroy(&ubi->scrub); |
1516 | kfree(ubi->lookuptbl); | 1555 | kfree(ubi->lookuptbl); |