drivers/mtd/ubi/wl.c
Source file repositories/reference/linux-study-clean/drivers/mtd/ubi/wl.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mtd/ubi/wl.c- Extension
.c- Size
- 58059 bytes
- Lines
- 2179
- Domain
- Driver Families
- Bucket
- drivers/mtd
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/slab.hlinux/crc32.hlinux/freezer.hlinux/kthread.hubi.hwl.hfastmap-wl.c
Detected Declarations
function wl_tree_addfunction wl_entry_destroyfunction do_workfunction in_wl_treefunction in_pqfunction prot_queue_addfunction refill_wl_user_poolfunction prot_queue_delfunction ubi_sync_erasefunction serve_prot_queuefunction __schedule_ubi_workfunction schedule_ubi_workfunction schedule_erasefunction do_sync_erasefunction wear_leveling_workerfunction ensure_wear_levelingfunction __erase_workerfunction erase_workerfunction ubi_wl_put_pebfunction ubi_wl_scrub_pebfunction in_wl_treefunction ubi_wl_flushfunction list_for_each_entry_safefunction scrub_possiblefunction ubi_bitflip_checkfunction tree_destroyfunction ubi_threadfunction kthread_should_stopfunction shutdown_workfunction erase_aebfunction ubi_wl_initfunction list_for_each_entryfunction ubi_rb_for_each_entryfunction list_for_each_entryfunction protection_queue_destroyfunction list_for_each_entry_safefunction ubi_wl_closefunction self_check_ecfunction self_check_in_wl_treefunction self_check_in_pqfunction produce_free_pebfunction ubi_wl_get_peb
Annotated Snippet
if (e->pnum == e1->pnum) {
ubi_assert(e == e1);
return 1;
}
if (e->ec < e1->ec)
p = p->rb_left;
else if (e->ec > e1->ec)
p = p->rb_right;
else {
ubi_assert(e->pnum != e1->pnum);
if (e->pnum < e1->pnum)
p = p->rb_left;
else
p = p->rb_right;
}
}
return 0;
}
/**
* in_pq - check if a wear-leveling entry is present in the protection queue.
* @ubi: UBI device description object
* @e: the wear-leveling entry to check
*
* This function returns non-zero if @e is in the protection queue and zero
* if it is not.
*/
static inline int in_pq(const struct ubi_device *ubi, struct ubi_wl_entry *e)
{
struct ubi_wl_entry *p;
int i;
for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i)
list_for_each_entry(p, &ubi->pq[i], u.list)
if (p == e)
return 1;
return 0;
}
/**
* prot_queue_add - add physical eraseblock to the protection queue.
* @ubi: UBI device description object
* @e: the physical eraseblock to add
*
* This function adds @e to the tail of the protection queue @ubi->pq, where
* @e will stay for %UBI_PROT_QUEUE_LEN erase operations and will be
* temporarily protected from the wear-leveling worker. Note, @wl->lock has to
* be locked.
*/
static void prot_queue_add(struct ubi_device *ubi, struct ubi_wl_entry *e)
{
int pq_tail = ubi->pq_head - 1;
if (pq_tail < 0)
pq_tail = UBI_PROT_QUEUE_LEN - 1;
ubi_assert(pq_tail >= 0 && pq_tail < UBI_PROT_QUEUE_LEN);
list_add_tail(&e->u.list, &ubi->pq[pq_tail]);
dbg_wl("added PEB %d EC %d to the protection queue", e->pnum, e->ec);
}
/**
* find_wl_entry - find wear-leveling entry closest to certain erase counter.
* @ubi: UBI device description object
* @root: the RB-tree where to look for
* @diff: maximum possible difference from the smallest erase counter
* @pick_max: pick PEB even its erase counter beyonds 'min_ec + @diff'
*
* This function looks for a wear leveling entry with erase counter closest to
* min + @diff, where min is the smallest erase counter.
*/
static struct ubi_wl_entry *find_wl_entry(struct ubi_device *ubi,
struct rb_root *root, int diff,
int pick_max)
{
struct rb_node *p;
struct ubi_wl_entry *e;
int max;
e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb);
max = e->ec + diff;
p = root->rb_node;
while (p) {
struct ubi_wl_entry *e1;
e1 = rb_entry(p, struct ubi_wl_entry, u.rb);
if (e1->ec >= max) {
Annotation
- Immediate include surface: `linux/slab.h`, `linux/crc32.h`, `linux/freezer.h`, `linux/kthread.h`, `ubi.h`, `wl.h`, `fastmap-wl.c`.
- Detected declarations: `function wl_tree_add`, `function wl_entry_destroy`, `function do_work`, `function in_wl_tree`, `function in_pq`, `function prot_queue_add`, `function refill_wl_user_pool`, `function prot_queue_del`, `function ubi_sync_erase`, `function serve_prot_queue`.
- Atlas domain: Driver Families / drivers/mtd.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.