aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dax.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dax.c')
-rw-r--r--fs/dax.c60
1 files changed, 35 insertions, 25 deletions
diff --git a/fs/dax.c b/fs/dax.c
index 616e36ea6aaa..9bcce89ea18e 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -98,12 +98,6 @@ static void *dax_make_entry(pfn_t pfn, unsigned long flags)
98 return xa_mk_value(flags | (pfn_t_to_pfn(pfn) << DAX_SHIFT)); 98 return xa_mk_value(flags | (pfn_t_to_pfn(pfn) << DAX_SHIFT));
99} 99}
100 100
101static void *dax_make_page_entry(struct page *page)
102{
103 pfn_t pfn = page_to_pfn_t(page);
104 return dax_make_entry(pfn, PageHead(page) ? DAX_PMD : 0);
105}
106
107static bool dax_is_locked(void *entry) 101static bool dax_is_locked(void *entry)
108{ 102{
109 return xa_to_value(entry) & DAX_LOCKED; 103 return xa_to_value(entry) & DAX_LOCKED;
@@ -116,12 +110,12 @@ static unsigned int dax_entry_order(void *entry)
116 return 0; 110 return 0;
117} 111}
118 112
119static int dax_is_pmd_entry(void *entry) 113static unsigned long dax_is_pmd_entry(void *entry)
120{ 114{
121 return xa_to_value(entry) & DAX_PMD; 115 return xa_to_value(entry) & DAX_PMD;
122} 116}
123 117
124static int dax_is_pte_entry(void *entry) 118static bool dax_is_pte_entry(void *entry)
125{ 119{
126 return !(xa_to_value(entry) & DAX_PMD); 120 return !(xa_to_value(entry) & DAX_PMD);
127} 121}
@@ -222,9 +216,8 @@ static void *get_unlocked_entry(struct xa_state *xas)
222 ewait.wait.func = wake_exceptional_entry_func; 216 ewait.wait.func = wake_exceptional_entry_func;
223 217
224 for (;;) { 218 for (;;) {
225 entry = xas_load(xas); 219 entry = xas_find_conflict(xas);
226 if (!entry || xa_is_internal(entry) || 220 if (!entry || WARN_ON_ONCE(!xa_is_value(entry)) ||
227 WARN_ON_ONCE(!xa_is_value(entry)) ||
228 !dax_is_locked(entry)) 221 !dax_is_locked(entry))
229 return entry; 222 return entry;
230 223
@@ -255,6 +248,7 @@ static void dax_unlock_entry(struct xa_state *xas, void *entry)
255{ 248{
256 void *old; 249 void *old;
257 250
251 BUG_ON(dax_is_locked(entry));
258 xas_reset(xas); 252 xas_reset(xas);
259 xas_lock_irq(xas); 253 xas_lock_irq(xas);
260 old = xas_store(xas, entry); 254 old = xas_store(xas, entry);
@@ -352,16 +346,27 @@ static struct page *dax_busy_page(void *entry)
352 return NULL; 346 return NULL;
353} 347}
354 348
349/*
350 * dax_lock_mapping_entry - Lock the DAX entry corresponding to a page
351 * @page: The page whose entry we want to lock
352 *
353 * Context: Process context.
354 * Return: %true if the entry was locked or does not need to be locked.
355 */
355bool dax_lock_mapping_entry(struct page *page) 356bool dax_lock_mapping_entry(struct page *page)
356{ 357{
357 XA_STATE(xas, NULL, 0); 358 XA_STATE(xas, NULL, 0);
358 void *entry; 359 void *entry;
360 bool locked;
359 361
362 /* Ensure page->mapping isn't freed while we look at it */
363 rcu_read_lock();
360 for (;;) { 364 for (;;) {
361 struct address_space *mapping = READ_ONCE(page->mapping); 365 struct address_space *mapping = READ_ONCE(page->mapping);
362 366
367 locked = false;
363 if (!dax_mapping(mapping)) 368 if (!dax_mapping(mapping))
364 return false; 369 break;
365 370
366 /* 371 /*
367 * In the device-dax case there's no need to lock, a 372 * In the device-dax case there's no need to lock, a
@@ -370,8 +375,9 @@ bool dax_lock_mapping_entry(struct page *page)
370 * otherwise we would not have a valid pfn_to_page() 375 * otherwise we would not have a valid pfn_to_page()
371 * translation. 376 * translation.
372 */ 377 */
378 locked = true;
373 if (S_ISCHR(mapping->host->i_mode)) 379 if (S_ISCHR(mapping->host->i_mode))
374 return true; 380 break;
375 381
376 xas.xa = &mapping->i_pages; 382 xas.xa = &mapping->i_pages;
377 xas_lock_irq(&xas); 383 xas_lock_irq(&xas);
@@ -382,28 +388,35 @@ bool dax_lock_mapping_entry(struct page *page)
382 xas_set(&xas, page->index); 388 xas_set(&xas, page->index);
383 entry = xas_load(&xas); 389 entry = xas_load(&xas);
384 if (dax_is_locked(entry)) { 390 if (dax_is_locked(entry)) {
391 rcu_read_unlock();
385 entry = get_unlocked_entry(&xas); 392 entry = get_unlocked_entry(&xas);
386 /* Did the page move while we slept? */ 393 xas_unlock_irq(&xas);
387 if (dax_to_pfn(entry) != page_to_pfn(page)) { 394 put_unlocked_entry(&xas, entry);
388 xas_unlock_irq(&xas); 395 rcu_read_lock();
389 continue; 396 continue;
390 }
391 } 397 }
392 dax_lock_entry(&xas, entry); 398 dax_lock_entry(&xas, entry);
393 xas_unlock_irq(&xas); 399 xas_unlock_irq(&xas);
394 return true; 400 break;
395 } 401 }
402 rcu_read_unlock();
403 return locked;
396} 404}
397 405
398void dax_unlock_mapping_entry(struct page *page) 406void dax_unlock_mapping_entry(struct page *page)
399{ 407{
400 struct address_space *mapping = page->mapping; 408 struct address_space *mapping = page->mapping;
401 XA_STATE(xas, &mapping->i_pages, page->index); 409 XA_STATE(xas, &mapping->i_pages, page->index);
410 void *entry;
402 411
403 if (S_ISCHR(mapping->host->i_mode)) 412 if (S_ISCHR(mapping->host->i_mode))
404 return; 413 return;
405 414
406 dax_unlock_entry(&xas, dax_make_page_entry(page)); 415 rcu_read_lock();
416 entry = xas_load(&xas);
417 rcu_read_unlock();
418 entry = dax_make_entry(page_to_pfn_t(page), dax_is_pmd_entry(entry));
419 dax_unlock_entry(&xas, entry);
407} 420}
408 421
409/* 422/*
@@ -445,11 +458,9 @@ static void *grab_mapping_entry(struct xa_state *xas,
445retry: 458retry:
446 xas_lock_irq(xas); 459 xas_lock_irq(xas);
447 entry = get_unlocked_entry(xas); 460 entry = get_unlocked_entry(xas);
448 if (xa_is_internal(entry))
449 goto fallback;
450 461
451 if (entry) { 462 if (entry) {
452 if (WARN_ON_ONCE(!xa_is_value(entry))) { 463 if (!xa_is_value(entry)) {
453 xas_set_err(xas, EIO); 464 xas_set_err(xas, EIO);
454 goto out_unlock; 465 goto out_unlock;
455 } 466 }
@@ -1628,8 +1639,7 @@ dax_insert_pfn_mkwrite(struct vm_fault *vmf, pfn_t pfn, unsigned int order)
1628 /* Did we race with someone splitting entry or so? */ 1639 /* Did we race with someone splitting entry or so? */
1629 if (!entry || 1640 if (!entry ||
1630 (order == 0 && !dax_is_pte_entry(entry)) || 1641 (order == 0 && !dax_is_pte_entry(entry)) ||
1631 (order == PMD_ORDER && (xa_is_internal(entry) || 1642 (order == PMD_ORDER && !dax_is_pmd_entry(entry))) {
1632 !dax_is_pmd_entry(entry)))) {
1633 put_unlocked_entry(&xas, entry); 1643 put_unlocked_entry(&xas, entry);
1634 xas_unlock_irq(&xas); 1644 xas_unlock_irq(&xas);
1635 trace_dax_insert_pfn_mkwrite_no_entry(mapping->host, vmf, 1645 trace_dax_insert_pfn_mkwrite_no_entry(mapping->host, vmf,