diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 141c602d5e85..78e32ba0553d 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -1209,9 +1209,8 @@ static int bfqq_process_refs(struct bfq_queue *bfqq) static void bfq_reset_burst_list(struct bfq_data *bfqd, struct bfq_queue *bfqq) { struct bfq_queue *item; - struct hlist_node *n; - hlist_for_each_entry_safe(item, n, &bfqd->burst_list, burst_list_node) + hlist_for_each_entry_mutable(item, &bfqd->burst_list, burst_list_node) hlist_del_init(&item->burst_list_node); /* @@ -1236,7 +1235,6 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) { struct bfq_queue *pos, *bfqq_item; - struct hlist_node *n; /* * Enough queues have been activated shortly after each @@ -1260,8 +1258,8 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) * belonging to a large burst. So the burst list is not * needed any more. Remove it. */ - hlist_for_each_entry_safe(pos, n, &bfqd->burst_list, - burst_list_node) + hlist_for_each_entry_mutable(pos, &bfqd->burst_list, + burst_list_node) hlist_del_init(&pos->burst_list_node); } else /* * Burst not yet large: add bfqq to the burst list. Do @@ -5330,7 +5328,6 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx) void bfq_put_queue(struct bfq_queue *bfqq) { struct bfq_queue *item; - struct hlist_node *n; struct bfq_group *bfqg = bfqq_group(bfqq); bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p %d", bfqq, bfqq->ref); @@ -5391,8 +5388,8 @@ void bfq_put_queue(struct bfq_queue *bfqq) hlist_del_init(&bfqq->woken_list_node); /* reset waker for all queues in woken list */ - hlist_for_each_entry_safe(item, n, &bfqq->woken_list, - woken_list_node) { + hlist_for_each_entry_mutable(item, &bfqq->woken_list, + woken_list_node) { item->waker_bfqq = NULL; hlist_del_init(&item->woken_list_node); } @@ -7141,13 +7138,13 @@ static void bfq_depth_updated(struct request_queue *q) static void bfq_exit_queue(struct elevator_queue *e) { struct bfq_data *bfqd = e->elevator_data; - struct bfq_queue *bfqq, *n; + struct bfq_queue *bfqq; unsigned int actuator; hrtimer_cancel(&bfqd->idle_slice_timer); spin_lock_irq(&bfqd->lock); - list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) + list_for_each_entry_mutable(bfqq, &bfqd->idle_list, bfqq_list) bfq_deactivate_bfqq(bfqd, bfqq, false, false); spin_unlock_irq(&bfqd->lock); diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 3093c1c03902..ced900019f2e 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -997,7 +997,7 @@ static void __blkcg_rstat_flush(struct blkcg *blkcg, int cpu) { struct llist_head *lhead = per_cpu_ptr(blkcg->lhead, cpu); struct llist_node *lnode; - struct blkg_iostat_set *bisc, *next_bisc; + struct blkg_iostat_set *bisc; unsigned long flags; rcu_read_lock(); @@ -1017,17 +1017,17 @@ static void __blkcg_rstat_flush(struct blkcg *blkcg, int cpu) /* * Iterate only the iostat_cpu's queued in the lockless list. */ - llist_for_each_entry_safe(bisc, next_bisc, lnode, lnode) { + llist_for_each_entry_mutable(bisc, lnode, lnode) { struct blkcg_gq *blkg = bisc->blkg; struct blkcg_gq *parent = blkg->parent; struct blkg_iostat cur; unsigned int seq; /* - * Order assignment of `next_bisc` from `bisc->lnode.next` in - * llist_for_each_entry_safe and clearing `bisc->lqueued` for - * avoiding to assign `next_bisc` with new next pointer added - * in blk_cgroup_bio_start() in case of re-ordering. + * Order the iterator's internal `bisc->lnode.next` load before + * clearing `bisc->lqueued`, so the iterator can't pick up a new + * next pointer added in blk_cgroup_bio_start() in case of + * re-ordering. * * The pair barrier is implied in llist_add() in blk_cgroup_bio_start(). */ diff --git a/block/blk-flush.c b/block/blk-flush.c index 403a46c86411..20654c2103f2 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -204,7 +204,7 @@ static enum rq_end_io_ret flush_end_io(struct request *flush_rq, { struct request_queue *q = flush_rq->q; struct list_head *running; - struct request *rq, *n; + struct request *rq; unsigned long flags = 0; struct blk_flush_queue *fq = blk_get_flush_queue(flush_rq->mq_ctx); @@ -243,7 +243,7 @@ static enum rq_end_io_ret flush_end_io(struct request *flush_rq, fq->flush_running_idx ^= 1; /* and push the waiting requests to the next stage */ - list_for_each_entry_safe(rq, n, running, queuelist) { + list_for_each_entry_mutable(rq, running, queuelist) { unsigned int seq = blk_flush_cur_seq(rq); BUG_ON(seq != REQ_FSEQ_PREFLUSH && seq != REQ_FSEQ_POSTFLUSH); diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 563cc7dcf348..2ca18e52bc13 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -1718,7 +1718,7 @@ static void iocg_flush_stat_leaf(struct ioc_gq *iocg, struct ioc_now *now) static void iocg_flush_stat(struct list_head *target_iocgs, struct ioc_now *now) { LIST_HEAD(inner_walk); - struct ioc_gq *iocg, *tiocg; + struct ioc_gq *iocg; /* flush leaves and build inner node walk list */ list_for_each_entry(iocg, target_iocgs, active_list) { @@ -1727,7 +1727,7 @@ static void iocg_flush_stat(struct list_head *target_iocgs, struct ioc_now *now) } /* keep flushing upwards by walking the inner list backwards */ - list_for_each_entry_safe_reverse(iocg, tiocg, &inner_walk, walk_list) { + list_for_each_entry_mutable_reverse(iocg, &inner_walk, walk_list) { iocg_flush_stat_upward(iocg); list_del_init(&iocg->walk_list); } @@ -1848,7 +1848,7 @@ static void transfer_surpluses(struct list_head *surpluses, struct ioc_now *now) { LIST_HEAD(over_hwa); LIST_HEAD(inner_walk); - struct ioc_gq *iocg, *tiocg, *root_iocg; + struct ioc_gq *iocg, *root_iocg; u32 after_sum, over_sum, over_target, gamma; /* @@ -1884,7 +1884,7 @@ static void transfer_surpluses(struct list_head *surpluses, struct ioc_now *now) over_target = 0; } - list_for_each_entry_safe(iocg, tiocg, &over_hwa, walk_list) { + list_for_each_entry_mutable(iocg, &over_hwa, walk_list) { if (over_target) iocg->hweight_after_donation = div_u64((u64)iocg->hweight_after_donation * @@ -2055,7 +2055,7 @@ static void transfer_surpluses(struct list_head *surpluses, struct ioc_now *now) } /* walk list should be dissolved after use */ - list_for_each_entry_safe(iocg, tiocg, &inner_walk, walk_list) + list_for_each_entry_mutable(iocg, &inner_walk, walk_list) list_del_init(&iocg->walk_list); } @@ -2166,9 +2166,9 @@ static void ioc_forgive_debts(struct ioc *ioc, u64 usage_us_sum, int nr_debtors, static int ioc_check_iocgs(struct ioc *ioc, struct ioc_now *now) { int nr_debtors = 0; - struct ioc_gq *iocg, *tiocg; + struct ioc_gq *iocg; - list_for_each_entry_safe(iocg, tiocg, &ioc->active_iocgs, active_list) { + list_for_each_entry_mutable(iocg, &ioc->active_iocgs, active_list) { if (!waitqueue_active(&iocg->waitq) && !iocg->abs_vdebt && !iocg->delay && !iocg_is_idle(iocg)) continue; @@ -2234,7 +2234,7 @@ static int ioc_check_iocgs(struct ioc *ioc, struct ioc_now *now) static void ioc_timer_fn(struct timer_list *timer) { struct ioc *ioc = container_of(timer, struct ioc, timer); - struct ioc_gq *iocg, *tiocg; + struct ioc_gq *iocg; struct ioc_now now; LIST_HEAD(surpluses); int nr_debtors, nr_shortages = 0, nr_lagging = 0; @@ -2378,7 +2378,7 @@ static void ioc_timer_fn(struct timer_list *timer) commit_weights(ioc); /* surplus list should be dissolved after use */ - list_for_each_entry_safe(iocg, tiocg, &surpluses, surplus_list) + list_for_each_entry_mutable(iocg, &surpluses, surplus_list) list_del_init(&iocg->surplus_list); /* diff --git a/block/blk-mq.c b/block/blk-mq.c index 88cb5acc4f39..2daed45ad4e7 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1216,9 +1216,9 @@ EXPORT_SYMBOL_GPL(blk_mq_end_request_batch); static void blk_complete_reqs(struct llist_head *list) { struct llist_node *entry = llist_reverse_order(llist_del_all(list)); - struct request *rq, *next; + struct request *rq; - llist_for_each_entry_safe(rq, next, entry, ipi_list) + llist_for_each_entry_mutable(rq, entry, ipi_list) rq->q->mq_ops->complete(rq); } @@ -4383,14 +4383,14 @@ static int blk_mq_alloc_ctxs(struct request_queue *q) */ void blk_mq_release(struct request_queue *q) { - struct blk_mq_hw_ctx *hctx, *next; + struct blk_mq_hw_ctx *hctx; unsigned long i; queue_for_each_hw_ctx(q, hctx, i) WARN_ON_ONCE(hctx && list_empty(&hctx->hctx_list)); /* all hctx are in .unused_hctx_list now */ - list_for_each_entry_safe(hctx, next, &q->unused_hctx_list, hctx_list) { + list_for_each_entry_mutable(hctx, &q->unused_hctx_list, hctx_list) { list_del_init(&hctx->hctx_list); kobject_put(&hctx->kobj); } diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 47052ba21d1b..1dd4901f00f3 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -1686,10 +1686,10 @@ static void tg_cancel_writeback_bios(struct throtl_grp *tg, tg->flags |= THROTL_TG_CANCELING; for (rw = READ; rw <= WRITE; rw++) { - struct throtl_qnode *qn, *tmp; + struct throtl_qnode *qn; unsigned int nr_bios = 0; - list_for_each_entry_safe(qn, tmp, &sq->queued[rw], node) { + list_for_each_entry_mutable(qn, &sq->queued[rw], node) { struct bio *bio; while ((bio = bio_list_pop(&qn->bios_iops))) { diff --git a/block/kyber-iosched.c b/block/kyber-iosched.c index 971818bcdc9d..1a509666b861 100644 --- a/block/kyber-iosched.c +++ b/block/kyber-iosched.c @@ -578,9 +578,9 @@ static void kyber_insert_requests(struct blk_mq_hw_ctx *hctx, blk_insert_t flags) { struct kyber_hctx_data *khd = hctx->sched_data; - struct request *rq, *next; + struct request *rq; - list_for_each_entry_safe(rq, next, rq_list, queuelist) { + list_for_each_entry_mutable(rq, rq_list, queuelist) { unsigned int sched_domain = kyber_sched_domain(rq->cmd_flags); struct kyber_ctx_queue *kcq = &khd->kcqs[rq->mq_ctx->index_hw[hctx->type]]; struct list_head *head = &kcq->rq_list[sched_domain]; diff --git a/block/partitions/ldm.c b/block/partitions/ldm.c index c0bdcae58a3e..459f72f2148a 100644 --- a/block/partitions/ldm.c +++ b/block/partitions/ldm.c @@ -1285,11 +1285,11 @@ static bool ldm_frag_add (const u8 *data, int size, struct list_head *frags) */ static void ldm_frag_free (struct list_head *list) { - struct list_head *item, *tmp; + struct list_head *item; BUG_ON (!list); - list_for_each_safe (item, tmp, list) + list_for_each_mutable(item, list) kfree (list_entry (item, struct frag, list)); } @@ -1400,11 +1400,11 @@ static bool ldm_get_vblks(struct parsed_partitions *state, unsigned long base, */ static void ldm_free_vblks (struct list_head *lh) { - struct list_head *item, *tmp; + struct list_head *item; BUG_ON (!lh); - list_for_each_safe (item, tmp, lh) + list_for_each_mutable(item, lh) kfree (list_entry (item, struct vblk, list)); } diff --git a/block/sed-opal.c b/block/sed-opal.c index 79b290d9458a..5bf9ebce8452 100644 --- a/block/sed-opal.c +++ b/block/sed-opal.c @@ -2573,10 +2573,10 @@ static int check_opal_support(struct opal_dev *dev) static void clean_opal_dev(struct opal_dev *dev) { - struct opal_suspend_data *suspend, *next; + struct opal_suspend_data *suspend; mutex_lock(&dev->dev_lock); - list_for_each_entry_safe(suspend, next, &dev->unlk_lst, node) { + list_for_each_entry_mutable(suspend, &dev->unlk_lst, node) { list_del(&suspend->node); kfree(suspend); } diff --git a/include/linux/list.h b/include/linux/list.h index 09d979976b3b..1081def7cea9 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -763,28 +764,72 @@ static inline void list_splice_tail_init(struct list_head *list, #define list_for_each_prev(pos, head) \ for (pos = (head)->prev; !list_is_head(pos, (head)); pos = pos->prev) -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. +/* + * list_for_each_safe is an old interface, use list_for_each_mutable instead. */ #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; \ !list_is_head(pos, (head)); \ pos = n, n = pos->next) +#define __list_for_each_mutable_internal(pos, tmp, head) \ + for (typeof(pos) tmp = (pos = (head)->next)->next; \ + !list_is_head(pos, (head)); \ + pos = tmp, tmp = pos->next) + +#define __list_for_each_mutable1(pos, head) \ + __list_for_each_mutable_internal(pos, __UNIQUE_ID(next), head) + +#define __list_for_each_mutable2(pos, next, head) \ + list_for_each_safe(pos, next, head) + /** - * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry + * list_for_each_mutable - iterate over a list safe against entry removal * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. + * @...: either (head) or (next, head) + * + * next: another &struct list_head to use as optional temporary storage. + * The temporary cursor is internal unless explicitly supplied by + * the caller. + * head: the head for your list. + */ +#define list_for_each_mutable(pos, ...) \ + CONCATENATE(__list_for_each_mutable, COUNT_ARGS(__VA_ARGS__)) \ + (pos, __VA_ARGS__) + +/* + * list_for_each_prev_safe is an old interface, use list_for_each_prev_mutable instead. */ #define list_for_each_prev_safe(pos, n, head) \ for (pos = (head)->prev, n = pos->prev; \ !list_is_head(pos, (head)); \ pos = n, n = pos->prev) +#define __list_for_each_prev_mutable_internal(pos, tmp, head) \ + for (typeof(pos) tmp = (pos = (head)->prev)->prev; \ + !list_is_head(pos, (head)); \ + pos = tmp, tmp = pos->prev) + +#define __list_for_each_prev_mutable1(pos, head) \ + __list_for_each_prev_mutable_internal(pos, __UNIQUE_ID(prev), head) + +#define __list_for_each_prev_mutable2(pos, prev, head) \ + list_for_each_prev_safe(pos, prev, head) + +/** + * list_for_each_prev_mutable - iterate over a list backwards safe against entry removal + * @pos: the &struct list_head to use as a loop cursor. + * @...: either (head) or (prev, head) + * + * prev: another &struct list_head to use as optional temporary storage. + * The temporary cursor is internal unless explicitly supplied by + * the caller. + * head: the head for your list. + */ +#define list_for_each_prev_mutable(pos, ...) \ + CONCATENATE(__list_for_each_prev_mutable, COUNT_ARGS(__VA_ARGS__)) \ + (pos, __VA_ARGS__) + /** * list_count_nodes - count nodes in the list * @head: the head for your list. @@ -895,12 +940,8 @@ static inline size_t list_count_nodes(struct list_head *head) for (; !list_entry_is_head(pos, head, member); \ pos = list_prev_entry(pos, member)) -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_head within the struct. +/* + * list_for_each_entry_safe is an old interface, use list_for_each_entry_mutable instead. */ #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member), \ @@ -908,15 +949,36 @@ static inline size_t list_count_nodes(struct list_head *head) !list_entry_is_head(pos, head, member); \ pos = n, n = list_next_entry(n, member)) +#define __list_for_each_entry_mutable_internal(pos, tmp, head, member) \ + for (typeof(pos) tmp = list_next_entry(pos = \ + list_first_entry(head, typeof(*pos), member), member); \ + !list_entry_is_head(pos, head, member); \ + pos = tmp, tmp = list_next_entry(tmp, member)) + +#define __list_for_each_entry_mutable2(pos, head, member) \ + __list_for_each_entry_mutable_internal(pos, __UNIQUE_ID(next), head, member) + +#define __list_for_each_entry_mutable3(pos, next, head, member) \ + list_for_each_entry_safe(pos, next, head, member) + /** - * list_for_each_entry_safe_continue - continue list iteration safe against removal + * list_for_each_entry_mutable - iterate over a list safe against entry removal * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_head within the struct. + * @...: either (head, member) or (next, head, member) * - * Iterate over list of given type, continuing after current point, - * safe against removal of list entry. + * next: another type * to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * head: the head for your list. + * member: the name of the list_head within the struct. + */ +#define list_for_each_entry_mutable(pos, ...) \ + CONCATENATE(__list_for_each_entry_mutable, COUNT_ARGS(__VA_ARGS__)) \ + (pos, __VA_ARGS__) + +/* + * list_for_each_entry_safe_continue is an old interface, + * use list_for_each_entry_mutable_continue instead. */ #define list_for_each_entry_safe_continue(pos, n, head, member) \ for (pos = list_next_entry(pos, member), \ @@ -924,30 +986,79 @@ static inline size_t list_count_nodes(struct list_head *head) !list_entry_is_head(pos, head, member); \ pos = n, n = list_next_entry(n, member)) +#define __list_for_each_entry_mutable_continue_internal(pos, tmp, head, member) \ + for (typeof(pos) tmp = list_next_entry(pos = \ + list_next_entry(pos, member), member); \ + !list_entry_is_head(pos, head, member); \ + pos = tmp, tmp = list_next_entry(tmp, member)) + +#define __list_for_each_entry_mutable_continue2(pos, head, member) \ + __list_for_each_entry_mutable_continue_internal(pos, \ + __UNIQUE_ID(next), head, member) + +#define __list_for_each_entry_mutable_continue3(pos, next, head, member) \ + list_for_each_entry_safe_continue(pos, next, head, member) + /** - * list_for_each_entry_safe_from - iterate over list from current point safe against removal + * list_for_each_entry_mutable_continue - continue list iteration safe against removal * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_head within the struct. + * @...: either (head, member) or (next, head, member) * - * Iterate over list of given type from current point, safe against - * removal of list entry. + * next: another type * to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * head: the head for your list. + * member: the name of the list_head within the struct. + * + * Iterate over list of given type, continuing after current point, + * safe against removal of list entry. + */ +#define list_for_each_entry_mutable_continue(pos, ...) \ + CONCATENATE(__list_for_each_entry_mutable_continue, \ + COUNT_ARGS(__VA_ARGS__))(pos, __VA_ARGS__) + +/* + * list_for_each_entry_safe_from is an old interface, + * use list_for_each_entry_mutable_from instead. */ #define list_for_each_entry_safe_from(pos, n, head, member) \ for (n = list_next_entry(pos, member); \ !list_entry_is_head(pos, head, member); \ pos = n, n = list_next_entry(n, member)) +#define __list_for_each_entry_mutable_from_internal(pos, tmp, head, member) \ + for (typeof(pos) tmp = list_next_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = tmp, tmp = list_next_entry(tmp, member)) + +#define __list_for_each_entry_mutable_from2(pos, head, member) \ + __list_for_each_entry_mutable_from_internal(pos, \ + __UNIQUE_ID(next), head, member) + +#define __list_for_each_entry_mutable_from3(pos, next, head, member) \ + list_for_each_entry_safe_from(pos, next, head, member) + /** - * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal + * list_for_each_entry_mutable_from - iterate over list from current point safe against removal * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_head within the struct. + * @...: either (head, member) or (next, head, member) * - * Iterate backwards over list of given type, safe against removal - * of list entry. + * next: another type * to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * head: the head for your list. + * member: the name of the list_head within the struct. + * + * Iterate over list of given type from current point, safe against + * removal of list entry. + */ +#define list_for_each_entry_mutable_from(pos, ...) \ + CONCATENATE(__list_for_each_entry_mutable_from, \ + COUNT_ARGS(__VA_ARGS__))(pos, __VA_ARGS__) + +/* + * list_for_each_entry_safe_reverse is an old interface, + * use list_for_each_entry_mutable_reverse instead. */ #define list_for_each_entry_safe_reverse(pos, n, head, member) \ for (pos = list_last_entry(head, typeof(*pos), member), \ @@ -955,6 +1066,37 @@ static inline size_t list_count_nodes(struct list_head *head) !list_entry_is_head(pos, head, member); \ pos = n, n = list_prev_entry(n, member)) +#define __list_for_each_entry_mutable_reverse_internal(pos, tmp, head, member) \ + for (typeof(pos) tmp = list_prev_entry(pos = \ + list_last_entry(head, typeof(*pos), member), member); \ + !list_entry_is_head(pos, head, member); \ + pos = tmp, tmp = list_prev_entry(tmp, member)) + +#define __list_for_each_entry_mutable_reverse2(pos, head, member) \ + __list_for_each_entry_mutable_reverse_internal(pos, \ + __UNIQUE_ID(prev), head, member) + +#define __list_for_each_entry_mutable_reverse3(pos, prev, head, member) \ + list_for_each_entry_safe_reverse(pos, prev, head, member) + +/** + * list_for_each_entry_mutable_reverse - iterate backwards over list safe against removal + * @pos: the type * to use as a loop cursor. + * @...: either (head, member) or (prev, head, member) + * + * prev: another type * to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * head: the head for your list. + * member: the name of the list_head within the struct. + * + * Iterate backwards over list of given type, safe against removal + * of list entry. + */ +#define list_for_each_entry_mutable_reverse(pos, ...) \ + CONCATENATE(__list_for_each_entry_mutable_reverse, \ + COUNT_ARGS(__VA_ARGS__))(pos, __VA_ARGS__) + /** * list_safe_reset_next - reset a stale list_for_each_entry_safe loop * @pos: the loop cursor used in the list_for_each_entry_safe loop @@ -1189,6 +1331,31 @@ static inline void hlist_splice_init(struct hlist_head *from, for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ pos = n) +#define __hlist_for_each_mutable_internal(pos, tmp, head) \ + for (typeof(pos) tmp = (pos = (head)->first) ? pos->next : NULL; \ + pos; \ + pos = tmp, tmp = pos ? pos->next : NULL) + +#define __hlist_for_each_mutable1(pos, head) \ + __hlist_for_each_mutable_internal(pos, __UNIQUE_ID(next), head) + +#define __hlist_for_each_mutable2(pos, next, head) \ + hlist_for_each_safe(pos, next, head) + +/** + * hlist_for_each_mutable - iterate over a hlist safe against entry removal + * @pos: the &struct hlist_node to use as a loop cursor. + * @...: either (head) or (next, head) + * + * next: another &struct hlist_node to use as optional temporary storage. + * The temporary cursor is internal unless explicitly supplied by + * the caller. + * head: the head for your hlist. + */ +#define hlist_for_each_mutable(pos, ...) \ + CONCATENATE(__hlist_for_each_mutable, COUNT_ARGS(__VA_ARGS__)) \ + (pos, __VA_ARGS__) + #define hlist_entry_safe(ptr, type, member) \ ({ typeof(ptr) ____ptr = (ptr); \ ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ @@ -1224,18 +1391,44 @@ static inline void hlist_splice_init(struct hlist_head *from, for (; pos; \ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) -/** - * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: a &struct hlist_node to use as temporary storage - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. +/* + * hlist_for_each_entry_safe is an old interface, use hlist_for_each_entry_mutable instead. */ #define hlist_for_each_entry_safe(pos, n, head, member) \ for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ pos && ({ n = pos->member.next; 1; }); \ pos = hlist_entry_safe(n, typeof(*pos), member)) +#define __hlist_for_each_entry_mutable_internal(pos, tmp, head, member) \ + for (struct hlist_node *tmp = (pos = \ + hlist_entry_safe((head)->first, typeof(*pos), member)) ? \ + pos->member.next : NULL; \ + pos; \ + pos = hlist_entry_safe((tmp), typeof(*pos), member), \ + tmp = pos ? pos->member.next : NULL) + +#define __hlist_for_each_entry_mutable2(pos, head, member) \ + __hlist_for_each_entry_mutable_internal(pos, \ + __UNIQUE_ID(next), head, member) + +#define __hlist_for_each_entry_mutable3(pos, next, head, member) \ + hlist_for_each_entry_safe(pos, next, head, member) + +/** + * hlist_for_each_entry_mutable - iterate over hlist safe against entry removal + * @pos: the type * to use as a loop cursor. + * @...: either (head, member) or (next, head, member) + * + * next: a &struct hlist_node to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * head: the head for your hlist. + * member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_mutable(pos, ...) \ + CONCATENATE(__hlist_for_each_entry_mutable, \ + COUNT_ARGS(__VA_ARGS__))(pos, __VA_ARGS__) + /** * hlist_count_nodes - count nodes in the hlist * @head: the head for your hlist. diff --git a/include/linux/llist.h b/include/linux/llist.h index 8846b7709669..1c6f12411d5e 100644 --- a/include/linux/llist.h +++ b/include/linux/llist.h @@ -49,6 +49,7 @@ */ #include +#include #include #include #include @@ -143,12 +144,33 @@ static inline bool llist_on_list(const struct llist_node *node) #define llist_for_each(pos, node) \ for ((pos) = (node); pos; (pos) = (pos)->next) +/* + * llist_for_each_safe is an old interface, use llist_for_each_mutable instead. + */ +#define llist_for_each_safe(pos, n, node) \ + for ((pos) = (node); (pos) && ((n) = (pos)->next, true); (pos) = (n)) + +#define __llist_for_each_mutable_internal(pos, tmp, node) \ + for (typeof(pos) tmp = ((pos) = (node)) ? (pos)->next : NULL; \ + (pos); \ + (pos) = tmp, tmp = (pos) ? (pos)->next : NULL) + +#define __llist_for_each_mutable1(pos, node) \ + __llist_for_each_mutable_internal(pos, __UNIQUE_ID(next), node) + +#define __llist_for_each_mutable2(pos, next, node) \ + llist_for_each_safe(pos, next, node) + /** - * llist_for_each_safe - iterate over some deleted entries of a lock-less list - * safe against removal of list entry + * llist_for_each_mutable - iterate over some deleted entries of a lock-less list + * safe against removal of list entry * @pos: the &struct llist_node to use as a loop cursor - * @n: another &struct llist_node to use as temporary storage - * @node: the first entry of deleted list entries + * @...: either (node) or (next, node) + * + * next: another &struct llist_node to use as optional temporary storage. + * The temporary cursor is internal unless explicitly supplied by + * the caller. + * node: the first entry of deleted list entries * * In general, some entries of the lock-less list can be traversed * safely only after being deleted from list, so start with an entry @@ -159,8 +181,9 @@ static inline bool llist_on_list(const struct llist_node *node) * you want to traverse from the oldest to the newest, you must * reverse the order by yourself before traversing. */ -#define llist_for_each_safe(pos, n, node) \ - for ((pos) = (node); (pos) && ((n) = (pos)->next, true); (pos) = (n)) +#define llist_for_each_mutable(pos, ...) \ + CONCATENATE(__llist_for_each_mutable, COUNT_ARGS(__VA_ARGS__)) \ + (pos, __VA_ARGS__) /** * llist_for_each_entry - iterate over some deleted entries of lock-less list of given type @@ -182,13 +205,41 @@ static inline bool llist_on_list(const struct llist_node *node) member_address_is_nonnull(pos, member); \ (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member)) +/* + * llist_for_each_entry_safe is an old interface, use llist_for_each_entry_mutable instead. + */ +#define llist_for_each_entry_safe(pos, n, node, member) \ + for (pos = llist_entry((node), typeof(*pos), member); \ + member_address_is_nonnull(pos, member) && \ + (n = llist_entry(pos->member.next, typeof(*n), member), true); \ + pos = n) + +#define __llist_for_each_entry_mutable_internal(pos, tmp, node, member) \ + for (typeof(pos) tmp = ((pos) = llist_entry((node), typeof(*pos), member), \ + member_address_is_nonnull(pos, member) ? \ + llist_entry((pos)->member.next, typeof(*pos), member) : NULL); \ + member_address_is_nonnull(pos, member); \ + (pos) = tmp, tmp = member_address_is_nonnull(pos, member) ? \ + llist_entry((pos)->member.next, typeof(*pos), member) : NULL) + +#define __llist_for_each_entry_mutable2(pos, node, member) \ + __llist_for_each_entry_mutable_internal(pos, __UNIQUE_ID(next), node, member) + +#define __llist_for_each_entry_mutable3(pos, next, node, member) \ + llist_for_each_entry_safe(pos, next, node, member) + /** - * llist_for_each_entry_safe - iterate over some deleted entries of lock-less list of given type - * safe against removal of list entry + * llist_for_each_entry_mutable - iterate over some deleted entries of + * lock-less list of given type safe against + * removal of list entry * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @node: the first entry of deleted list entries. - * @member: the name of the llist_node with the struct. + * @...: either (node, member) or (next, node, member) + * + * next: another type * to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * node: the first entry of deleted list entries. + * member: the name of the llist_node with the struct. * * In general, some entries of the lock-less list can be traversed * safely only after being removed from list, so start with an entry @@ -199,11 +250,9 @@ static inline bool llist_on_list(const struct llist_node *node) * you want to traverse from the oldest to the newest, you must * reverse the order by yourself before traversing. */ -#define llist_for_each_entry_safe(pos, n, node, member) \ - for (pos = llist_entry((node), typeof(*pos), member); \ - member_address_is_nonnull(pos, member) && \ - (n = llist_entry(pos->member.next, typeof(*n), member), true); \ - pos = n) +#define llist_for_each_entry_mutable(pos, ...) \ + CONCATENATE(__llist_for_each_entry_mutable, \ + COUNT_ARGS(__VA_ARGS__))(pos, __VA_ARGS__) /** * llist_empty - tests whether a lock-less list is empty