Pull dax fixes from Dan Williams: "The last of the known regression fixes and fallout from the Xarray conversion of the filesystem-dax implementation. On the path to debugging why the dax memory-failure injection test started failing after the Xarray conversion a couple more fixes for the dax_lock_mapping_entry(), now called dax_lock_page(), surfaced. Those plus the bug that started the hunt are now addressed. These patches have appeared in a -next release with no issues reported. Note the touches to mm/memory-failure.c are just the conversion to the new function signature for dax_lock_page(). Summary: - Fix the Xarray conversion of fsdax to properly handle dax_lock_mapping_entry() in the presense of pmd entries - Fix inode destruction racing a new lock request" * tag 'dax-fixes-4.20-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: dax: Fix unlock mismatch with updated API dax: Don't access a freed inode dax: Check page->mapping isn't NULL
Unified · Split
| @@ -232,6 +232,34 @@ static void *get_unlocked_entry(struct xa_state *xas) · 231 unmodified lines | ||
| 232 | 232 | } |
| 233 | 233 | } |
| 234 | 234 | |
| 235 | +/* | |
| 236 | + * The only thing keeping the address space around is the i_pages lock | |
| 237 | + * (it's cycled in clear_inode() after removing the entries from i_pages) | |
| 238 | + * After we call xas_unlock_irq(), we cannot touch xas->xa. | |
| 239 | + */ | |
| 240 | +static void wait_entry_unlocked(struct xa_state *xas, void *entry) | |
| 241 | +{ | |
| 242 | + struct wait_exceptional_entry_queue ewait; | |
| 243 | + wait_queue_head_t *wq; | |
| 244 | + | |
| 245 | + init_wait(&ewait.wait); | |
| 246 | + ewait.wait.func = wake_exceptional_entry_func; | |
| 247 | + | |
| 248 | + wq = dax_entry_waitqueue(xas, entry, &ewait.key); | |
| 249 | + prepare_to_wait_exclusive(wq, &ewait.wait, TASK_UNINTERRUPTIBLE); | |
| 250 | + xas_unlock_irq(xas); | |
| 251 | + schedule(); | |
| 252 | + finish_wait(wq, &ewait.wait); | |
| 253 | + | |
| 254 | + /* | |
| 255 | + * Entry lock waits are exclusive. Wake up the next waiter since | |
| 256 | + * we aren't sure we will acquire the entry lock and thus wake | |
| 257 | + * the next waiter up on unlock. | |
| 258 | + */ | |
| 259 | + if (waitqueue_active(wq)) | |
| 260 | + __wake_up(wq, TASK_NORMAL, 1, &ewait.key); | |
| 261 | +} | |
| 262 | + | |
| 235 | 263 | static void put_unlocked_entry(struct xa_state *xas, void *entry) |
| 236 | 264 | { |
| 237 | 265 | /* If we were the only waiter woken, wake the next one */ |
| @@ -351,21 +379,21 @@ static struct page *dax_busy_page(void *entry) · 113 unmodified lines | ||
| 351 | 379 | * @page: The page whose entry we want to lock |
| 352 | 380 | * |
| 353 | 381 | * Context: Process context. |
| 354 | − * Return: %true if the entry was locked or does not need to be locked. | |
| 382 | + * Return: A cookie to pass to dax_unlock_page() or 0 if the entry could | |
| 383 | + * not be locked. | |
| 355 | 384 | */ |
| 356 | −bool dax_lock_mapping_entry(struct page *page) | |
| 385 | +dax_entry_t dax_lock_page(struct page *page) | |
| 357 | 386 | { |
| 358 | 387 | XA_STATE(xas, NULL, 0); |
| 359 | 388 | void *entry; |
| 360 | − bool locked; | |
| 361 | 389 | |
| 362 | 390 | /* Ensure page->mapping isn't freed while we look at it */ |
| 363 | 391 | rcu_read_lock(); |
| 364 | 392 | for (;;) { |
| 365 | 393 | struct address_space *mapping = READ_ONCE(page->mapping); |
| 366 | 394 | |
| 367 | − locked = false; | |
| 368 | − if (!dax_mapping(mapping)) | |
| 395 | + entry = NULL; | |
| 396 | + if (!mapping || !dax_mapping(mapping)) | |
| 369 | 397 | break; |
| 370 | 398 | |
| 371 | 399 | /* |
| @@ -375,7 +403,7 @@ bool dax_lock_mapping_entry(struct page *page) · 3 unmodified lines | ||
| 375 | 403 | * otherwise we would not have a valid pfn_to_page() |
| 376 | 404 | * translation. |
| 377 | 405 | */ |
| 378 | − locked = true; | |
| 406 | + entry = (void *)~0UL; | |
| 379 | 407 | if (S_ISCHR(mapping->host->i_mode)) |
| 380 | 408 | break; |
| 381 | 409 | |
| @@ -389,9 +417,7 @@ bool dax_lock_mapping_entry(struct page *page) · 7 unmodified lines | ||
| 389 | 417 | entry = xas_load(&xas); |
| 390 | 418 | if (dax_is_locked(entry)) { |
| 391 | 419 | rcu_read_unlock(); |
| 392 | − entry = get_unlocked_entry(&xas); | |
| 393 | − xas_unlock_irq(&xas); | |
| 394 | − put_unlocked_entry(&xas, entry); | |
| 420 | + wait_entry_unlocked(&xas, entry); | |
| 395 | 421 | rcu_read_lock(); |
| 396 | 422 | continue; |
| 397 | 423 | } |
| @@ -400,23 +426,18 @@ bool dax_lock_mapping_entry(struct page *page) · 2 unmodified lines | ||
| 400 | 426 | break; |
| 401 | 427 | } |
| 402 | 428 | rcu_read_unlock(); |
| 403 | − return locked; | |
| 429 | + return (dax_entry_t)entry; | |
| 404 | 430 | } |
| 405 | 431 | |
| 406 | −void dax_unlock_mapping_entry(struct page *page) | |
| 432 | +void dax_unlock_page(struct page *page, dax_entry_t cookie) | |
| 407 | 433 | { |
| 408 | 434 | struct address_space *mapping = page->mapping; |
| 409 | 435 | XA_STATE(xas, &mapping->i_pages, page->index); |
| 410 | − void *entry; | |
| 411 | 436 | |
| 412 | 437 | if (S_ISCHR(mapping->host->i_mode)) |
| 413 | 438 | return; |
| 414 | 439 | |
| 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); | |
| 440 | + dax_unlock_entry(&xas, (void *)cookie); | |
| 420 | 441 | } |
| 421 | 442 | |
| 422 | 443 | /* |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <linux/radix-tree.h> |
| 8 | 8 | #include <asm/pgtable.h> |
| 9 | 9 | |
| 10 | +typedef unsigned long dax_entry_t; | |
| 11 | + | |
| 10 | 12 | struct iomap_ops; |
| 11 | 13 | struct dax_device; |
| 12 | 14 | struct dax_operations { |
| @@ -88,8 +90,8 @@ int dax_writeback_mapping_range(struct address_space *mapping, · 75 unmodified lines | ||
| 88 | 90 | struct block_device *bdev, struct writeback_control *wbc); |
| 89 | 91 | |
| 90 | 92 | struct page *dax_layout_busy_page(struct address_space *mapping); |
| 91 | −bool dax_lock_mapping_entry(struct page *page); | |
| 92 | −void dax_unlock_mapping_entry(struct page *page); | |
| 93 | +dax_entry_t dax_lock_page(struct page *page); | |
| 94 | +void dax_unlock_page(struct page *page, dax_entry_t cookie); | |
| 93 | 95 | #else |
| 94 | 96 | static inline bool bdev_dax_supported(struct block_device *bdev, |
| 95 | 97 | int blocksize) |
| @@ -122,14 +124,14 @@ static inline int dax_writeback_mapping_range(struct address_space *mapping, · 26 unmodified lines | ||
| 122 | 124 | return -EOPNOTSUPP; |
| 123 | 125 | } |
| 124 | 126 | |
| 125 | −static inline bool dax_lock_mapping_entry(struct page *page) | |
| 127 | +static inline dax_entry_t dax_lock_page(struct page *page) | |
| 126 | 128 | { |
| 127 | 129 | if (IS_DAX(page->mapping->host)) |
| 128 | − return true; | |
| 129 | − return false; | |
| 130 | + return ~0UL; | |
| 131 | + return 0; | |
| 130 | 132 | } |
| 131 | 133 | |
| 132 | −static inline void dax_unlock_mapping_entry(struct page *page) | |
| 134 | +static inline void dax_unlock_page(struct page *page, dax_entry_t cookie) | |
| 133 | 135 | { |
| 134 | 136 | } |
| 135 | 137 | #endif |
| @@ -1161,6 +1161,7 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags, · 1160 unmodified lines | ||
| 1161 | 1161 | LIST_HEAD(tokill); |
| 1162 | 1162 | int rc = -EBUSY; |
| 1163 | 1163 | loff_t start; |
| 1164 | + dax_entry_t cookie; | |
| 1164 | 1165 | |
| 1165 | 1166 | /* |
| 1166 | 1167 | * Prevent the inode from being freed while we are interrogating |
| @@ -1169,7 +1170,8 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags, · 2 unmodified lines | ||
| 1169 | 1170 | * also prevents changes to the mapping of this pfn until |
| 1170 | 1171 | * poison signaling is complete. |
| 1171 | 1172 | */ |
| 1172 | − if (!dax_lock_mapping_entry(page)) | |
| 1173 | + cookie = dax_lock_page(page); | |
| 1174 | + if (!cookie) | |
| 1173 | 1175 | goto out; |
| 1174 | 1176 | |
| 1175 | 1177 | if (hwpoison_filter(page)) { |
| @@ -1220,7 +1222,7 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags, · 44 unmodified lines | ||
| 1220 | 1222 | kill_procs(&tokill, flags & MF_MUST_KILL, !unmap_success, pfn, flags); |
| 1221 | 1223 | rc = 0; |
| 1222 | 1224 | unlock: |
| 1223 | − dax_unlock_mapping_entry(page); | |
| 1225 | + dax_unlock_page(page, cookie); | |
| 1224 | 1226 | out: |
| 1225 | 1227 | /* drop pgmap ref acquired in caller */ |
| 1226 | 1228 | put_dev_pagemap(pgmap); |