diff options
| -rw-r--r-- | drivers/block/xen-blkfront.c | 3 | ||||
| -rw-r--r-- | include/linux/llist.h | 25 |
2 files changed, 27 insertions, 1 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 96e9b00db081..cfdb033c7107 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
| @@ -792,6 +792,7 @@ static void blkif_free(struct blkfront_info *info, int suspend) | |||
| 792 | { | 792 | { |
| 793 | struct llist_node *all_gnts; | 793 | struct llist_node *all_gnts; |
| 794 | struct grant *persistent_gnt; | 794 | struct grant *persistent_gnt; |
| 795 | struct llist_node *n; | ||
| 795 | 796 | ||
| 796 | /* Prevent new requests being issued until we fix things up. */ | 797 | /* Prevent new requests being issued until we fix things up. */ |
| 797 | spin_lock_irq(&info->io_lock); | 798 | spin_lock_irq(&info->io_lock); |
| @@ -804,7 +805,7 @@ static void blkif_free(struct blkfront_info *info, int suspend) | |||
| 804 | /* Remove all persistent grants */ | 805 | /* Remove all persistent grants */ |
| 805 | if (info->persistent_gnts_c) { | 806 | if (info->persistent_gnts_c) { |
| 806 | all_gnts = llist_del_all(&info->persistent_gnts); | 807 | all_gnts = llist_del_all(&info->persistent_gnts); |
| 807 | llist_for_each_entry(persistent_gnt, all_gnts, node) { | 808 | llist_for_each_entry_safe(persistent_gnt, n, all_gnts, node) { |
| 808 | gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); | 809 | gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); |
| 809 | __free_page(pfn_to_page(persistent_gnt->pfn)); | 810 | __free_page(pfn_to_page(persistent_gnt->pfn)); |
| 810 | kfree(persistent_gnt); | 811 | kfree(persistent_gnt); |
diff --git a/include/linux/llist.h b/include/linux/llist.h index a5199f6d0e82..d0ab98f73d38 100644 --- a/include/linux/llist.h +++ b/include/linux/llist.h | |||
| @@ -125,6 +125,31 @@ static inline void init_llist_head(struct llist_head *list) | |||
| 125 | (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member)) | 125 | (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member)) |
| 126 | 126 | ||
| 127 | /** | 127 | /** |
| 128 | * llist_for_each_entry_safe - iterate safely against remove over some entries | ||
| 129 | * of lock-less list of given type. | ||
| 130 | * @pos: the type * to use as a loop cursor. | ||
| 131 | * @n: another type * to use as a temporary storage. | ||
| 132 | * @node: the fist entry of deleted list entries. | ||
| 133 | * @member: the name of the llist_node with the struct. | ||
| 134 | * | ||
| 135 | * In general, some entries of the lock-less list can be traversed | ||
| 136 | * safely only after being removed from list, so start with an entry | ||
| 137 | * instead of list head. This variant allows removal of entries | ||
| 138 | * as we iterate. | ||
| 139 | * | ||
| 140 | * If being used on entries deleted from lock-less list directly, the | ||
| 141 | * traverse order is from the newest to the oldest added entry. If | ||
| 142 | * you want to traverse from the oldest to the newest, you must | ||
| 143 | * reverse the order by yourself before traversing. | ||
| 144 | */ | ||
| 145 | #define llist_for_each_entry_safe(pos, n, node, member) \ | ||
| 146 | for ((pos) = llist_entry((node), typeof(*(pos)), member), \ | ||
| 147 | (n) = (pos)->member.next; \ | ||
| 148 | &(pos)->member != NULL; \ | ||
| 149 | (pos) = llist_entry(n, typeof(*(pos)), member), \ | ||
| 150 | (n) = (&(pos)->member != NULL) ? (pos)->member.next : NULL) | ||
| 151 | |||
| 152 | /** | ||
| 128 | * llist_empty - tests whether a lock-less list is empty | 153 | * llist_empty - tests whether a lock-less list is empty |
| 129 | * @head: the list to test | 154 | * @head: the list to test |
| 130 | * | 155 | * |
