From owner-freebsd-mips@FreeBSD.ORG Fri Aug 10 17:50:59 2012 Return-Path: Delivered-To: freebsd-mips@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4C59C106566B for ; Fri, 10 Aug 2012 17:50:59 +0000 (UTC) (envelope-from juli@clockworksquid.com) Received: from mail-wg0-f50.google.com (mail-wg0-f50.google.com [74.125.82.50]) by mx1.freebsd.org (Postfix) with ESMTP id D02CD8FC2A for ; Fri, 10 Aug 2012 17:50:58 +0000 (UTC) Received: by wgbds11 with SMTP id ds11so1526981wgb.31 for ; Fri, 10 Aug 2012 10:50:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date :x-google-sender-auth:message-id:subject:to:cc:content-type :x-gm-message-state; bh=NoXBAJ9VvM/wbkl3Nj5Dvo8FqS+G7CIG/YMcTSvXHww=; b=pPHydzzS2hcOW2iFiN/X4lz8DFXI8ToCGtg+cjtncDT4z8234axfeP+OoD7Izn33gW 6FW6SsX3nzfY6kUaBv5oYhMLlH+ou0jIrtIGPNJz2TEVpDmw7jF62ZgFgvZ5lXlRcImH duqftl60FPTLVHt8JWb3zTn7Y0I2DvLXDKTk7tb++hh6TitNXBOdPQN51U/F9nsha/hX zFb9kNozKrfhzuIUTkT98DUDrbiOfQCS706M6khkrZUaHAw7loBZC2VNcYYza+SpPCeB /NQmPsQluT4ujtTeW68aqHDHKY9S2vbhNmejnZESqXtRMRyq2QDILwqaTvbU5WKE+YbI U9Pg== Received: by 10.216.134.169 with SMTP id s41mr1948618wei.183.1344621052422; Fri, 10 Aug 2012 10:50:52 -0700 (PDT) MIME-Version: 1.0 Sender: juli@clockworksquid.com Received: by 10.223.157.76 with HTTP; Fri, 10 Aug 2012 10:50:23 -0700 (PDT) In-Reply-To: References: From: Juli Mallett Date: Fri, 10 Aug 2012 10:50:23 -0700 X-Google-Sender-Auth: f3HKUZ76VsSfaf9Yvkagn5N1gUo Message-ID: To: Paul Ambrose Content-Type: text/plain; charset=UTF-8 X-Gm-Message-State: ALoCoQkgnfe26UkafJV3tOnhBt+EioOqbB6erGlZMSImmjJBuiC7EC4wEBg0UG9kw2ead0fykiif Cc: freebsd-mips@freebsd.org Subject: Re: tlb.c tlb_invalidate_all_user simplified X-BeenThere: freebsd-mips@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting FreeBSD to MIPS List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Aug 2012 17:50:59 -0000 Actually, tlb_invalidate_all_user is beneath the pmap layer, and checks for a NULL pmap are useful here because tlb_invalidate_all_user may be passed a NULL pmap by the caller deliberately. When a NULL pmap is passed, the behavior is changed: rather than ejecting from the TLB any entries which belong to a specific user pmap, it ejects all entries from the pmap that do not belong to the kernel. This is necessary because user address spaces are partitioned within the (shared) TLB by something called an Address Space ID (ASID). We allocate these linearly and keep a generation count to know whether one is currently valid. (This way we can avoid removing entries owned by a task from the TLB during most context switches.) That is, to know whether a given pmap already has a valid ASID assigned to it. Because the ASID field is 8 bits, we must increment that generation count every time we allocate our 256th (actually 255th since ASID 0 is reserved) ASID, and know that any entries in the TLB belonging to tasks from the previous run of ASIDs must be removed. So we call tlb_invalidate_all_user(NULL), which flushes all user entries, without flushing kernel entries and requiring the kernel to reload a bunch of TLB entries just to keep running. I hope that's remotely clear. The need and use of this function touch upon just about every complicated result of the MIPS TLB being software managed. Thanks, Juli. On Fri, Aug 10, 2012 at 4:57 AM, Paul Ambrose wrote: > when I saw this commit, > commit e60abd7cb37fb1b66e8b0c48050aa56732c73e90 > Author: alc > Date: Fri Aug 10 05:00:50 2012 +0000 > > Merge r134393 from amd64/i386: > The machine-independent parts of the virtual memory system always > pass a > valid pmap to the pmap functions that require one. Remove the checks > for > NULL. (These checks have their origins in the Mach pmap.c that was > integrated into BSD. None of the new code written specifically for > FreeBSD included them.) > > according to the description here, pmap should not be null, I think > tlb_invalidate_all_user(struct pmap * pmap), in mips/mips/tlb.c > ---------------------------------------------------------------------------------------------------- > tlb_invalidate_all_user(struct pmap *pmap) > { > register_t asid; > register_t s; > unsigned i; > > s = intr_disable(); > asid = mips_rd_entryhi() & TLBHI_ASID_MASK; > > for (i = mips_rd_wired(); i < num_tlbentries; i++) { > register_t uasid; > > mips_wr_index(i); > tlb_read(); > > uasid = mips_rd_entryhi() & TLBHI_ASID_MASK; > if (pmap == NULL) { > /* > * Invalidate all non-kernel entries. > */ > if (uasid == 0) > continue; > } else { > /* > * Invalidate this pmap's entries. > */ > if (uasid != pmap_asid(pmap)) > continue; > } > tlb_invalidate_one(i); > } > > mips_wr_entryhi(asid); > intr_restore(s); > } > --------------------------------------------------------------------------- > could be simplified like this: > --------------------------------------------------------------------------- > tlb_invalidate_all_user(struct pmap *pmap) > { > register_t asid; > register_t s; > unsigned i; > > s = intr_disable(); > asid = mips_rd_entryhi() & TLBHI_ASID_MASK; > > for (i = mips_rd_wired(); i < num_tlbentries; i++) { > register_t uasid; > > mips_wr_index(i); > tlb_read(); > > uasid = mips_rd_entryhi() & TLBHI_ASID_MASK; > if ((uasid != pmap_asid(pmap)) || (uasid == 0)) > continue; > tlb_invalidate_one(i); > } > > mips_wr_entryhi(asid); > intr_restore(s); > } > > funcntion tlb_invalidate_all_user(struct pmap *pmap) is ONLY called like > this: > pmap_activate -> pmap_alloc_asid -> tlb_invalidate_all_user, I think the > pmap passed > fullfils the assumption. How do you like it ? > _______________________________________________ > freebsd-mips@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-mips > To unsubscribe, send any mail to "freebsd-mips-unsubscribe@freebsd.org"