From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754188AbdDLMth (ORCPT ); Wed, 12 Apr 2017 08:49:37 -0400 Received: from mail-eopbgr00101.outbound.protection.outlook.com ([40.107.0.101]:44640 "EHLO EUR02-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753313AbdDLMtc (ORCPT ); Wed, 12 Apr 2017 08:49:32 -0400 Authentication-Results: linux-foundation.org; dkim=none (message not signed) header.d=none;linux-foundation.org; dmarc=none action=none header.from=virtuozzo.com; From: Andrey Ryabinin To: Andrew Morton CC: , Andrey Ryabinin , , , , , , , , , , , , , , Subject: [PATCH v2 1/5] mm/vmalloc: allow to call vfree() in atomic context Date: Wed, 12 Apr 2017 15:49:01 +0300 Message-ID: <20170412124905.25443-2-aryabinin@virtuozzo.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20170412124905.25443-1-aryabinin@virtuozzo.com> References: <20170330102719.13119-1-aryabinin@virtuozzo.com> <20170412124905.25443-1-aryabinin@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: HE1PR0601CA0026.eurprd06.prod.outlook.com (10.166.117.36) To VI1PR0801MB2734.eurprd08.prod.outlook.com (10.166.198.27) X-MS-Office365-Filtering-Correlation-Id: dd7b827b-7dda-488c-eeb8-08d481a2583c X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(201703131423075)(201703031133081);SRVR:VI1PR0801MB2734; X-Microsoft-Exchange-Diagnostics: 1;VI1PR0801MB2734;3:2vL9QuNRxnuz/rN5aYZulon1a/I56MjTIG2daTuMDW4R4f84ReYKhg3p54O+Md/0FjlE8/tybtJPhGqXrIjbrws0puflH+rBj+p1hAt4XRBNr3pYqFPRwt27f+TTS5QtmLeTOBIpAUJ1LX53XKUaEnpP2rJ+BMt8L6rMHmUCpsewCRd/mP7n15fFxMHZjzCF2UnI59ZC7KFzo7YYz6qGlduFE5NnwkaXgRiNyoiJ6035kAPEyAuOFZgJH7xlXZVaR4ZQfOI+jq3KoibiNpH45hlS6fdstjlghiqLkrvTswnieYPdBsD1PXvhCjBAet4keivGkr2RrhN3xLCD7oOFCw==;25:Ljmn5Hw7jRvBKRj7hDhG/+Q0VDVtR+hEzErRuuLN8a3dFGo+dXhgJsHpvPYQbnxDQa2XJXg9QPDELlrPMrz+IH3I95LlrW5c8NCfsSnQIrrJ7WmAEtRfm8/XeC8IsBn2H4pKxnCUz+xxjVHQmJWU9yKom2/L134TVNbBcIh9eq85DpMDGdyEciPCj29+43kxqFlBeXNnP9P1Tsh1M6zEwyB1g+MS/7k/GwBV14/sYdete5hQfiw933y3IkMwRCj+QrjLxYE2VMCRu3IlTKTDQ3PTahgPn/2f25OQfRcDwgJcdtJNyslzkXFtv9NmUYbccijONwUj9fQ1UblFpdTbW6IP1XSHUWLJHNCl/zCLGiMmJx2sTz3e/96EpDk7m8fBdKt8rVyH1CdtTJZ26cEGXLd42uv1PLMpZN6xoNqGtNpB0vqU4gvOnwhTPSlPBqG+I2ugWAonFfE5IebTb/Lz7Q== X-Microsoft-Exchange-Diagnostics: 1;VI1PR0801MB2734;31:E+Wht1hRX9eMgaQVwckpDUce6h42T808fMRvS7AvJAWFSav0265OHNS1Yt6wjHxy+J9/ALyvw2fTWerivuG7m33zMWaLPqsxvOI+TeB98R0MRuKvBC6ZNNueeDwMulz7MPfdl82sJXwDmLP0SDNvnLqobx3YyG9P7BAYIrTRJCmDTEmloCkrwdnV3XuN6/HB7JNAyrPuM/uLqJowG1puYMW9d//UD29y4DIancbka0Qw8cCzBmBG93C/uja6+lR/;20:MX9cn5VsshNEmsZUCQJ7/CLhPJ6MBmHN0f/s8SWmA0xn63uiB54mMUQX/FDB3Ed29oPCZ/PeAnky6rsbezLVXoEwZIQ2wWn4OjRoTFTIv2nAET4IpIszhsKpL9Mc9/6MHVhqCUSoB3Bp8NLkzi5cEiqy1s69jiN34eAdGiCl72hNNiGpLct5uiHljSgr2sQ9leSoNL3V339RhTbaBzqgfAN5WOa5AKvZ+6PaRdDCLLnygtl9VRLQcSsMPIGJkI8X1f8+JH/rEElqPh8B9NUvj3WuLV5H5JDob9H9XZqAWFW2wcdvOzTaogKNsBc8fn3983gm5HTZSffo/495KqKeeB2d7sp1rxongCEVjjxOmn+uvQB8OeDhvLWLO1/i9BOIQHugXNKMr5UxYkIo5N5QwdXHTdTknPRTxB/um7vEJLk= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(61668805478150)(9452136761055); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040450)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(93006095)(93001095)(6041248)(20161123560025)(20161123555025)(201703131423075)(201702281528075)(201703061421075)(20161123562025)(20161123564025)(6072148);SRVR:VI1PR0801MB2734;BCL:0;PCL:0;RULEID:;SRVR:VI1PR0801MB2734; X-Microsoft-Exchange-Diagnostics: 1;VI1PR0801MB2734;4:4Vv+WpJrvepPs/JiXcwsNlJFTz0q9axGDsrchZA/N1EAyJ3R6hsg8jqt8aOhFuTr4PoRsnZBf7FZcY1CflFmzI1MFr+dVoY4cz9lPAhR8QGGsN045kj46Lp+L0180brAv8liXYOFHxz8f4ghQ4hhKTIbGpU0x3AC+7HkOAM7h8E8pXrwHDlDVVGlNRusYyFLKGW4Cj0hQfq2KP7gOMr9ZS9WLy9lhla49qkbmGXMSlF3Pmcdr0M7mwAJoM84hGjJ3uPMq1w+rNBk+NxvUFEkQAIEmUd5HU4NZThL5U+sTlCxymcsQZcNf8OV1cPLNkhUy9tQ15yx0w/NCZf+hnwkUrz9x7rn3yp42ps9besK1Iz+/pkFHdGjCjq8gAOVePTw7BjHy50TEJYwMZrnzH4hOjIqQafhLzIMKcmPT2R3D50/URe2FK20hniqbjYtcIg6g+/29TAz8qSzTrKnK6BhbGIFMOVzNFriapmeGELFckwBOgCsiMqjNmxgcnvy6JpLRlcjEFgiLSLJPAAsOuNwcYhT02PqTR/y/Wrk2fHu7gGznmw/To9InSATlQI53CFqzmrx+Wf4beG7I7+H1f6KdUBwjt5YYXm7I03+K0z8hWmGQ64ex8mllAOfaW5jrVwYXhUqxFj691X3vl7P/lBRc4/myOMSVqGszTCiS48bG4MYyr2eoCgmYnUcinPEv+fhcHRZ02TXqeWEKA0Wv9c0CxSO6AJT6mWyahUwPcoH10UpZoPlR5pd4BS3dhcM5YhWdO7QceRaLi7QXUe49tywBRHAhQhudBifNfr1z2V1JLQ= X-Forefront-PRVS: 027578BB13 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(979002)(6069001)(6009001)(39400400002)(39410400002)(39830400002)(39450400003)(42186005)(25786009)(53416004)(3846002)(33646002)(6116002)(76506005)(305945005)(50466002)(53936002)(4326008)(86362001)(8676002)(5003940100001)(38730400002)(2950100002)(1076002)(6916009)(2906002)(50226002)(189998001)(110136004)(48376002)(6666003)(6486002)(5660300001)(6512007)(36756003)(54906002)(6506006)(7416002)(81166006)(50986999)(76176999)(7736002)(47776003)(66066001)(969003)(989001)(999001)(1009001)(1019001);DIR:OUT;SFP:1102;SCL:1;SRVR:VI1PR0801MB2734;H:localhost.sw.ru;FPR:;SPF:None;MLV:ovrnspm;PTR:InfoNoRecords;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;VI1PR0801MB2734;23:wlTCRlMpYn+D/VslZ8sojbCORiun/8Cdnq7x5e2?= =?us-ascii?Q?9i9Mk5hYWTcA3MDsBL2TCFq2EZBnjmo+1yItMiAqRpZKSl+fJ1dZQbPhy0pZ?= =?us-ascii?Q?eDa906LjlRGtKKZ6/IHnuZJy+LIAPo8TF+XufIk12m5GPVNtk1KP05pf10Rv?= =?us-ascii?Q?vf/i99CV0Peztmo3mwGwELnVZN369FXJBCVN8qV0h4JCtC7BHKZeBpMB2QWi?= =?us-ascii?Q?1YdtWhN8Se8OofNiplkYN0uT7MsOx96Xz/8CyqxqbqPOW9S5LP32i8RjOu33?= =?us-ascii?Q?24UMN6LTep/5sJRwwB8hcmHL7E41IiCOuCzpJhRcgRhUBB9Vn4HX741PpHwW?= =?us-ascii?Q?7YybljSzHnjZVFRS6X9ZoituyJmnFjfBtqfZB6LQWP0l+HFO7/3+L1GUCaKg?= =?us-ascii?Q?71iySx6HpgmlZyJHrYjGdELSkUxYUcg/0S8/H0ayi9/clCpJR/x1/+IO13Xt?= =?us-ascii?Q?d1e+pBQwy6JthxMKhvMhp62tG5rOtghwsJxM9/KaMDS2HNJEjVuFZyA4VQyM?= =?us-ascii?Q?4pGSFc2b6fzBPtilQW7hLSKkJTuZnxVvXds3z2vKt4Lzo6TDl3kpDSqFPBxs?= =?us-ascii?Q?qXQeICAqq2TuD5C207ovsL5QkWCdciEbs4Ht/6kB0xFlKaasJO/7ANSZow2M?= =?us-ascii?Q?F726OI3oc/21x5LSh5p/02xqYeArOLahjMSxSKIOdEWePpHYqVRz8BNmw61B?= =?us-ascii?Q?Mi4nIzNs85ePzDPZQ6MCcgtldrkiElmwga+NN3d6+Pv3k131zAvieDqfSqda?= =?us-ascii?Q?AhNynDoWfNDTE7cfr0YxHNqHuOmjap6HsJTjWtky9kgmgPuKsCRrGXXXwF07?= =?us-ascii?Q?nCnQX8DeLW3BZx4GXEEVd5MST6/ezNoWg5HxyytSVjpRZttD4yCT9BZ8njOU?= =?us-ascii?Q?yyOJMCagStrIaEwh6Iaci2cMfn8oc2LKqC/sotO3Td1Gxk+qcuwG4vK3khbM?= =?us-ascii?Q?ApVAONjFsWtv6/ICbGTTO3k0f/0bo303pwFuZnPpJ8Co8dDpLI+Wt1aKWfu7?= =?us-ascii?Q?vWCBBg1neLVqmdPlxkugNytqY66n8t1+SMN8YmvPZ2fsnWNsz2qhca0BI0ez?= =?us-ascii?Q?qak3No12CEkE8BGUxU7iZ6+7Kg7iVqlhexOLwxxYyecGepZkfzQTo12Vf3GR?= =?us-ascii?Q?6CZMdvdqJgV4qPvt1leVbt/wRsM/P/opw/JmeQDq23JPnyE89EB/vHC9Q4ce?= =?us-ascii?Q?FJlKCOShjpCsw7lU=3D?= X-Microsoft-Exchange-Diagnostics: 1;VI1PR0801MB2734;6:AUvZwWx6P41XmK4zZJn6RnaTDfnkEu1ryrRsyngkfpx4zVk9akF31xXSUl7H2lYCdxUh++/5r1MFVVrxKvfggdxzpM27gITjipiZGTHMwphfaYdUascL5bDs0uxxyCIUxBzqdhBglSi+8Bu371aWBo7VlZjGz+7h4hJhg2B7ItE08xEoRgRzHcPTZoD9RM7H1QbrNreNT/iDRAX0gfsr+35nhAy8qK6H7wkbvTjLEdRBchzkdDBvE+LXsxbO3Uuifb5n/RrgOtMl9DLmZ+pP0iTlTgePj2pf6H8hixHEQNYxsqk0L4I3TP/KQ1aBjYb9VUyvUWyYfs3cFPPwMCXMdc6hsWQ3oHuPnbfZmekJc14HNOWmv8fLVwaw5QPovztLu7Q2+a1gQx3f/oBRoAOlafqr0X/vzDODL29baisjkBQHvSu6yNNAoTj1BcGsjCaWSgsCjlU/Hu+OtnO43j1eEA==;5:jqtydvO98mpteVdiBTZDKJH1sfoGHQHkTLgxfFlsYr+K80EXULTecAz0xMOK0MlRTcT7/rPxB7hefPJEp/GmhsWQKoQdpl4LVjVpZl2FpWJPx9My2dhPyTxeNPia3tqnIERYcAiFy/ZXrQP0LcS06g==;24:0NGD4VAaOQ09p7tDwdU00PeZ/GYj2V70El7q88/mBbeGUXBbenuNBxP2ky/eAOvJfZ3KT1l+9d94Im9EdQ+5VcAvCqkGO9W52gW5LreYqgA= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;VI1PR0801MB2734;7:cveS0Zcjilg8qIUkl/OgvDscqMuET37qdn7OXMi66OljIzjiNzgSBq2IG/O/+EUJJtY+j4UaAQyV75jvwEA7PLT0xEQr+Goz0hyInJt/iZzN9hdhe5qEe43A10RdJPiF5Elgde+ebH10LSQT004O3cbRFvWwiiTctgdNTZYZdpQ3PkjghEHA46V57HnXcR/HkQiErUkf3mCIt5GRWN2vBO0SsUfN0eEVnXfWsCcutXzu24CveufzkqUFFwcPTvnVzoLSJo+fd5W+iBQBWZE99E+DDvEuI8A0iPnkf3qeZiOW5qtoyGiJ63mV/bVETjRG9BfMzFKk0/Xf4T/CwGJCSg==;20:fjEFG0RsWScZ65A9mkFI+RZuZ87VSsGLs4mtJPG9yzQc3lSL7Cp4aIzf62PrYKNj8ymyj1+nkS5/x+VyOm8r/nInVGyWnatJGYeH++01FRAlu+r9zhLDYw7N2XrKt31yYemT0NPsLd3nGxt5+A+iNeXlKrmwkrfQvca7gRcUc4c= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Apr 2017 12:49:21.4436 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0801MB2734 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit 5803ed292e63 ("mm: mark all calls into the vmalloc subsystem as potentially sleeping") added might_sleep() to remove_vm_area() from vfree(), and commit 763b218ddfaf ("mm: add preempt points into __purge_vmap_area_lazy()") actually made vfree() potentially sleeping. This broke vmwgfx driver which calls vfree() under spin_lock(). BUG: sleeping function called from invalid context at mm/vmalloc.c:1480 in_atomic(): 1, irqs_disabled(): 0, pid: 341, name: plymouthd 2 locks held by plymouthd/341: #0: (drm_global_mutex){+.+.+.}, at: [] drm_release+0x3b/0x3b0 [drm] #1: (&(&tfile->lock)->rlock){+.+...}, at: [] ttm_object_file_release+0x28/0x90 [ttm] Call Trace: dump_stack+0x86/0xc3 ___might_sleep+0x17d/0x250 __might_sleep+0x4a/0x80 remove_vm_area+0x22/0x90 __vunmap+0x2e/0x110 vfree+0x42/0x90 kvfree+0x2c/0x40 drm_ht_remove+0x1a/0x30 [drm] ttm_object_file_release+0x50/0x90 [ttm] vmw_postclose+0x47/0x60 [vmwgfx] drm_release+0x290/0x3b0 [drm] __fput+0xf8/0x210 ____fput+0xe/0x10 task_work_run+0x85/0xc0 exit_to_usermode_loop+0xb4/0xc0 do_syscall_64+0x185/0x1f0 entry_SYSCALL64_slow_path+0x25/0x25 This can be fixed in vmgfx, but it would be better to make vfree() non-sleeping again because we may have other bugs like this one. __purge_vmap_area_lazy() is the only function in the vfree() path that wants to be able to sleep. So it make sense to schedule __purge_vmap_area_lazy() via schedule_work() so it runs only in sleepable context. This will have a minimal effect on the regular vfree() path. since __purge_vmap_area_lazy() is rarely called. Fixes: 5803ed292e63 ("mm: mark all calls into the vmalloc subsystem as potentially sleeping") Reported-by: Tetsuo Handa Signed-off-by: Andrey Ryabinin Reviewed-by: Thomas Hellstrom Acked-by: Michal Hocko Cc: --- mm/vmalloc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 8ef8ea1..1c74b26 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -701,7 +701,7 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) * Kick off a purge of the outstanding lazy areas. Don't bother if somebody * is already purging. */ -static void try_purge_vmap_area_lazy(void) +static void try_purge_vmap_area_lazy(struct work_struct *work) { if (mutex_trylock(&vmap_purge_lock)) { __purge_vmap_area_lazy(ULONG_MAX, 0); @@ -720,6 +720,8 @@ static void purge_vmap_area_lazy(void) mutex_unlock(&vmap_purge_lock); } +static DECLARE_WORK(purge_vmap_work, try_purge_vmap_area_lazy); + /* * Free a vmap area, caller ensuring that the area has been unmapped * and flush_cache_vunmap had been called for the correct range @@ -736,7 +738,7 @@ static void free_vmap_area_noflush(struct vmap_area *va) llist_add(&va->purge_list, &vmap_purge_list); if (unlikely(nr_lazy > lazy_max_pages())) - try_purge_vmap_area_lazy(); + schedule_work(&purge_vmap_work); } /* @@ -1125,7 +1127,6 @@ void vm_unmap_ram(const void *mem, unsigned int count) unsigned long addr = (unsigned long)mem; struct vmap_area *va; - might_sleep(); BUG_ON(!addr); BUG_ON(addr < VMALLOC_START); BUG_ON(addr > VMALLOC_END); @@ -1477,8 +1478,6 @@ struct vm_struct *remove_vm_area(const void *addr) { struct vmap_area *va; - might_sleep(); - va = find_vmap_area((unsigned long)addr); if (va && va->flags & VM_VM_AREA) { struct vm_struct *vm = va->vm; -- 2.10.2 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Andrey Ryabinin To: Andrew Morton CC: , Andrey Ryabinin , , , , , , , , , , , , , , Subject: [PATCH v2 1/5] mm/vmalloc: allow to call vfree() in atomic context Date: Wed, 12 Apr 2017 15:49:01 +0300 Message-ID: <20170412124905.25443-2-aryabinin@virtuozzo.com> In-Reply-To: <20170412124905.25443-1-aryabinin@virtuozzo.com> References: <20170330102719.13119-1-aryabinin@virtuozzo.com> <20170412124905.25443-1-aryabinin@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain Sender: owner-linux-mm@kvack.org List-ID: Commit 5803ed292e63 ("mm: mark all calls into the vmalloc subsystem as potentially sleeping") added might_sleep() to remove_vm_area() from vfree(), and commit 763b218ddfaf ("mm: add preempt points into __purge_vmap_area_lazy()") actually made vfree() potentially sleeping. This broke vmwgfx driver which calls vfree() under spin_lock(). BUG: sleeping function called from invalid context at mm/vmalloc.c:1480 in_atomic(): 1, irqs_disabled(): 0, pid: 341, name: plymouthd 2 locks held by plymouthd/341: #0: (drm_global_mutex){+.+.+.}, at: [] drm_release+0x3b/0x3b0 [drm] #1: (&(&tfile->lock)->rlock){+.+...}, at: [] ttm_object_file_release+0x28/0x90 [ttm] Call Trace: dump_stack+0x86/0xc3 ___might_sleep+0x17d/0x250 __might_sleep+0x4a/0x80 remove_vm_area+0x22/0x90 __vunmap+0x2e/0x110 vfree+0x42/0x90 kvfree+0x2c/0x40 drm_ht_remove+0x1a/0x30 [drm] ttm_object_file_release+0x50/0x90 [ttm] vmw_postclose+0x47/0x60 [vmwgfx] drm_release+0x290/0x3b0 [drm] __fput+0xf8/0x210 ____fput+0xe/0x10 task_work_run+0x85/0xc0 exit_to_usermode_loop+0xb4/0xc0 do_syscall_64+0x185/0x1f0 entry_SYSCALL64_slow_path+0x25/0x25 This can be fixed in vmgfx, but it would be better to make vfree() non-sleeping again because we may have other bugs like this one. __purge_vmap_area_lazy() is the only function in the vfree() path that wants to be able to sleep. So it make sense to schedule __purge_vmap_area_lazy() via schedule_work() so it runs only in sleepable context. This will have a minimal effect on the regular vfree() path. since __purge_vmap_area_lazy() is rarely called. Fixes: 5803ed292e63 ("mm: mark all calls into the vmalloc subsystem as potentially sleeping") Reported-by: Tetsuo Handa Signed-off-by: Andrey Ryabinin Reviewed-by: Thomas Hellstrom Acked-by: Michal Hocko Cc: --- mm/vmalloc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 8ef8ea1..1c74b26 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -701,7 +701,7 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) * Kick off a purge of the outstanding lazy areas. Don't bother if somebody * is already purging. */ -static void try_purge_vmap_area_lazy(void) +static void try_purge_vmap_area_lazy(struct work_struct *work) { if (mutex_trylock(&vmap_purge_lock)) { __purge_vmap_area_lazy(ULONG_MAX, 0); @@ -720,6 +720,8 @@ static void purge_vmap_area_lazy(void) mutex_unlock(&vmap_purge_lock); } +static DECLARE_WORK(purge_vmap_work, try_purge_vmap_area_lazy); + /* * Free a vmap area, caller ensuring that the area has been unmapped * and flush_cache_vunmap had been called for the correct range @@ -736,7 +738,7 @@ static void free_vmap_area_noflush(struct vmap_area *va) llist_add(&va->purge_list, &vmap_purge_list); if (unlikely(nr_lazy > lazy_max_pages())) - try_purge_vmap_area_lazy(); + schedule_work(&purge_vmap_work); } /* @@ -1125,7 +1127,6 @@ void vm_unmap_ram(const void *mem, unsigned int count) unsigned long addr = (unsigned long)mem; struct vmap_area *va; - might_sleep(); BUG_ON(!addr); BUG_ON(addr < VMALLOC_START); BUG_ON(addr > VMALLOC_END); @@ -1477,8 +1478,6 @@ struct vm_struct *remove_vm_area(const void *addr) { struct vmap_area *va; - might_sleep(); - va = find_vmap_area((unsigned long)addr); if (va && va->flags & VM_VM_AREA) { struct vm_struct *vm = va->vm; -- 2.10.2 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oi0-f72.google.com (mail-oi0-f72.google.com [209.85.218.72]) by kanga.kvack.org (Postfix) with ESMTP id 73A896B0390 for ; Wed, 12 Apr 2017 08:49:27 -0400 (EDT) Received: by mail-oi0-f72.google.com with SMTP id d201so20033879oib.23 for ; Wed, 12 Apr 2017 05:49:27 -0700 (PDT) Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00091.outbound.protection.outlook.com. [40.107.0.91]) by mx.google.com with ESMTPS id x68si6324399oif.260.2017.04.12.05.49.26 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 12 Apr 2017 05:49:26 -0700 (PDT) From: Andrey Ryabinin Subject: [PATCH v2 1/5] mm/vmalloc: allow to call vfree() in atomic context Date: Wed, 12 Apr 2017 15:49:01 +0300 Message-ID: <20170412124905.25443-2-aryabinin@virtuozzo.com> In-Reply-To: <20170412124905.25443-1-aryabinin@virtuozzo.com> References: <20170330102719.13119-1-aryabinin@virtuozzo.com> <20170412124905.25443-1-aryabinin@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain Sender: owner-linux-mm@kvack.org List-ID: To: Andrew Morton Cc: linux-kernel@vger.kernel.org, Andrey Ryabinin , stable@vger.kernel.org, penguin-kernel@I-love.SAKURA.ne.jp, mhocko@kernel.org, linux-mm@kvack.org, hpa@zytor.com, chris@chris-wilson.co.uk, hch@lst.de, mingo@elte.hu, jszhang@marvell.com, joelaf@google.com, joaodias@google.com, willy@infradead.org, tglx@linutronix.de, thellstrom@vmware.com Commit 5803ed292e63 ("mm: mark all calls into the vmalloc subsystem as potentially sleeping") added might_sleep() to remove_vm_area() from vfree(), and commit 763b218ddfaf ("mm: add preempt points into __purge_vmap_area_lazy()") actually made vfree() potentially sleeping. This broke vmwgfx driver which calls vfree() under spin_lock(). BUG: sleeping function called from invalid context at mm/vmalloc.c:1480 in_atomic(): 1, irqs_disabled(): 0, pid: 341, name: plymouthd 2 locks held by plymouthd/341: #0: (drm_global_mutex){+.+.+.}, at: [] drm_release+0x3b/0x3b0 [drm] #1: (&(&tfile->lock)->rlock){+.+...}, at: [] ttm_object_file_release+0x28/0x90 [ttm] Call Trace: dump_stack+0x86/0xc3 ___might_sleep+0x17d/0x250 __might_sleep+0x4a/0x80 remove_vm_area+0x22/0x90 __vunmap+0x2e/0x110 vfree+0x42/0x90 kvfree+0x2c/0x40 drm_ht_remove+0x1a/0x30 [drm] ttm_object_file_release+0x50/0x90 [ttm] vmw_postclose+0x47/0x60 [vmwgfx] drm_release+0x290/0x3b0 [drm] __fput+0xf8/0x210 ____fput+0xe/0x10 task_work_run+0x85/0xc0 exit_to_usermode_loop+0xb4/0xc0 do_syscall_64+0x185/0x1f0 entry_SYSCALL64_slow_path+0x25/0x25 This can be fixed in vmgfx, but it would be better to make vfree() non-sleeping again because we may have other bugs like this one. __purge_vmap_area_lazy() is the only function in the vfree() path that wants to be able to sleep. So it make sense to schedule __purge_vmap_area_lazy() via schedule_work() so it runs only in sleepable context. This will have a minimal effect on the regular vfree() path. since __purge_vmap_area_lazy() is rarely called. Fixes: 5803ed292e63 ("mm: mark all calls into the vmalloc subsystem as potentially sleeping") Reported-by: Tetsuo Handa Signed-off-by: Andrey Ryabinin Reviewed-by: Thomas Hellstrom Acked-by: Michal Hocko Cc: --- mm/vmalloc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 8ef8ea1..1c74b26 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -701,7 +701,7 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) * Kick off a purge of the outstanding lazy areas. Don't bother if somebody * is already purging. */ -static void try_purge_vmap_area_lazy(void) +static void try_purge_vmap_area_lazy(struct work_struct *work) { if (mutex_trylock(&vmap_purge_lock)) { __purge_vmap_area_lazy(ULONG_MAX, 0); @@ -720,6 +720,8 @@ static void purge_vmap_area_lazy(void) mutex_unlock(&vmap_purge_lock); } +static DECLARE_WORK(purge_vmap_work, try_purge_vmap_area_lazy); + /* * Free a vmap area, caller ensuring that the area has been unmapped * and flush_cache_vunmap had been called for the correct range @@ -736,7 +738,7 @@ static void free_vmap_area_noflush(struct vmap_area *va) llist_add(&va->purge_list, &vmap_purge_list); if (unlikely(nr_lazy > lazy_max_pages())) - try_purge_vmap_area_lazy(); + schedule_work(&purge_vmap_work); } /* @@ -1125,7 +1127,6 @@ void vm_unmap_ram(const void *mem, unsigned int count) unsigned long addr = (unsigned long)mem; struct vmap_area *va; - might_sleep(); BUG_ON(!addr); BUG_ON(addr < VMALLOC_START); BUG_ON(addr > VMALLOC_END); @@ -1477,8 +1478,6 @@ struct vm_struct *remove_vm_area(const void *addr) { struct vmap_area *va; - might_sleep(); - va = find_vmap_area((unsigned long)addr); if (va && va->flags & VM_VM_AREA) { struct vm_struct *vm = va->vm; -- 2.10.2 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org