From 030a58a05e595694dccfa958563103d2f0644231 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Thu, 13 Jun 2013 21:24:14 -0400 Subject: Another fix for hlist_for_each_entry_safe. Although the previous patch does fix hlist_for_each_entry_safe for the common case, it doesn't work correctly when deleting the current node. To fix this, introduce two macros - hlist_for_each_entry_safe for iterating through a list that can be modified, and hlist_for_each_entry_pprev for those users that only need access to the "pprev" pointer. Signed-off-by: Kevin O'Connor --- src/boot.c | 2 +- src/list.h | 8 +++++++- src/pciinit.c | 12 +++++++----- src/pmm.c | 2 +- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/boot.c b/src/boot.c index 6286e3c..2fce315 100644 --- a/src/boot.c +++ b/src/boot.c @@ -324,7 +324,7 @@ bootentry_add(int type, int prio, u32 data, const char *desc) // Add entry in sorted order. struct hlist_node **pprev; struct bootentry_s *pos; - hlist_for_each_entry_safe(pos, pprev, &BootList, node) { + hlist_for_each_entry_pprev(pos, pprev, &BootList, node) { if (be->priority < pos->priority) break; if (be->priority > pos->priority) diff --git a/src/list.h b/src/list.h index 0f0909b..de656b9 100644 --- a/src/list.h +++ b/src/list.h @@ -66,7 +66,13 @@ hlist_add_after(struct hlist_node *n, struct hlist_node *prev) ; pos != container_of(NULL, typeof(*pos), member) \ ; pos = container_of(pos->member.next, typeof(*pos), member)) -#define hlist_for_each_entry_safe(pos, pprev, head, member) \ +#define hlist_for_each_entry_safe(pos, n, head, member) \ + for (pos = container_of((head)->first, typeof(*pos), member) \ + ; pos != container_of(NULL, typeof(*pos), member) \ + && ({ n = pos->member.next; 1; }) \ + ; pos = container_of(n, typeof(*pos), member)) + +#define hlist_for_each_entry_pprev(pos, pprev, head, member) \ for (pprev = &(head)->first \ ; *pprev && ({ pos=container_of(*pprev, typeof(*pos), member); 1; }) \ ; pprev = &(*pprev)->next) diff --git a/src/pciinit.c b/src/pciinit.c index 446dddf..1943e64 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -571,9 +571,9 @@ static u64 pci_region_sum(struct pci_region *r) static void pci_region_migrate_64bit_entries(struct pci_region *from, struct pci_region *to) { - struct hlist_node **pprev, **last = &to->list.first; + struct hlist_node *n, **last = &to->list.first; struct pci_region_entry *entry; - hlist_for_each_entry_safe(entry, pprev, &from->list, node) { + hlist_for_each_entry_safe(entry, n, &from->list, node) { if (!entry->is64) continue; // Move from source list to destination list. @@ -601,11 +601,13 @@ pci_region_create_entry(struct pci_bus *bus, struct pci_device *dev, // Insert into list in sorted order. struct hlist_node **pprev; struct pci_region_entry *pos; - hlist_for_each_entry_safe(pos, pprev, &bus->r[type].list, node) { + hlist_for_each_entry_pprev(pos, pprev, &bus->r[type].list, node) { if (pos->align < align || (pos->align == align && pos->size < size)) break; } hlist_add(&entry->node, pprev); + dprintf(1, "Add %p to %p (bus=%p dev=%p bar=%d size=%llx align=%lld type=%d is64=%d\n" + , entry, pprev, bus, dev, bar, size, align, type, is64); return entry; } @@ -744,9 +746,9 @@ pci_region_map_one_entry(struct pci_region_entry *entry, u64 addr) static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r) { - struct hlist_node **pprev; + struct hlist_node *n; struct pci_region_entry *entry; - hlist_for_each_entry_safe(entry, pprev, &r->list, node) { + hlist_for_each_entry_safe(entry, n, &r->list, node) { u64 addr = r->base; r->base += entry->size; if (entry->bar == -1) diff --git a/src/pmm.c b/src/pmm.c index da97283..8f993fd 100644 --- a/src/pmm.c +++ b/src/pmm.c @@ -86,7 +86,7 @@ addSpace(struct zone_s *zone, void *start, void *end) // Find position to add space struct allocinfo_s *info; struct hlist_node **pprev; - hlist_for_each_entry_safe(info, pprev, &zone->head, node) { + hlist_for_each_entry_pprev(info, pprev, &zone->head, node) { if (info->data < start) break; } -- cgit v1.1