Skip to contentSkip to conversation

ext4: a couple writeback path fixes

PATCH Superseded Eric Sandeen 1 participant 6 messages Aug 31, 2010 – Sep 3, 2010 ext4 file system

lore
Share & tools
lore
#0 lore raw

cover ext4: a couple writeback path fixes

I've found a couple small problems in the ext4_da_writepages path;

1) ext4_num_dirty_pages() can continue looping after max_pages is reached
- this leads to wasted cpu cycles during writeback

2) bumping nr_to_write can wrap if we started with LONG_MAX
- Not sure of all ramifications, but nr_to_write = -8 can't be good

-Eric

#1 lore raw

PATCH 1/2] ext4: stop looping in ext4_num_dirty_pages when max_pages reached

Today we simply break out of the inner loop when we have accumulated max_pages; this keeps scanning forwad and doing pagevec_lookup_tag() in the while (!done) loop, this does potentially a lot of work with no net effect.

When we have accumulated max_pages, just clean up and return.

---

fs/ext4/inode.c +4 -2
index 4b8debe..93497f6 100644
@@ -1207,8 +1207,10 @@ static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx,
 				break;
 			idx++;
 			num++;
-			if (num >= max_pages)
-				break;
+			if (num >= max_pages) {
+				pagevec_release(&pvec);
+				return num;
+			}
 		}
 		pagevec_release(&pvec);
 	}
#2 lore raw

PATCH 2/2 ext4: don't bump nr_to_write if LONG_MAX

In reply to Eric Sandeen

In some cases we can reach ext4_da_writepages with wbc->nr_to_write == LONG_MAX, !range_cyclic, and range_whole=1; in this case we will try to bump it up by a factor of 8, which leads to a nr_to_write value of -8.

I think we still get through the logic without changing wbc->nr_to_write because the other tests which would change it don't trip, but it seems dangerous to overflow desired_nr_to_write in the interim, it's not obvious.

---

fs/ext4/inode.c +5 -3
index 93497f6..2e72a4a 100644
@@ -3004,9 +3004,11 @@ static int ext4_da_writepages(struct address_space *mapping,
 	 * sbi->max_writeback_mb_bump whichever is smaller.
 	 */
 	max_pages = sbi->s_max_writeback_mb_bump << (20 - PAGE_CACHE_SHIFT);
-	if (!range_cyclic && range_whole)
-		desired_nr_to_write = wbc->nr_to_write * 8;
-	else
+	if (!range_cyclic && range_whole) {
+		desired_nr_to_write = wbc->nr_to_write;
+		if (desired_nr_to_write != LONG_MAX)
+			desired_nr_to_write *= 8;
+	} else
 		desired_nr_to_write = ext4_num_dirty_pages(inode, index,
 							   max_pages);
 	if (desired_nr_to_write > max_pages)
#3 lore raw

PATCH v2 2/2 ext4: don't bump nr_to_write if LONG_MAX

In some cases we can reach ext4_da_writepages() with wbc->nr_to_write == LONG_MAX, !range_cyclic, and range_whole=1; in this case we will try to bump it up by a factor of 8, which leads to a desired_nr_to_write value of -8.

We still get through the logic without actually changing wbc->nr_to_write because the other tests which would change it don't trip due to the negative value, but it seems dangerous to overflow desired_nr_to_write in the interim, it's not an obvious situation.

---

(V2 minor commit message edits)

fs/ext4/inode.c +5 -3
index 93497f6..2e72a4a 100644
@@ -3004,9 +3004,11 @@ static int ext4_da_writepages(struct address_space *mapping,
 	 * sbi->max_writeback_mb_bump whichever is smaller.
 	 */
 	max_pages = sbi->s_max_writeback_mb_bump << (20 - PAGE_CACHE_SHIFT);
-	if (!range_cyclic && range_whole)
-		desired_nr_to_write = wbc->nr_to_write * 8;
-	else
+	if (!range_cyclic && range_whole) {
+		desired_nr_to_write = wbc->nr_to_write;
+		if (desired_nr_to_write != LONG_MAX)
+			desired_nr_to_write *= 8;
+	} else
 		desired_nr_to_write = ext4_num_dirty_pages(inode, index,
 							   max_pages);
 	if (desired_nr_to_write > max_pages)

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw

Re: [PATCH 2/2 V2] ext4: don't bump nr_to_write if LONG_MAX

Quoted 4 lines · Eric Sandeen

In some cases we can reach ext4_da_writepages() with wbc->nr_to_write == LONG_MAX, !range_cyclic, and range_whole=1; in this case we will try to bump it up by a factor of 8, which leads to a desired_nr_to_write value of -8.

Sorry Ted, hold off on this, it should have been LLONG_MAX of course, and I'm still looking for one other bit of brokennes I see.

The 1/2 patch should be good though.

-Eric

Quoted 41 lines

We still get through the logic without actually changing wbc->nr_to_write because the other tests which would change it don't trip due to the negative value, but it seems dangerous to overflow desired_nr_to_write in the interim, it's not an obvious situation.

---

(V2 minor commit message edits)

fs/ext4/inode.c +5 -4
index 93497f6..2e72a4a 100644
@@ -3004,9 +3004,11 @@ static int ext4_da_writepages(struct address_space *mapping,
 	 * sbi->max_writeback_mb_bump whichever is smaller.
 	 */
 	max_pages = sbi->s_max_writeback_mb_bump << (20 - PAGE_CACHE_SHIFT);
-	if (!range_cyclic && range_whole)
-		desired_nr_to_write = wbc->nr_to_write * 8;
-	else
+	if (!range_cyclic && range_whole) {
+		desired_nr_to_write = wbc->nr_to_write;
+		if (desired_nr_to_write != LONG_MAX)
+			desired_nr_to_write *= 8;
+	} else
 		desired_nr_to_write = ext4_num_dirty_pages(inode, index,
 							   max_pages);
 	if (desired_nr_to_write > max_pages)
 
 
--

To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#5 lore raw
In reply to Eric Sandeen
Quoted 9 lines · Eric Sandeen

I've found a couple small problems in the ext4_da_writepages path;

1) ext4_num_dirty_pages() can continue looping after max_pages is reached
- this leads to wasted cpu cycles during writeback

2) bumping nr_to_write can wrap if we started with LONG_MAX
- Not sure of all ramifications, but nr_to_write = -8 can't be good

-Eric

sigh just nak this whole thing for now, too many errors.

Will resubmit after more careful reading, patching, and testing.

Sorry for the noise.

-Eric