| From ed130be225046b3c469744265f8c3526deebbafd Mon Sep 17 00:00:00 2001 |
| From: Dan Williams <dan.j.williams@intel.com> |
| Date: Mon, 21 Oct 2019 09:29:20 -0700 |
| Subject: [PATCH] fs/dax: Fix pmd vs pte conflict detection |
| |
| commit 6370740e5f8ef12de7f9a9bf48a0393d202cd827 upstream. |
| |
| Users reported a v5.3 performance regression and inability to establish |
| huge page mappings. A revised version of the ndctl "dax.sh" huge page |
| unit test identifies commit 23c84eb78375 "dax: Fix missed wakeup with |
| PMD faults" as the source. |
| |
| Update get_unlocked_entry() to check for NULL entries before checking |
| the entry order, otherwise NULL is misinterpreted as a present pte |
| conflict. The 'order' check needs to happen before the locked check as |
| an unlocked entry at the wrong order must fallback to lookup the correct |
| order. |
| |
| Reported-by: Jeff Smits <jeff.smits@intel.com> |
| Reported-by: Doug Nelson <doug.nelson@intel.com> |
| Cc: <stable@vger.kernel.org> |
| Fixes: 23c84eb78375 ("dax: Fix missed wakeup with PMD faults") |
| Reviewed-by: Jan Kara <jack@suse.cz> |
| Cc: Jeff Moyer <jmoyer@redhat.com> |
| Cc: Matthew Wilcox (Oracle) <willy@infradead.org> |
| Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> |
| Link: https://lore.kernel.org/r/157167532455.3945484.11971474077040503994.stgit@dwillia2-desk3.amr.corp.intel.com |
| Signed-off-by: Dan Williams <dan.j.williams@intel.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/fs/dax.c b/fs/dax.c |
| index 4f42b852375b..36538f5ecc31 100644 |
| --- a/fs/dax.c |
| +++ b/fs/dax.c |
| @@ -221,10 +221,11 @@ static void *get_unlocked_entry(struct xa_state *xas, unsigned int order) |
| |
| for (;;) { |
| entry = xas_find_conflict(xas); |
| + if (!entry || WARN_ON_ONCE(!xa_is_value(entry))) |
| + return entry; |
| if (dax_entry_order(entry) < order) |
| return XA_RETRY_ENTRY; |
| - if (!entry || WARN_ON_ONCE(!xa_is_value(entry)) || |
| - !dax_is_locked(entry)) |
| + if (!dax_is_locked(entry)) |
| return entry; |
| |
| wq = dax_entry_waitqueue(xas, entry, &ewait.key); |
| -- |
| 2.7.4 |
| |