Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754035AbcJNCrf (ORCPT ); Thu, 13 Oct 2016 22:47:35 -0400 Received: from out01.mta.xmission.com ([166.70.13.231]:36511 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752071AbcJNCr3 (ORCPT ); Thu, 13 Oct 2016 22:47:29 -0400 From: ebiederm@xmission.com (Eric W. Biederman) To: Andrey Vagin Cc: Andrei Vagin , Alexander Viro , Linux Containers , linux-fsdevel , LKML References: <1476141965-21429-1-git-send-email-avagin@openvz.org> <877f9c6ui8.fsf@x220.int.ebiederm.org> <87pon458l1.fsf_-_@x220.int.ebiederm.org> <20161013214650.GB19836@outlook.office365.com> Date: Thu, 13 Oct 2016 21:45:00 -0500 In-Reply-To: (Andrey Vagin's message of "Thu, 13 Oct 2016 19:31:22 -0700") Message-ID: <87wphb4pjn.fsf@x220.int.ebiederm.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-XM-SPF: eid=1busWT-0007ES-Ng;;;mid=<87wphb4pjn.fsf@x220.int.ebiederm.org>;;;hst=in02.mta.xmission.com;;;ip=75.170.125.99;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX19ZEAIgv2B/nsyY4kf2+w3xRXnv1loPk4U= X-SA-Exim-Connect-IP: 75.170.125.99 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Report: * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP * 1.5 TR_Symld_Words too many words that have symbols inside * 0.7 XMSubLong Long Subject * 0.0 TVD_RCVD_IP Message was received from an IP address * 0.0 T_TM2_M_HEADER_IN_MSG BODY: No description available. * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa06 1397; Body=1 Fuz1=1 Fuz2=1] X-Spam-DCC: XMission; sa06 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: **;Andrey Vagin X-Spam-Relay-Country: X-Spam-Timing: total 321 ms - load_scoreonly_sql: 0.03 (0.0%), signal_user_changed: 3.3 (1.0%), b_tie_ro: 2.4 (0.7%), parse: 0.77 (0.2%), extract_message_metadata: 19 (5.9%), get_uri_detail_list: 2.5 (0.8%), tests_pri_-1000: 11 (3.4%), tests_pri_-950: 1.11 (0.3%), tests_pri_-900: 0.96 (0.3%), tests_pri_-400: 27 (8.4%), check_bayes: 26 (8.1%), b_tokenize: 8 (2.5%), b_tok_get_all: 9 (2.8%), b_comp_prob: 2.6 (0.8%), b_tok_touch_all: 4.3 (1.3%), b_finish: 0.62 (0.2%), tests_pri_0: 251 (78.2%), check_dkim_signature: 0.48 (0.1%), check_dkim_adsp: 2.6 (0.8%), tests_pri_500: 4.5 (1.4%), rewrite_mail: 0.00 (0.0%) Subject: Re: [RFC][PATCH] mount: In mark_umount_candidates and __propogate_umount visit each mount once X-Spam-Flag: No X-SA-Exim-Version: 4.2.1 (built Thu, 05 May 2016 13:38:54 -0600) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3342 Lines: 84 Andrey Vagin writes: > On Thu, Oct 13, 2016 at 2:46 PM, Andrei Vagin wrote: >> On Thu, Oct 13, 2016 at 02:53:46PM -0500, Eric W. Biederman wrote: >>> >>> Adrei Vagin pointed out that time to executue propagate_umount can go >>> non-linear (and take a ludicrious amount of time) when the mount >>> propogation trees of the mounts to be unmunted by a lazy unmount >>> overlap. >>> >>> Solve this in the most straight forward way possible, by adding a new >>> mount flag to mark parts of the mount propagation tree that have been >>> visited, and use that mark to skip parts of the mount propagation tree >>> that have already been visited during an unmount. This guarantees >>> that each mountpoint in the possibly overlapping mount propagation >>> trees will be visited exactly once. >>> >>> Add the functions propagation_visit_next and propagation_revisit_next >>> to coordinate setting and clearling the visited mount mark. >>> >>> Here is a script to generate such mount tree: >>> $ cat run.sh >>> mount -t tmpfs test-mount /mnt >>> mount --make-shared /mnt >>> for i in `seq $1`; do >>> mkdir /mnt/test.$i >>> mount --bind /mnt /mnt/test.$i >>> done >>> cat /proc/mounts | grep test-mount | wc -l >>> time umount -l /mnt >>> $ for i in `seq 10 16`; do echo $i; unshare -Urm bash ./run.sh $i; done >>> >>> Here are the performance numbers with and without the patch: >>> >>> mounts | before | after (real sec) >>> ----------------------------- >>> 1024 | 0.071 | 0.024 >>> 2048 | 0.184 | 0.030 >>> 4096 | 0.604 | 0.040 >>> 8912 | 4.471 | 0.043 >>> 16384 | 34.826 | 0.082 >>> 32768 | | 0.151 >>> 65536 | | 0.289 >>> 131072 | | 0.659 >>> >>> Andrei Vagin fixing this performance problem is part of the >>> work to fix CVE-2016-6213. >>> >>> Cc: stable@vger.kernel.org >>> Reported-by: Andrei Vagin >>> Signed-off-by: "Eric W. Biederman" >>> --- >>> >>> Andrei can you take a look at this patch and see if you can see any >>> problems. My limited testing suggests this approach does a much better >>> job of solving the problem you were seeing. With the time looking >>> almost linear in the number of mounts now. >> >> I read this patch and I like the idea. >> >> Then I run my tests and one of them doesn't work with this patch. >> I haven't found a reason yet. > >>> + for (m = propagation_visit_next(parent, parent); m; >>> + m = propagation_visit_next(m, parent)) { >>> struct mount *child = __lookup_mnt_last(&m->mnt, >>> mnt->mnt_mountpoint); > > The reason is that this loop is called for different "mnt", but > it is executed only once with this optimization. > > So I think the idea to mark parent will not work, because one parent > can have a few children which have to be umounted. Good catch. So what needs to be marked is the parent mount and mountpoint combination. Which is effectively the child mount. I still think replacing the propagation_next and fixing the propagation walk is the way to go. But it sounds like to make things work the __lookup_mnt_last needs to be moved into the propagation walk function. That doesn't feel to hard. I will have to see what the code looks like. Eric