Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp4909659ybv; Mon, 17 Feb 2020 08:15:25 -0800 (PST) X-Google-Smtp-Source: APXvYqy8zkaabhkbGEir+6HreDpV9/zyeRrT7Bu9iZdJL4IX5BisgoKqa+aHGemPzd9425mcfhZI X-Received: by 2002:aca:5f85:: with SMTP id t127mr10831243oib.1.1581956125678; Mon, 17 Feb 2020 08:15:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581956125; cv=none; d=google.com; s=arc-20160816; b=GVrOaOeEPJhiQKnBKG644SFEj/6EJ9b2CQKlJfpUcb3eux/Jc2h203C/2e7o8RgxLI gXIZzlR156+AnE6wYWcihOwFLmWw6ghczl9wq1BHLxy1abRPGlTxOLN1xUwiNxrASjlL 7LfYD1vVVLauOrw3MTpw1M2PKwsw3A3zE7A784Orc/I9XjQQfri3U7dsNw2ErphpOuHO 177TMF5g+Hy+md4FaQWAJXMEY1XJD26tHfirKM9g7q+lZb8lm9U7lXxVNpz63ggkmDT0 +kXy2cg0GFj+At8RZGqpIIwbT/Mtlm3nFP140CqsS+uDsNNVnryR45ufgp+n/KPyi7Ti gF0A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:date:from:dkim-signature; bh=zpUtYYYKt6wzJhX3LmXRTbfSCKjGKcoBGWi5MqIx9/8=; b=PJ2ctMJlS5NT9yCFLx1ch9elqN7FuEaTkRcFVMncFK7o51U9QQUgXNtqjHjwwOJ9Pu bKgXUd2optTJyHYk+JUCS4n91wWIfaCj0V7iLEM0IDWZKqTQdONHUcICxyxzkUxM1x8H 8upG3JooS/8jR/TUvhpj9FKmKoTO77Fz739LfujPtWkwylry83ZLbQNyYhBYPLlg240A HoyYwalRLtjQ6QA4bkJn5oEJiufx0OEby2NqlsDPRPPG4Bae9/qZNTO2tmVPf+oHDHht nel/y1MjkgQSrioHSAn9sIxFf92uyL7EqwGfPMxUDKBr0jVaVTGpWWJWCZlo30dsIP1E 04fA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=dTILJvqb; spf=pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r14si6526542oic.12.2020.02.17.08.15.09; Mon, 17 Feb 2020 08:15:25 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=dTILJvqb; spf=pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729150AbgBQQIj (ORCPT + 99 others); Mon, 17 Feb 2020 11:08:39 -0500 Received: from mail-lf1-f68.google.com ([209.85.167.68]:45729 "EHLO mail-lf1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726420AbgBQQIj (ORCPT ); Mon, 17 Feb 2020 11:08:39 -0500 Received: by mail-lf1-f68.google.com with SMTP id 203so12238887lfa.12 for ; Mon, 17 Feb 2020 08:08:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:date:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=zpUtYYYKt6wzJhX3LmXRTbfSCKjGKcoBGWi5MqIx9/8=; b=dTILJvqb88Mv+kzD4eLuXI67qGD5SLWpy6H1HP55y9s6JH5m3w3TN++A5rp51dEU+5 A80wUeUVvbiZh4TnFsrjcAp0XK82LY5Hi5lrnqvY+Pv55SC44mlCyD26pAlP1ReaoK79 vj9O97rMZifJfCXO29Ej4O+kOEYHgyLvd52Ufpu2lNvpEoOWx4FSj5G7kS4Lusrb2Meb t0i+/IOaA5p65vzVM5jOnjW+VoSpBWBy2JMadEz+fg7aU7/EbxA2squxzA1HA1GD3RFw wJWL25lGnJ/WNZ9YSSsgXSVZtAnfikhslMFZXCQ2e+JbGBehRwtgDBWMGh2JpMAdiEpf nEsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:date:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=zpUtYYYKt6wzJhX3LmXRTbfSCKjGKcoBGWi5MqIx9/8=; b=kYSWVq1cb3SJZDJ9LTipZV5NKEP2/3AG9ONJAJ0lfpBbyHKiZMZEZyM3MDGjJEzyXa 6ni12XyETIsnVTHeiHP8p5y7k2U0q/p+payYrcA+z5s08NW+qtbiLbnpZPo+OtM+mpRI KWWpaHoKJOqM2sqIjVpCXKKE6zzjyS48UAzbh1U2Qw+7AdTBvkB2eRJrt9m2c4N0xDac 3rY3hDlxYQg3fJrPRShRbPC5XTe+k0aVziuVGQZ8IJMH1tiqxDdhvXiv7ZXILwFBiJRr c9hiBe8HEeiZ9aa5cmpPtznTrgcA6ihUurKXGXg+dW/su222a7D7Xc8QFa2bgEtHrD8o eheg== X-Gm-Message-State: APjAAAUW3aSN9MIdiawYJ4R2ra0JyoxMPnhvUR/ggTdlq+d171Q5iJ2B W2oyPekdeCsS5O9jdPKM0Fo= X-Received: by 2002:a19:7d04:: with SMTP id y4mr8398784lfc.111.1581955716074; Mon, 17 Feb 2020 08:08:36 -0800 (PST) Received: from pc636 ([37.139.158.167]) by smtp.gmail.com with ESMTPSA id y7sm593496lfk.83.2020.02.17.08.08.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 08:08:35 -0800 (PST) From: Uladzislau Rezki X-Google-Original-From: Uladzislau Rezki Date: Mon, 17 Feb 2020 17:08:27 +0100 To: "Paul E. McKenney" , Joel Fernandes , "Theodore Y. Ts'o" Cc: "Theodore Y. Ts'o" , Ext4 Developers List , Suraj Jitindar Singh , Uladzislau Rezki , Joel Fernandes Subject: Re: [PATCH RFC] ext4: fix potential race between online resizing and write operations Message-ID: <20200217160827.GA5685@pc636> References: <20200215233817.GA670792@mit.edu> <20200216121246.GG2935@paulmck-ThinkPad-P72> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200216121246.GG2935@paulmck-ThinkPad-P72> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Hello, Joel, Paul, Ted. > > Good point! > > Now that kfree_rcu() is on its way to being less of a hack deeply > entangled into the bowels of RCU, this might be fairly easy to implement. > It might well be simply a matter of a function pointer and a kvfree_rcu() > API. Adding Uladzislau Rezki and Joel Fernandez on CC for their thoughts. > I think it makes sense. For example i see there is a similar demand in the mm/list_lru.c too. As for implementation, it will not be hard, i think. The easiest way is to inject kvfree() support directly into existing kfree_call_rcu() logic(probably will need to rename that function), i.e. to free vmalloc() allocations only in "emergency path" by just calling kvfree(). So that function in its turn will figure out if it is _vmalloc_ address or not and trigger corresponding "free" path. Just an example: diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 75a2eded7aa2..0c4af5d0e3f8 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -806,6 +806,11 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) kfree_call_rcu(head, (rcu_callback_t)(unsigned long)(offset)); \ } while (0) +#define __kvfree_rcu(head, offset) \ + do { \ + kfree_call_rcu(head, (rcu_callback_t)(unsigned long)(offset)); \ + } while (0) + /** * kfree_rcu() - kfree an object after a grace period. * @ptr: pointer to kfree @@ -840,6 +845,14 @@ do { \ __kfree_rcu(&((___p)->rhf), offsetof(typeof(*(ptr)), rhf)); \ } while (0) +#define kvfree_rcu_my(ptr, rhf) \ +do { \ + typeof (ptr) ___p = (ptr); \ + \ + if (___p) \ + __kvfree_rcu(&((___p)->rhf), offsetof(typeof(*(ptr)), rhf)); \ +} while (0) + /* * Place this after a lock-acquisition primitive to guarantee that * an UNLOCK+LOCK pair acts as a full barrier. This guarantee applies diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 394a83bd7ff4..1a05bb44951b 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -2783,11 +2783,10 @@ static void kfree_rcu_work(struct work_struct *work) rcu_lock_acquire(&rcu_callback_map); trace_rcu_invoke_kfree_callback(rcu_state.name, head, offset); - if (!WARN_ON_ONCE(!__is_kfree_rcu_offset(offset))) - kfree((void *)head - offset); + kvfree((void *)head - offset); - rcu_lock_release(&rcu_callback_map); - cond_resched_tasks_rcu_qs(); + rcu_lock_release(&rcu_callback_map); + cond_resched_tasks_rcu_qs(); } } @@ -2964,7 +2963,8 @@ void kfree_call_rcu(struct rcu_head *head, rcu_callback_t func) * Under high memory pressure GFP_NOWAIT can fail, * in that case the emergency path is maintained. */ - if (unlikely(!kfree_call_rcu_add_ptr_to_bulk(krcp, head, func))) { + if (is_vmalloc_addr((void *) head - (unsigned long) func) || + unlikely(!kfree_call_rcu_add_ptr_to_bulk(krcp, head, func))) { head->func = func; head->next = krcp->head; krcp->head = head; How to use it: struct test_kvfree_rcu { unsigned char array[PAGE_SIZE * 2]; struct rcu_head rcu; }; struct test_kvfree_rcu *p; p = vmalloc(sizeof(struct test_kvfree_rcu)); kvfree_rcu_my((struct test_kvfree_rcu *) p, rcu); Any thoughts? Thank you! -- Vlad Rezki