On 11/9/2018 8:13 PM, Pavel Tatashin wrote:
On 18-11-05 13:20:01, Alexander Duyck wrote:
+static unsigned long __next_pfn_valid_range(unsigned long *i,
+                                           unsigned long end_pfn)
  {
-       if (!pfn_valid_within(pfn))
-               return false;
-       if (!(pfn & (pageblock_nr_pages - 1)) && !pfn_valid(pfn))
-               return false;
-       return true;
+       unsigned long pfn = *i;
+       unsigned long count;
+
+       while (pfn < end_pfn) {
+               unsigned long t = ALIGN(pfn + 1, pageblock_nr_pages);
+               unsigned long pageblock_pfn = min(t, end_pfn);
+
+#ifndef CONFIG_HOLES_IN_ZONE
+               count = pageblock_pfn - pfn;
+               pfn = pageblock_pfn;
+               if (!pfn_valid(pfn))
+                       continue;
+#else
+               for (count = 0; pfn < pageblock_pfn; pfn++) {
+                       if (pfn_valid_within(pfn)) {
+                               count++;
+                               continue;
+                       }
+
+                       if (count)
+                               break;
+               }
+
+               if (!count)
+                       continue;
+#endif
+               *i = pfn;
+               return count;
+       }
+
+       return 0;
  }
+#define for_each_deferred_pfn_valid_range(i, start_pfn, end_pfn, pfn, count) \
+       for (i = (start_pfn),                                                \
+            count = __next_pfn_valid_range(&i, (end_pfn));              \
+            count && ({ pfn = i - count; 1; });                             \
+            count = __next_pfn_valid_range(&i, (end_pfn)))

Can this be improved somehow? It took me a while to understand this
piece of code. i is actually end of block, and not an index by PFN, ({pfn = i - 
count; 1;}) is
simply hard to parse. Why can't we make __next_pfn_valid_range() to
return both end and a start of a block?

One thing I could do is flip the direction and work from the end to the start. If I did that then 'i' and 'pfn' would be the same value and I wouldn't have to do the subtraction. If that works for you I could probably do that and it may actually be more efficient.

Otherwise I could probably pass pfn as a reference, and compute it in the case where count is non-zero.

The rest is good:

Reviewed-by: Pavel Tatashin <pasha.tatas...@soleen.com>

Thank you,
Pasha

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

Reply via email to