]> xenbits.xensource.com Git - seabios.git/commitdiff
Another fix for hlist_for_each_entry_safe.
authorKevin O'Connor <kevin@koconnor.net>
Fri, 14 Jun 2013 01:24:14 +0000 (21:24 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Fri, 14 Jun 2013 01:24:14 +0000 (21:24 -0400)
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 <kevin@koconnor.net>
src/boot.c
src/list.h
src/pciinit.c
src/pmm.c

index 6286e3cd245e372e404fa10c1d628022302939c0..2fce315c9838eed9161ad18ece9e86522bd5d4fe 100644 (file)
@@ -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)
index 0f0909bbc2544fb9e684b3e983d1da71d86381de..de656b9d6c21538f0366b3ba3d74db92795b3810 100644 (file)
@@ -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)
index 446dddf01facacd5c3ec0c2f5287a0d4dac6d3d1..1943e644c1822be2e0be22392b1871ff032a3430 100644 (file)
@@ -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)
index da972832a29f7453f5260656a9c06f87ddb8e79b..8f993fd104f0b0befc8a6f9f181ab28fade5a67a 100644 (file)
--- 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;
     }