|
15 | 15 | #include <linux/pagemap.h>
|
16 | 16 | #include <linux/swap.h>
|
17 | 17 | #include <linux/pagewalk.h>
|
| 18 | +#include <linux/backing-dev.h> |
18 | 19 | #include <asm/facility.h>
|
19 | 20 | #include <asm/sections.h>
|
20 | 21 | #include <asm/uv.h>
|
@@ -338,22 +339,75 @@ static int make_folio_secure(struct mm_struct *mm, struct folio *folio, struct u
|
338 | 339 | */
|
339 | 340 | static int s390_wiggle_split_folio(struct mm_struct *mm, struct folio *folio)
|
340 | 341 | {
|
341 |
| - int rc; |
| 342 | + int rc, tried_splits; |
342 | 343 |
|
343 | 344 | lockdep_assert_not_held(&mm->mmap_lock);
|
344 | 345 | folio_wait_writeback(folio);
|
345 | 346 | lru_add_drain_all();
|
346 | 347 |
|
347 |
| - if (folio_test_large(folio)) { |
| 348 | + if (!folio_test_large(folio)) |
| 349 | + return 0; |
| 350 | + |
| 351 | + for (tried_splits = 0; tried_splits < 2; tried_splits++) { |
| 352 | + struct address_space *mapping; |
| 353 | + loff_t lstart, lend; |
| 354 | + struct inode *inode; |
| 355 | + |
348 | 356 | folio_lock(folio);
|
349 | 357 | rc = split_folio(folio);
|
| 358 | + if (rc != -EBUSY) { |
| 359 | + folio_unlock(folio); |
| 360 | + return rc; |
| 361 | + } |
| 362 | + |
| 363 | + /* |
| 364 | + * Splitting with -EBUSY can fail for various reasons, but we |
| 365 | + * have to handle one case explicitly for now: some mappings |
| 366 | + * don't allow for splitting dirty folios; writeback will |
| 367 | + * mark them clean again, including marking all page table |
| 368 | + * entries mapping the folio read-only, to catch future write |
| 369 | + * attempts. |
| 370 | + * |
| 371 | + * While the system should be writing back dirty folios in the |
| 372 | + * background, we obtained this folio by looking up a writable |
| 373 | + * page table entry. On these problematic mappings, writable |
| 374 | + * page table entries imply dirty folios, preventing the |
| 375 | + * split in the first place. |
| 376 | + * |
| 377 | + * To prevent a livelock when trigger writeback manually and |
| 378 | + * letting the caller look up the folio again in the page |
| 379 | + * table (turning it dirty), immediately try to split again. |
| 380 | + * |
| 381 | + * This is only a problem for some mappings (e.g., XFS); |
| 382 | + * mappings that do not support writeback (e.g., shmem) do not |
| 383 | + * apply. |
| 384 | + */ |
| 385 | + if (!folio_test_dirty(folio) || folio_test_anon(folio) || |
| 386 | + !folio->mapping || !mapping_can_writeback(folio->mapping)) { |
| 387 | + folio_unlock(folio); |
| 388 | + break; |
| 389 | + } |
| 390 | + |
| 391 | + /* |
| 392 | + * Ideally, we'd only trigger writeback on this exact folio. But |
| 393 | + * there is no easy way to do that, so we'll stabilize the |
| 394 | + * mapping while we still hold the folio lock, so we can drop |
| 395 | + * the folio lock to trigger writeback on the range currently |
| 396 | + * covered by the folio instead. |
| 397 | + */ |
| 398 | + mapping = folio->mapping; |
| 399 | + lstart = folio_pos(folio); |
| 400 | + lend = lstart + folio_size(folio) - 1; |
| 401 | + inode = igrab(mapping->host); |
350 | 402 | folio_unlock(folio);
|
351 | 403 |
|
352 |
| - if (rc != -EBUSY) |
353 |
| - return rc; |
354 |
| - return -EAGAIN; |
| 404 | + if (unlikely(!inode)) |
| 405 | + break; |
| 406 | + |
| 407 | + filemap_write_and_wait_range(mapping, lstart, lend); |
| 408 | + iput(mapping->host); |
355 | 409 | }
|
356 |
| - return 0; |
| 410 | + return -EAGAIN; |
357 | 411 | }
|
358 | 412 |
|
359 | 413 | int make_hva_secure(struct mm_struct *mm, unsigned long hva, struct uv_cb_header *uvcb)
|
|
0 commit comments