From owner-freebsd-ppc@FreeBSD.ORG Sun Mar 1 08:49:46 2015 Return-Path: Delivered-To: freebsd-ppc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 74D2FC13 for ; Sun, 1 Mar 2015 08:49:46 +0000 (UTC) Received: from asp.reflexion.net (outbound-242.asp.reflexion.net [69.84.129.242]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2EBE710F for ; Sun, 1 Mar 2015 08:49:45 +0000 (UTC) Received: (qmail 20203 invoked from network); 1 Mar 2015 08:49:44 -0000 Received: from unknown (HELO mail-cs-02.app.dca.reflexion.local) (10.81.19.2) by 0 (rfx-qmail) with SMTP; 1 Mar 2015 08:49:44 -0000 Received: by mail-cs-02.app.dca.reflexion.local (Reflexion email security v7.40.1) with SMTP; Sun, 01 Mar 2015 03:49:44 -0500 (EST) Received: (qmail 5146 invoked from network); 1 Mar 2015 08:49:43 -0000 Received: from unknown (HELO iron2.pdx.net) (69.64.224.71) by 0 (rfx-qmail) with (DHE-RSA-AES256-SHA encrypted) SMTP; 1 Mar 2015 08:49:43 -0000 X-No-Relay: not in my network X-No-Relay: not in my network X-No-Relay: not in my network Received: from [192.168.1.8] (c-67-189-19-145.hsd1.or.comcast.net [67.189.19.145]) by iron2.pdx.net (Postfix) with ESMTPSA id 71C531C43A8; Sun, 1 Mar 2015 00:49:42 -0800 (PST) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2070.6\)) Subject: Re: Large RAM Powermac G5 powerpc64 openfirmware entry point use: I seem to have removed the major/frequent boot problem(s) From: Mark Millard In-Reply-To: Date: Sun, 1 Mar 2015 00:49:41 -0800 Content-Transfer-Encoding: quoted-printable Message-Id: References: To: FreeBSD PowerPC ML , Nathan Whitehorn , Justin Hibbits X-Mailer: Apple Mail (2.2070.6) X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 01 Mar 2015 08:49:46 -0000 Having a working code combination and switching to finding the minimal = change to FreeBSD's powerpc64 code that preserves the good behavior has = shown that the required change to FreeBSD's powerpc64 code is tiny. The code that must be changed for PowerMac G5 contexts is in = ofw_sprg_prepare: __asm __volatile("mfsprg0 %0\n\t" "mtsprg0 %1\n\t" "mtsprg1 %2\n\t" "mtsprg2 %3\n\t" "mtsprg3 %4\n\t" : "=3D&r"(ofw_sprg0_save) : "r"(ofmsr[1]), "r"(ofmsr[2]), "r"(ofmsr[3]), "r"(ofmsr[4])); Specifically, the "mtsprg0 %1\n\t" must not be done: the FreeBSD SPRG0 = value must be left in place before the use of ofwcall. The PowerMac G5 = openfirmware treats SPRG0 as a scratch register initially (and later), = not as having a value that must be preserved. SPRG0 from before FreeBSD = has no stable initial value to put back here. PowerMac G5 openfirmware entry point code does save SPRG0-SPRG3 but = later depends on SPRG3's unchanged value to point to a pointer to use to = store information. So "mtsprg3 %4\n\t" is required to be in place before = the use of ofwcall: openfirmware requires the value, much like FreeBSD = requires SPRG0 to be in place. "mtsprg1 %2\n\t" and "mtsprg2 %3\n\t" are not needed but do not harm = anything: Both FreeBSD and PowerMac G5 openfirmware treat them as = scratch. I've tested such changes with both 10.1-STABLE's ofwcall64.S and = 11.0-CURRENT's ofwcall64.S (substituted into 10.1-STABLE and with = sys/powerpc/include/asm.h from 11.0-CURRENT as well). Both ofwcall64.S's = work when this change is in place. My initial, special ofwcall code that = I was using is not needed. [Again: I only claim that the most frequent boot failure disappears and = that I've not found any .got corruptions when the change is in place. = Other far less frequent boot failures that I've historically reported = backtraces for may well still happen.] I only have access to PowerMac G5 powerpc64 contexts (11,2 and 7,2, 8G = RAM, 12G RAM and 16G RAM examples) so I can not claim any wider range of = appropriateness than PowerMac G5s, not even other AIM contexts (if any). So to not change the behavior for other contexts: I do not know if there = is a reasonable "IsPowerMac" test but conceptually if an official change = for the improvement was to be made it would need such a live check for a = generic build that was to span PowerMac G5s and other things. I would = not presume to remove "mtsprg0 %1\n\t" for other contexts. My experimental code just plugs in a constant for where the live = IsPowerMac test could possibly be: #if defined(AIM) && defined(__powerpc64__) /* HACK: PowerMac G5 specific code to avoid demonstrated hangs in * the early boot time frame. * This would need a live test for PowerMac vs. not in order * to remove HACK status. */ if (1) __asm __volatile("mfsprg0 %0\n\t" "mtsprg1 %1\n\t" "mtsprg2 %2\n\t" "mtsprg3 %3\n\t" : "=3D&r"(ofw_sprg0_save) : "r"(ofmsr[2]), "r"(ofmsr[3]), "r"(ofmsr[4])); else #endif __asm __volatile("mfsprg0 %0\n\t" "mtsprg0 %1\n\t" "mtsprg1 %2\n\t" "mtsprg2 %3\n\t" "mtsprg3 %4\n\t" : "=3D&r"(ofw_sprg0_save) : "r"(ofmsr[1]), "r"(ofmsr[2]), "r"(ofmsr[3]), "r"(ofmsr[4])); But it also may be that there would be a desire to get the PowerMac = specific code into sys/powerpc/powermac/... someplace. I do hope that an official powerpc64 FreeBSD update for this can be made = to help other PowerMac G5s boot more reliably. Context details: root@FBSDG5M1:/usr/src # freebsd-version -ku ; uname -a 10.1-STABLE 10.1-STABLE FreeBSD FBSDG5M1 10.1-STABLE FreeBSD 10.1-STABLE #78 r279201M: Sat Feb = 28 22:54:30 PST 2015 = root@FBSDG5M1:/usr/obj/usr/src/sys/GENERIC64vtsc powerpc root@FBSDG5M1:/usr/src # svnlite info Path: . Working Copy Root Path: /usr/src URL: https://svn0.us-west.freebsd.org/base/stable/10 Relative URL: ^/stable/10 Repository Root: https://svn0.us-west.freebsd.org/base Repository UUID: ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f Revision: 279201 Node Kind: directory Schedule: normal Last Changed Author: pluknet Last Changed Rev: 279201 Last Changed Date: 2015-02-23 00:45:42 -0800 (Mon, 23 Feb 2015) root@FBSDG5M1:/usr/src # svnlite st ? .snap M sys/ddb/db_main.c M sys/ddb/db_script.c M sys/powerpc/conf ? sys/powerpc/conf/GENERIC64vtsc M sys/powerpc/ofw/ofw_machdep.c M sys/powerpc/ofw/ofwcall64.S The ddb/...'s and ofw/ofwcall64.S are changed only to allow reporting = information for early failures as part of my investigation process (if = any). root@FBSDG5M1:/usr/src # more sys/powerpc/conf/GENERIC64vtsc=20 include GENERIC64 ident GENERIC64vtsc nooptions PS3 #Sony Playstation 3 = HACK!!! to allow sc options DDB # HACK!!! to dump early crash = info (but 11.0-CURRENT already has it) options GDB # HACK!!! ... #options VERBOSE_SYSINIT #options BOOTVERBOSE=3D1 #options BOOTHOWTO=3DRB_VERBOSE #options KTR #options KTR_MASK=3DKTR_TRAP #options KTR_CPUMASK=3D0xF #options KTR_VERBOSE # HACK!!! to allow sc for 2560x1440 display on Radeon X1950 that vt = historically mishandled during booting device sc #device kbdmux # HACK: already listed by vt options SC_OFWFB # OFW frame buffer options SC_DFLT_FONT # compile font in makeoptions SC_DFLT_FONT=3Dcp437 # Disable extra checking typically used for FreeBSD 11.0-CURRENT: nooptions DEADLKRES #Enable the deadlock resolver nooptions INVARIANTS #Enable calls of extra sanity = checking nooptions INVARIANT_SUPPORT #Extra sanity checks of internal = structures, required by INVARIANTS nooptions WITNESS #Enable checks to detect = deadlocks and cycles nooptions WITNESS_SKIPSPIN #Don't run witness on spinlocks = for speed nooptions MALLOC_DEBUG_MAXZONES # Separate malloc(9) zones root@FBSDG5M1:/usr/src # more /etc/make.conf WRKDIRPREFIX=3D/usr/obj/portswork WITH_DEBUG=3D MALLOC_PRODUCTION=3D root@FBSDG5M1:/usr/src # more /etc/src.conf #CFLAGS+=3D-DELF_VERBOSE #WITH_DEBUG_FILES=3D #WITHOUT_CLANG=3D =3D=3D=3D Mark Millard markmi at dsl-only.net From owner-freebsd-ppc@FreeBSD.ORG Sun Mar 1 12:14:08 2015 Return-Path: Delivered-To: freebsd-ppc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 46B2183F for ; Sun, 1 Mar 2015 12:14:08 +0000 (UTC) Received: from asp.reflexion.net (outbound-242.asp.reflexion.net [69.84.129.242]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E2A8E832 for ; Sun, 1 Mar 2015 12:14:07 +0000 (UTC) Received: (qmail 30509 invoked from network); 1 Mar 2015 12:14:05 -0000 Received: from unknown (HELO mail-cs-02.app.dca.reflexion.local) (10.81.19.2) by 0 (rfx-qmail) with SMTP; 1 Mar 2015 12:14:05 -0000 Received: by mail-cs-02.app.dca.reflexion.local (Reflexion email security v7.40.1) with SMTP; Sun, 01 Mar 2015 07:14:05 -0500 (EST) Received: (qmail 26857 invoked from network); 1 Mar 2015 12:14:05 -0000 Received: from unknown (HELO iron2.pdx.net) (69.64.224.71) by 0 (rfx-qmail) with (DHE-RSA-AES256-SHA encrypted) SMTP; 1 Mar 2015 12:14:05 -0000 X-No-Relay: not in my network Received: from [192.168.1.8] (c-67-189-19-145.hsd1.or.comcast.net [67.189.19.145]) by iron2.pdx.net (Postfix) with ESMTPSA id E8FFE1C43AA for ; Sun, 1 Mar 2015 04:14:02 -0800 (PST) From: Mark Millard Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Subject: cb_dumpdata vs. PowerMac G5's (or at least my SSD context): add involvement of dumpinfo's maxiosize value? Message-Id: <84EBF11A-FB29-440B-BA0F-9FA94F1501AD@dsl-only.net> Date: Sun, 1 Mar 2015 04:14:03 -0800 To: FreeBSD PowerPC ML Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2070.6\)) X-Mailer: Apple Mail (2.2070.6) X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 01 Mar 2015 12:14:08 -0000 Context: 10.1-STABLE powerpc64 for PowerMac G5 I'm unable to get panic dumps because the DMA size is rejected, 64K = being too big. I'd like to get things to the point where panic dumps are = possible for that context. Looking around I find: root@FBSDG5M1:/usr/src # grep DFLTPHYS sys/sys/*.h sys/sys/param.h:#ifndef DFLTPHYS sys/sys/param.h:#define DFLTPHYS (64 * 1024) /* default max = raw I/O transfer size */ sys/sys/param.h:#define MAXDUMPPGS (DFLTPHYS/PAGE_SIZE) root@FBSDG5M1:/usr/src # grep DFLTPHYS sys/powerpc/powerpc/* sys/powerpc/powerpc/dump_machdep.c: sz =3D (resid > = DFLTPHYS) ? DFLTPHYS : resid; static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; ... resid =3D md->md_size; ... while (resid) { sz =3D (resid > DFLTPHYS) ? DFLTPHYS : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, = sz); ... } Which may well be where the 64K is from. sys/sys/conf.h has: struct dumperinfo { dumper_t *dumper; /* Dumping function. */ void *priv; /* Private parts. */ u_int blocksize; /* Size of block in bytes. */ u_int maxiosize; /* Max size allowed for an individual = I/O */ off_t mediaoffset; /* Initial offset in bytes. */ off_t mediasize; /* Space available in bytes. */ }; So it would appear that maxiosize from dumperinfo was supposed to be = involved. But at this level nothing is checking dumperinfo's maxiosize = field value to avoid using anything bigger. It may be that the di->dumper is supposed to deal with allowed sizes = being smaller than its size parameter indicates (sz here). But then = exposing maxiosize in dumperinfo would seem a bit odd as an interface. My initial guess would be that cb_dumpdata should be more like: static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (di->maxiosizemaxiosize = : DFLTPHYS; ... printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, = sz); ... } I have assumed that even when 0=3D=3Dresid that 0!=3Darg: the origin = code would not dereference di in that kind of context so a little more = conditional logic might be required if that property needs to be = preserved. Anyone know if I seem to be going in a reasonable direction for this? I've only noted the large transfer size that I found. Many other places = use a di->dumper with the size of something much smaller or with a = smaller symbolic constant (such as having value 512). Again there is no = maxiosize handling. It seems there there is an expected (implicit?) = minimum size for maxiosize such that these various things would always = fit. =46rom that point of view I'm just objecting to DFLTPHYS being that = minimum I guess: I want a smaller minimum so that I can get dumps from = my existing configuration. =3D=3D=3D Mark Millard markmi at dsl-only.net From owner-freebsd-ppc@FreeBSD.ORG Sun Mar 1 16:22:34 2015 Return-Path: Delivered-To: freebsd-ppc@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C01CA25D for ; Sun, 1 Mar 2015 16:22:34 +0000 (UTC) Received: from kenobi.freebsd.org (kenobi.freebsd.org [IPv6:2001:1900:2254:206a::16:76]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A16642BD for ; Sun, 1 Mar 2015 16:22:34 +0000 (UTC) Received: from bugs.freebsd.org ([127.0.1.118]) by kenobi.freebsd.org (8.14.9/8.14.9) with ESMTP id t21GMYI5018774 for ; Sun, 1 Mar 2015 16:22:34 GMT (envelope-from bugzilla-noreply@freebsd.org) From: bugzilla-noreply@freebsd.org To: freebsd-ppc@FreeBSD.org Subject: [Bug 198133] graphics/opencv-core fails to build on powerpc64 Date: Sun, 01 Mar 2015 16:22:34 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: Ports & Packages X-Bugzilla-Component: Individual Port(s) X-Bugzilla-Version: Latest X-Bugzilla-Keywords: X-Bugzilla-Severity: Affects Only Me X-Bugzilla-Who: jhibbits@FreeBSD.org X-Bugzilla-Status: New X-Bugzilla-Priority: --- X-Bugzilla-Assigned-To: jhale@FreeBSD.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: maintainer-feedback? X-Bugzilla-Changed-Fields: bug_id short_desc product version rep_platform op_sys bug_status bug_severity priority component assigned_to reporter cc flagtypes.name attachments.created Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: https://bugs.freebsd.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 01 Mar 2015 16:22:34 -0000 https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198133 Bug ID: 198133 Summary: graphics/opencv-core fails to build on powerpc64 Product: Ports & Packages Version: Latest Hardware: ppc OS: Any Status: New Severity: Affects Only Me Priority: --- Component: Individual Port(s) Assignee: jhale@FreeBSD.org Reporter: jhibbits@FreeBSD.org CC: freebsd-ppc@FreeBSD.org CC: freebsd-ppc@FreeBSD.org Flags: maintainer-feedback?(jhale@FreeBSD.org) Assignee: jhale@FreeBSD.org Created attachment 153643 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=153643&action=edit poudriere failure log for graphics/opencv-core graphics/opencv-core throws a linker error: cd /wrkdirs/usr/ports/graphics/opencv-core/work/opencv-2.4.9/modules/core && /usr/local/bin/g++48 -O2 -pipe -mcpu=970 -Wl,-rpath=/usr/local/lib/gcc48 -fno-strict-aliasing -Wl,-rpath=/usr/local/lib/gcc48 -DNDEBUG -fPIC -I"/wrkdirs/usr/ports/graphics/opencv-core/work/opencv-2.4.9/modules/dynamicuda/include" -I"/wrkdirs/usr/ports/graphics/opencv-core/work/opencv-2.4.9/modules/core" -I"/wrkdirs/usr/ports/graphics/opencv-core/work/opencv-2.4.9/modules/core/src" -I"/wrkdirs/usr/ports/graphics/opencv-core/work/opencv-2.4.9/modules/core/include" -isystem"/wrkdirs/usr/ports/graphics/opencv-core/work/opencv-2.4.9" -isystem"/usr/local/include/eigen3" -isystem"/usr/include" -O2 -pipe -mcpu=970 -Wl,-rpath=/usr/local/lib/gcc48 -fno-strict-aliasing -Wl,-rpath=/usr/local/lib/gcc48 -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -fdiagnostics-show-option -pthread -fomit-frame-pointer -mtune=G5 -ffunction-sections -DCVAPI_EXPORTS -x c++-header -o /wrkdirs/usr/ports/graphics/opencv-core/work/opencv-2.4.9/modules/core/precomp.hpp.gch/opencv_core_Release.gch /wrkdirs/usr/ports/graphics/opencv-core/work/opencv-2.4.9/modules/core/precomp.hpp /usr/lib/crt1.o:(.got+0x60): undefined reference to `main' collect2: error: ld returned 1 exit status *** Error code 1 Building on powerpc64. I've attached the poudriere log. The only difference from default is this is being built with lang/gcc instead of base. -- You are receiving this mail because: You are on the CC list for the bug. From owner-freebsd-ppc@FreeBSD.ORG Mon Mar 2 00:47:23 2015 Return-Path: Delivered-To: freebsd-ppc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id E96BE2FF for ; Mon, 2 Mar 2015 00:47:23 +0000 (UTC) Received: from asp.reflexion.net (outbound-242.asp.reflexion.net [69.84.129.242]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A2F77D53 for ; Mon, 2 Mar 2015 00:47:22 +0000 (UTC) Received: (qmail 5451 invoked from network); 2 Mar 2015 00:47:16 -0000 Received: from unknown (HELO rtc-sm-01.app.dca.reflexion.local) (10.81.150.1) by 0 (rfx-qmail) with SMTP; 2 Mar 2015 00:47:16 -0000 Received: by rtc-sm-01.app.dca.reflexion.local (Reflexion email security v7.40.1) with SMTP; Sun, 01 Mar 2015 19:47:16 -0500 (EST) Received: (qmail 7198 invoked from network); 2 Mar 2015 00:47:15 -0000 Received: from unknown (HELO iron2.pdx.net) (69.64.224.71) by 0 (rfx-qmail) with (DHE-RSA-AES256-SHA encrypted) SMTP; 2 Mar 2015 00:47:15 -0000 X-No-Relay: not in my network Received: from [192.168.1.8] (c-67-189-19-145.hsd1.or.comcast.net [67.189.19.145]) by iron2.pdx.net (Postfix) with ESMTPSA id 534AA1C439E for ; Sun, 1 Mar 2015 16:47:10 -0800 (PST) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2070.6\)) Subject: Re: cb_dumpdata vs. PowerMac G5's (or at least my SSD context): add involvement of dumpinfo's maxiosize value? From: Mark Millard In-Reply-To: <84EBF11A-FB29-440B-BA0F-9FA94F1501AD@dsl-only.net> Date: Sun, 1 Mar 2015 16:47:13 -0800 Content-Transfer-Encoding: quoted-printable Message-Id: <9F6AE9A1-CDE0-47F9-9EF6-1C3710A5C59B@dsl-only.net> References: <84EBF11A-FB29-440B-BA0F-9FA94F1501AD@dsl-only.net> To: FreeBSD PowerPC ML X-Mailer: Apple Mail (2.2070.6) X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Mar 2015 00:47:24 -0000 Unfortunately reporting the trace of finding what is happening for the = DMA size panic-dump issue for powerpc64 on PowerMac G5's (and others = FreeBSDs?) is rather long... My test of trying a variant of my example code still ended up trying for = a 64K DMA when only 32K is allowed according to the error message it = generated. It would appear the dumperinfo's maxiosize is too big as well. Looking = around... $ find sys -name '*.[hcsm]' -exec grep "\" {} \; -print = | more "FAILURE - oversized DMA transfer attempt %d > = %d\n", sys/dev/ata/ata-dma.c "FAILURE - oversized DMA transfer attempt %d > = %d\n", sys/powerpc/powermac/ata_dbdma.c static int ata_dmaload(struct ata_request *request, void *addr, int *entries) { struct ata_channel *ch =3D device_get_softc(request->parent); ... if (request->bytecount > ch->dma.max_iosize) { device_printf(request->parent, "FAILURE - oversized DMA transfer attempt %d > = %d\n", request->bytecount, ch->dma.max_iosize); return EIO; } ... } and static int ata_dbdma_load(struct ata_request *request, void *addr, int *entries) { struct ata_channel *ch =3D device_get_softc(request->parent); ... if (request->bytecount > ch->dma.max_iosize) { device_printf(request->dev, "FAILURE - oversized DMA transfer attempt %d > = %d\n", request->bytecount, ch->dma.max_iosize); return EIO; } ... } These suggest that the dumperinfo's maxiosize might sometimes be = legitimately bigger than ata_channel's dma.max_iosize since = dma.max_iosize would be very specific to DMA transfers. So it would appear that either: A) ata_channel's dma.max_iosize should also be considered in = dump_machdep.c . or B) dumperinfo's maxiosize value should in part be based on ata_channel's = dma.max_iosize when an ata_channel is involved and DMA would be = involved. Then looking... $ find sys -name '*.[hcSm]' -exec grep "\" {} \; -print | = more =20= maxdumpsz =3D di->maxiosize; sys/mips/mips/minidump_machdep.c maxdumppgs =3D min(di->maxiosize / PAGE_SIZE, MAXDUMPPGS); sys/x86/x86/dump_machdep.c gkd->di.maxiosize =3D DFLTPHYS; sys/geom/raid/g_raid.c gkd->di.maxiosize =3D dp->d_maxsize; sys/geom/geom_disk.c maxdumpsz =3D min(di->maxiosize, MAXDUMPPGS * PAGE_SIZE); sys/i386/i386/minidump_machdep.c maxdumpsz =3D min(di->maxiosize, MAXDUMPPGS * PAGE_SIZE); sys/amd64/amd64/minidump_machdep.c u_int maxiosize; /* Max size allowed for an individual = I/O */ sys/sys/conf.h maxdumpsz =3D di->maxiosize; sys/arm/arm/minidump_machdep.c u_int max_trans_sz =3D (0=3D=3Ddi) ? 0 : = (di->maxiosizemaxiosize : DFLTPHYS; * The original code that ignored = di->maxiosize had that property sys/powerpc/powerpc/dump_machdep.c static void g_disk_kerneldump(struct bio *bp, struct disk *dp) { struct g_kerneldump *gkd; struct g_geom *gp; gkd =3D (struct g_kerneldump*)bp->bio_data; ... gkd->di.maxiosize =3D dp->d_maxsize; ... } So that would trace back to disk's d_maxsize. The only assignment to the = field that I find is in g_disk_access: g_disk_access(struct g_provider *pp, int r, int w, int e) { struct disk *dp; struct g_disk_softc *sc; int error; g_trace(G_T_ACCESS, "g_disk_access(%s, %d, %d, %d)", pp->name, r, w, e); g_topology_assert(); sc =3D pp->private; if (sc =3D=3D NULL || (dp =3D sc->dp) =3D=3D NULL || = dp->d_destroyed) { ... return (ENXIO); } ... if ((pp->acr + pp->acw + pp->ace) =3D=3D 0 && (r + w + e) > 0) { ... if (dp->d_maxsize =3D=3D 0) { printf("WARNING: Disk drive %s%d has no = d_maxsize\n", dp->d_name, dp->d_unit); dp->d_maxsize =3D DFLTPHYS; } ... } So it appears that the caller(s) of disk_create need to supply the value = to the field. Looking at sys/cam/ata/ata_da.c's calling code... #ifndef ata_disk_firmware_geom_adjust #define ata_disk_firmware_geom_adjust(disk) #endif ... static cam_status adaregister(struct cam_periph *periph, void *arg) { struct ada_softc *softc; struct ccb_pathinq cpi; struct ccb_getdev *cgd; char announce_buf[80], buf1[32]; struct disk_params *dp; caddr_t match; u_int maxio; int legacy_id, quirks; ... bzero(&cpi, sizeof(cpi)); xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code =3D XPT_PATH_INQ; xpt_action((union ccb *)&cpi); ... maxio =3D cpi.maxio; /* Honor max I/O size of SIM = */ if (maxio =3D=3D 0) maxio =3D DFLTPHYS; /* traditional default */ else if (maxio > MAXPHYS) maxio =3D MAXPHYS; /* for safety */ if (softc->flags & ADA_FLAG_CAN_48BIT) maxio =3D min(maxio, 65536 * softc->params.secsize); else /* 28bit ATA command = limit */ maxio =3D min(maxio, 256 * softc->params.secsize); softc->disk->d_maxsize =3D maxio; ... ata_disk_firmware_geom_adjust(softc->disk); ... } So far I do not see any hint of a ata_channel's dma.max_iosize being = involved in setting d_maxsize. (Only pc98 and sparc64 seem to have = ata_disk_firmware_geom_adjust definitions.) As overall there may not be a global requirement to use DMA this may = well make sense. But it would mean that when DMA is to be used and it is an ata_channel = context that the ata_channel's dma.max_iosize should be consulted. (Not = that ata_channel need be the only context with such an issue. But it is = the one involved in my problem.) Looking around I find the following assignments: $ find sys -name '*.[hcSm]' -exec grep "\" {} \; -print | = more = =20 ch->dma.max_iosize =3D (ATA_SIIPRB_DMA_ENTRIES - 1) * PAGE_SIZE; sys/dev/ata/chipsets/ata-siliconimage.c ch->dma.max_iosize =3D 65536; sys/dev/ata/chipsets/ata-promise.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-serverworks.c ch->dma.max_iosize =3D (ATA_AHCI_DMA_ENTRIES - 1) * PAGE_SIZE; sys/dev/ata/chipsets/ata-ahci.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-cyrix.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-national.c if (ch->dma.max_iosize > 256 * 512) ch->dma.max_iosize =3D 256 * 512; sys/dev/ata/chipsets/ata-acerlabs.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-marvell.c ... (no assignment) ... sys/dev/ata/ata-all.c ... (no assignment) ... sys/dev/ata/ata-all.h if (ch->dma.max_iosize =3D=3D 0) ch->dma.max_iosize =3D MIN((ATA_DMA_ENTRIES - 1) * PAGE_SIZE, = MAXPHYS); NULL, NULL, ch->dma.max_iosize, NULL, NULL, ch->dma.max_iosize, if (request->bytecount > ch->dma.max_iosize) { request->bytecount, ch->dma.max_iosize); sys/dev/ata/ata-dma.c ... (no assignment) ... sys/arm/mv/mv_sata.c ... (no assignment) ... sys/powerpc/powermac/ata_dbdma.c ... (no assignment) ... sys/cam/ctl/ctl_backend_block.c All but possibly the last being ata contexts for the field name = max_iosize . In sys/sys/param.h I find: #define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */ #define DEV_BSIZE (1<" {} \; -print | = more =20= #define ATA_AHCI_DMA_ENTRIES 129 struct ata_ahci_dma_prd prd_tab[ATA_AHCI_DMA_ENTRIES]; #define ATA_DMA_ENTRIES 256 sys/dev/ata/ata-all.h and sys/powerpc/include/param.h has: #define PAGE_SHIFT 12 #define PAGE_SIZE (1L << PAGE_SHIFT) /* Page size */ #define PAGE_MASK (vm_offset_t)(PAGE_SIZE - 1) So PAGE_SIZE =3D=3D 4096 for the context. So any ATA_..._ENTRIES * = PAGE_SIZE alternatives are not involved in my problem. Looking at what dumper is assigned... static void g_disk_kerneldump(struct bio *bp, struct disk *dp) { struct g_kerneldump *gkd; struct g_geom *gp; ... if (dp->d_dump =3D=3D NULL) { g_io_deliver(bp, ENODEV); return; } gkd->di.dumper =3D dp->d_dump; ... } where sys/cam/ata/ata_da.c has: static cam_status adaregister(struct cam_periph *periph, void *arg) { struct ada_softc *softc; ... softc->disk->d_dump =3D adadump; ... } adadump has no logic to limit its I/O requests by the dma.max_iosize = when given a length bigger than that. sys/cam/ata/ata_da.c has no text = "dma" at all. But adadump does have: adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, = size_t length) { ... if ((softc->flags & ADA_FLAG_CAN_48BIT) && (lba + count >=3D ATA_MAX_28BIT_LBA || count >=3D 256)) { ata_48bit_cmd(&ccb.ataio, ATA_WRITE_DMA48, 0, lba, count); } else { ata_28bit_cmd(&ccb.ataio, ATA_WRITE_DMA, 0, lba, count); } ... } which makes the I/O a DMA based I/O for sure. I do not see that sys/cam/ata/... explicitly uses or exposes = ata_channel's dma.max_iosize in any way. As a matter of interfacing I would expect that --just like the dumper = field gets into the appropriate cam code-- any abstraction spanning = dma.max_iosize sorts of issues would also reference something that gets = into the cam code that matches up with the dumper cam code. There seems to be no such interface. One could imagine a new dumpinfo = field (look for the dumper_adjusted_maxsize below): static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (di->maxiosizemaxiosize : = DFLTPHYS; ... max_trans_sz =3D di->dumper_adjusted_maxsize(di->priv, = max_trans_sz); ... printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } (Middle layers would need to be set up to allow plugging in the value = into dumpinfo's new field and sys/cam/ata/... would need ata_channel's = dma.max_iosize access and use of it.) In many cases dumper_adjusted_maxsize might be an identity operation (no = adjustment) or a simple maximum operation but for sys/cam/ata/ata_da.c = contexts its main purpose would be to apply DMA size limitations if they = are smaller than the parameter passed in. Out of all this my overall conclusion is that there is a hole in the = FreeBSD design and without some design changes the technique is to = change the constant values used in cb_dumpdata to values that happen to = work. In this simpler line of things it leaves me wondering if something like = DFLTPHYS/2 would be appropriate for dumper contexts in official = 10.1-STABLE FreeBSD for now: static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (di->maxiosizemaxiosize = : DFLTPHYS/2; ... printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } More of the existing ch->dma.max_iosize assignments would not be = exceeded and so more contexts could then generate panic dumps. Context for the experiment that prompted the above looking around: $ freebsd-version -ku; uname -a 10.1-RELEASE-p6 10.1-STABLE FreeBSD FBSDG5M1 10.1-RELEASE-p6 FreeBSD 10.1-RELEASE-p6 #21 r279264M: = Sun Mar 1 03:31:59 PST 2015 = root@FBSDG5M1:/usr/obj/usr/home/markmi/src_10_1_releng/sys/GENERIC64vtsc = powerpc $ svnlite st ? .snap M sys/ddb/db_main.c M sys/ddb/db_script.c M sys/powerpc/conf ? sys/powerpc/conf/GENERIC64vtsc M sys/powerpc/ofw/ofw_machdep.c M sys/powerpc/ofw/ofwcall64.S M sys/powerpc/powerpc/dump_machdep.c $ svnlite info Path: . Working Copy Root Path: /usr/src URL: https://svn0.us-west.freebsd.org/base/stable/10 Relative URL: ^/stable/10 Repository Root: https://svn0.us-west.freebsd.org/base Repository UUID: ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f Revision: 279201 Node Kind: directory Schedule: normal Last Changed Author: pluknet Last Changed Rev: 279201 Last Changed Date: 2015-02-23 00:45:42 -0800 (Mon, 23 Feb 2015) $ svnlite diff sys/powerpc/powerpc/dump_machdep.c | more Index: sys/powerpc/powerpc/dump_machdep.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/powerpc/powerpc/dump_machdep.c (revision 279201) +++ sys/powerpc/powerpc/dump_machdep.c (working copy) @@ -113,6 +113,11 @@ cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; + u_int max_trans_sz =3D (0=3D=3Ddi) ? 0 : = (di->maxiosizemaxiosize : DFLTPHYS; + /* If md->md_size turns out to be 0 the = above avoids derefercing di. + * The original code that ignored = di->maxiosize had that property + * overall. So this update does too. + */ vm_offset_t va; size_t counter, ofs, resid, sz; int c, error, twiddle; @@ -124,10 +129,10 @@ ofs =3D 0; /* Logical offset within the chunk */ resid =3D md->md_size; =20 - printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); + printf(" chunk %d: %lu bytes max_trans_sz %lu ", seqnr, = (u_long)resid, (u_long)max_trans_sz); =20 while (resid) { - sz =3D (resid > DFLTPHYS) ? DFLTPHYS : resid; + sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; va =3D pmap_dumpsys_map(md, ofs, &sz); counter +=3D sz; if (counter >> 24) { =3D=3D=3D Mark Millard markmi at dsl-only.net On 2015-Mar-1, at 04:14 AM, Mark Millard wrote: Context: 10.1-STABLE powerpc64 for PowerMac G5 I'm unable to get panic dumps because the DMA size is rejected, 64K = being too big. I'd like to get things to the point where panic dumps are = possible for that context. Looking around I find: root@FBSDG5M1:/usr/src # grep DFLTPHYS sys/sys/*.h sys/sys/param.h:#ifndef DFLTPHYS sys/sys/param.h:#define DFLTPHYS (64 * 1024) /* default max = raw I/O transfer size */ sys/sys/param.h:#define MAXDUMPPGS (DFLTPHYS/PAGE_SIZE) root@FBSDG5M1:/usr/src # grep DFLTPHYS sys/powerpc/powerpc/* sys/powerpc/powerpc/dump_machdep.c: sz =3D (resid > = DFLTPHYS) ? DFLTPHYS : resid; static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; ... resid =3D md->md_size; ... while (resid) { sz =3D (resid > DFLTPHYS) ? DFLTPHYS : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } Which may well be where the 64K is from. sys/sys/conf.h has: struct dumperinfo { dumper_t *dumper; /* Dumping function. */ void *priv; /* Private parts. */ u_int blocksize; /* Size of block in bytes. */ u_int maxiosize; /* Max size allowed for an individual I/O = */ off_t mediaoffset; /* Initial offset in bytes. */ off_t mediasize; /* Space available in bytes. */ }; So it would appear that maxiosize from dumperinfo was supposed to be = involved. But at this level nothing is checking dumperinfo's maxiosize = field value to avoid using anything bigger. It may be that the di->dumper is supposed to deal with allowed sizes = being smaller than its size parameter indicates (sz here). But then = exposing maxiosize in dumperinfo would seem a bit odd as an interface. My initial guess would be that cb_dumpdata should be more like: static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (di->maxiosizemaxiosize : = DFLTPHYS; ... printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } I have assumed that even when 0=3D=3Dresid that 0!=3Darg: the origin = code would not dereference di in that kind of context so a little more = conditional logic might be required if that property needs to be = preserved. Anyone know if I seem to be going in a reasonable direction for this? I've only noted the large transfer size that I found. Many other places = use a di->dumper with the size of something much smaller or with a = smaller symbolic constant (such as having value 512). Again there is no = maxiosize handling. It seems there there is an expected (implicit?) = minimum size for maxiosize such that these various things would always = fit. =46rom that point of view I'm just objecting to DFLTPHYS being that = minimum I guess: I want a smaller minimum so that I can get dumps from = my existing configuration. =3D=3D=3D Mark Millard markmi at dsl-only.net From owner-freebsd-ppc@FreeBSD.ORG Mon Mar 2 01:17:36 2015 Return-Path: Delivered-To: freebsd-ppc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D72C0438 for ; Mon, 2 Mar 2015 01:17:36 +0000 (UTC) Received: from mail-pa0-x235.google.com (mail-pa0-x235.google.com [IPv6:2607:f8b0:400e:c03::235]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id A0422FAC for ; Mon, 2 Mar 2015 01:17:36 +0000 (UTC) Received: by padfb1 with SMTP id fb1so455253pad.7 for ; Sun, 01 Mar 2015 17:17:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type:content-transfer-encoding; bh=2D0WZwNljfmfuqYhTIEeY7Mj0b3eE8sz0oGFf0FXwjE=; b=pOuPn4vr3YJhHsn1r/CsNLtamEfI6g9FMvJNKEomtWKktN/KXNnMSnPeF5uzQqEG/N LDWZ+PRRcihWUejkcwt0kmaOih333jU4SpnsmgP/H8mRCu3vh8DiwWWt+tccmLKZb7Ab WjSkTVgoViVVbI6nULmukzVF+jM1BwHK/5IGKnsNyqsEW4Aa38gX/D9t23S8tqdKeEry c3sAKA1mIm/L3/Fq5aOi7NS99QkQetIStOVqp3J98JXcUyMHGUWa6M2r52BlON9H//h3 6DI49TSw/LlqO66Nil2YrbHt7GykkVPHL2Ht81/4+xR6fnr03N/22iQKI2XPyMRn2EXG sH0w== X-Received: by 10.68.189.229 with SMTP id gl5mr42415024pbc.109.1425259056051; Sun, 01 Mar 2015 17:17:36 -0800 (PST) Received: from [192.168.1.69] (107-222-186-3.lightspeed.sntcca.sbcglobal.net. [107.222.186.3]) by mx.google.com with ESMTPSA id fz7sm10109161pbd.60.2015.03.01.17.17.34 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 01 Mar 2015 17:17:34 -0800 (PST) Message-ID: <54F3BA2D.8060701@gmail.com> Date: Sun, 01 Mar 2015 17:17:33 -0800 From: Justin Hibbits User-Agent: Mozilla/5.0 (X11; FreeBSD powerpc; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-Version: 1.0 To: freebsd-ppc@freebsd.org Subject: Re: cb_dumpdata vs. PowerMac G5's (or at least my SSD context): add involvement of dumpinfo's maxiosize value? References: <84EBF11A-FB29-440B-BA0F-9FA94F1501AD@dsl-only.net> In-Reply-To: <84EBF11A-FB29-440B-BA0F-9FA94F1501AD@dsl-only.net> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Mar 2015 01:17:36 -0000 On 03/01/15 04:14, Mark Millard wrote: > Context: 10.1-STABLE powerpc64 for PowerMac G5 > > I'm unable to get panic dumps because the DMA size is rejected, 64K being too big. I'd like to get things to the point where panic dumps are possible for that context. This was working in the original powerpc64 dump code. Look at r257941, which was the original code that I committed. I guess the DMA size clamping didn't get migrated to the new dump code. - Justin From owner-freebsd-ppc@FreeBSD.ORG Mon Mar 2 03:07:56 2015 Return-Path: Delivered-To: freebsd-ppc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 9750EA36 for ; Mon, 2 Mar 2015 03:07:56 +0000 (UTC) Received: from asp.reflexion.net (outbound-242.asp.reflexion.net [69.84.129.242]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 50128E12 for ; Mon, 2 Mar 2015 03:07:55 +0000 (UTC) Received: (qmail 28933 invoked from network); 2 Mar 2015 03:07:54 -0000 Received: from unknown (HELO rtc-sm-01.app.dca.reflexion.local) (10.81.150.1) by 0 (rfx-qmail) with SMTP; 2 Mar 2015 03:07:54 -0000 Received: by rtc-sm-01.app.dca.reflexion.local (Reflexion email security v7.40.1) with SMTP; Sun, 01 Mar 2015 22:07:54 -0500 (EST) Received: (qmail 29983 invoked from network); 2 Mar 2015 03:07:53 -0000 Received: from unknown (HELO iron2.pdx.net) (69.64.224.71) by 0 (rfx-qmail) with (DHE-RSA-AES256-SHA encrypted) SMTP; 2 Mar 2015 03:07:53 -0000 X-No-Relay: not in my network X-No-Relay: not in my network Received: from [192.168.1.8] (c-67-189-19-145.hsd1.or.comcast.net [67.189.19.145]) by iron2.pdx.net (Postfix) with ESMTPSA id 94ABF1C43AB; Sun, 1 Mar 2015 19:07:47 -0800 (PST) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2070.6\)) Subject: Re: cb_dumpdata vs. PowerMac G5's (or at least my SSD context): add involvement of dumpinfo's maxiosize value? From: Mark Millard In-Reply-To: <9F6AE9A1-CDE0-47F9-9EF6-1C3710A5C59B@dsl-only.net> Date: Sun, 1 Mar 2015 19:07:51 -0800 Content-Transfer-Encoding: quoted-printable Message-Id: <9BF9F7F8-16B3-4E23-8393-B72D01C96215@dsl-only.net> References: <84EBF11A-FB29-440B-BA0F-9FA94F1501AD@dsl-only.net> <9F6AE9A1-CDE0-47F9-9EF6-1C3710A5C59B@dsl-only.net> To: FreeBSD PowerPC ML , Justin Hibbits X-Mailer: Apple Mail (2.2070.6) X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Mar 2015 03:07:56 -0000 Justing H. wrote: > This was working in the original powerpc64 dump code. Look at = r257941,=20 > which was the original code that I committed. I guess the DMA size=20 > clamping didn't get migrated to the new dump code. So looking around... Using Sticky Revision 257941 shows /head at 257941. sys/powerpc/aim/mmu_oea64.c is what was changed in 257941: adding = moea64_dumpsys_map and moea64_scan_md and the MMUMETHOD entries = mmu_scan_md and mmu_dumpsys_map . For /stable/10/sys/powerpc/aim/mmu_oea64.c the MFC that includes 257941 = is revision 260672 and the most recent code is 279920. = moea64_dumpsys_map, moea64_scan_md, mmu_scan_md, and mmu_dumpsys_map are = still there. First a reminder of the usage context for the two routines (pmap_scan_md = and pmap_dumpsys_map route to the matching moea64_.* routines). static int foreach_chunk(callback_t cb, void *arg) { struct pmap_md *md; int error, seqnr; seqnr =3D 0; md =3D pmap_scan_md(NULL); while (md !=3D NULL) { error =3D (*cb)(md, seqnr++, arg); if (error) return (-error); md =3D pmap_scan_md(md); } return (seqnr); } ... (The below is from my DFLTPHYS/2 variant of the original.) ... static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (0=3D=3Ddi) ? 0 : = (di->maxiosizemaxiosize : DFLTPHYS/2; /* If md->md_size turns out to be 0 the = above avoids derefercing di. * The original code that ignored = di->maxiosize had that property * overall. So this update does too. */ ... while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; va =3D pmap_dumpsys_map(md, ofs, &sz); ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, = sz); pmap_dumpsys_unmap(md, ofs, va); ... } printf("... %s\n", (error) ? "fail" : "ok"); return (error); } Then the routine that the signature/interface gives the potential to = adjust the size: vm_offset_t moea64_dumpsys_map(mmu_t mmu, struct pmap_md *md, vm_size_t ofs, vm_size_t *sz) { if (md->md_vaddr =3D=3D ~0UL) return (md->md_paddr + ofs); else return (md->md_vaddr + ofs); } This code ignores its sz argument. NULL could have been passed in for sz = and nothing would change. As stands pmap_dumpsys_map/moea64_dumpsys_map only determine the = starting address, leaving sz alone. It is not clear to me that moea64_dumpsys_map would have access to the = dma.max_iosize information for the ata_channel that happens to be in = use. Summary of my looking at pmap_scan_md and pmap_dumpsys_map usage: no = effect on the DMA size used and it may not be the appropriate context = for an ata_channel's dma.max_iosize based sz adjustment. My change to DFLTPHYS/2 as I listed earlier as a possibility did allow = chunks to be written --until chunk 29 got an error in my only test so = far. With DFLTPHYS it was no-go. Anyone with a context that gets a 64*1024 dma.max_iosize would not see = the "no-go" problem and for all I know there are such PowerMac G5 = contexts. So to know if the problem is being tested requires = establishing ata_channel's dma.max_iosize is both involved and is = smaller than 64*1024. I've definitely got that context. =3D=3D=3D Mark Millard markmi at dsl-only.net On 2015-Mar-1, at 04:47 PM, Mark Millard wrote: Unfortunately reporting the trace of finding what is happening for the = DMA size panic-dump issue for powerpc64 on PowerMac G5's (and others = FreeBSDs?) is rather long... My test of trying a variant of my example code still ended up trying for = a 64K DMA when only 32K is allowed according to the error message it = generated. It would appear the dumperinfo's maxiosize is too big as well. Looking = around... $ find sys -name '*.[hcsm]' -exec grep "\" {} \; -print = | more "FAILURE - oversized DMA transfer attempt %d > = %d\n", sys/dev/ata/ata-dma.c "FAILURE - oversized DMA transfer attempt %d > %d\n", sys/powerpc/powermac/ata_dbdma.c static int ata_dmaload(struct ata_request *request, void *addr, int *entries) { struct ata_channel *ch =3D device_get_softc(request->parent); ... if (request->bytecount > ch->dma.max_iosize) { device_printf(request->parent, "FAILURE - oversized DMA transfer attempt %d > = %d\n", request->bytecount, ch->dma.max_iosize); return EIO; } ... } and static int ata_dbdma_load(struct ata_request *request, void *addr, int *entries) { struct ata_channel *ch =3D device_get_softc(request->parent); ... if (request->bytecount > ch->dma.max_iosize) { device_printf(request->dev, "FAILURE - oversized DMA transfer attempt %d > %d\n", request->bytecount, ch->dma.max_iosize); return EIO; } ... } These suggest that the dumperinfo's maxiosize might sometimes be = legitimately bigger than ata_channel's dma.max_iosize since = dma.max_iosize would be very specific to DMA transfers. So it would appear that either: A) ata_channel's dma.max_iosize should also be considered in = dump_machdep.c . or B) dumperinfo's maxiosize value should in part be based on ata_channel's = dma.max_iosize when an ata_channel is involved and DMA would be = involved. Then looking... $ find sys -name '*.[hcSm]' -exec grep "\" {} \; -print | = more =20= maxdumpsz =3D di->maxiosize; sys/mips/mips/minidump_machdep.c maxdumppgs =3D min(di->maxiosize / PAGE_SIZE, MAXDUMPPGS); sys/x86/x86/dump_machdep.c gkd->di.maxiosize =3D DFLTPHYS; sys/geom/raid/g_raid.c gkd->di.maxiosize =3D dp->d_maxsize; sys/geom/geom_disk.c maxdumpsz =3D min(di->maxiosize, MAXDUMPPGS * PAGE_SIZE); sys/i386/i386/minidump_machdep.c maxdumpsz =3D min(di->maxiosize, MAXDUMPPGS * PAGE_SIZE); sys/amd64/amd64/minidump_machdep.c u_int maxiosize; /* Max size allowed for an individual I/O = */ sys/sys/conf.h maxdumpsz =3D di->maxiosize; sys/arm/arm/minidump_machdep.c u_int max_trans_sz =3D (0=3D=3Ddi) ? 0 : (di->maxiosizemaxiosize : DFLTPHYS; * The original code that ignored = di->maxiosize had that property sys/powerpc/powerpc/dump_machdep.c static void g_disk_kerneldump(struct bio *bp, struct disk *dp) { struct g_kerneldump *gkd; struct g_geom *gp; gkd =3D (struct g_kerneldump*)bp->bio_data; ... gkd->di.maxiosize =3D dp->d_maxsize; ... } So that would trace back to disk's d_maxsize. The only assignment to the = field that I find is in g_disk_access: g_disk_access(struct g_provider *pp, int r, int w, int e) { struct disk *dp; struct g_disk_softc *sc; int error; g_trace(G_T_ACCESS, "g_disk_access(%s, %d, %d, %d)", pp->name, r, w, e); g_topology_assert(); sc =3D pp->private; if (sc =3D=3D NULL || (dp =3D sc->dp) =3D=3D NULL || = dp->d_destroyed) { ... return (ENXIO); } ... if ((pp->acr + pp->acw + pp->ace) =3D=3D 0 && (r + w + e) > 0) { ... if (dp->d_maxsize =3D=3D 0) { printf("WARNING: Disk drive %s%d has no = d_maxsize\n", dp->d_name, dp->d_unit); dp->d_maxsize =3D DFLTPHYS; } ... } So it appears that the caller(s) of disk_create need to supply the value = to the field. Looking at sys/cam/ata/ata_da.c's calling code... #ifndef ata_disk_firmware_geom_adjust #define ata_disk_firmware_geom_adjust(disk) #endif ... static cam_status adaregister(struct cam_periph *periph, void *arg) { struct ada_softc *softc; struct ccb_pathinq cpi; struct ccb_getdev *cgd; char announce_buf[80], buf1[32]; struct disk_params *dp; caddr_t match; u_int maxio; int legacy_id, quirks; ... bzero(&cpi, sizeof(cpi)); xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code =3D XPT_PATH_INQ; xpt_action((union ccb *)&cpi); ... maxio =3D cpi.maxio; /* Honor max I/O size of SIM */ if (maxio =3D=3D 0) maxio =3D DFLTPHYS; /* traditional default */ else if (maxio > MAXPHYS) maxio =3D MAXPHYS; /* for safety */ if (softc->flags & ADA_FLAG_CAN_48BIT) maxio =3D min(maxio, 65536 * softc->params.secsize); else /* 28bit ATA command = limit */ maxio =3D min(maxio, 256 * softc->params.secsize); softc->disk->d_maxsize =3D maxio; ... ata_disk_firmware_geom_adjust(softc->disk); ... } So far I do not see any hint of a ata_channel's dma.max_iosize being = involved in setting d_maxsize. (Only pc98 and sparc64 seem to have = ata_disk_firmware_geom_adjust definitions.) As overall there may not be a global requirement to use DMA this may = well make sense. But it would mean that when DMA is to be used and it is an ata_channel = context that the ata_channel's dma.max_iosize should be consulted. (Not = that ata_channel need be the only context with such an issue. But it is = the one involved in my problem.) Looking around I find the following assignments: $ find sys -name '*.[hcSm]' -exec grep "\" {} \; -print | = more = =20 ch->dma.max_iosize =3D (ATA_SIIPRB_DMA_ENTRIES - 1) * PAGE_SIZE; sys/dev/ata/chipsets/ata-siliconimage.c ch->dma.max_iosize =3D 65536; sys/dev/ata/chipsets/ata-promise.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-serverworks.c ch->dma.max_iosize =3D (ATA_AHCI_DMA_ENTRIES - 1) * PAGE_SIZE; sys/dev/ata/chipsets/ata-ahci.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-cyrix.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-national.c if (ch->dma.max_iosize > 256 * 512) ch->dma.max_iosize =3D 256 * 512; sys/dev/ata/chipsets/ata-acerlabs.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-marvell.c ... (no assignment) ... sys/dev/ata/ata-all.c ... (no assignment) ... sys/dev/ata/ata-all.h if (ch->dma.max_iosize =3D=3D 0) ch->dma.max_iosize =3D MIN((ATA_DMA_ENTRIES - 1) * PAGE_SIZE, = MAXPHYS); NULL, NULL, ch->dma.max_iosize, NULL, NULL, ch->dma.max_iosize, if (request->bytecount > ch->dma.max_iosize) { request->bytecount, ch->dma.max_iosize); sys/dev/ata/ata-dma.c ... (no assignment) ... sys/arm/mv/mv_sata.c ... (no assignment) ... sys/powerpc/powermac/ata_dbdma.c ... (no assignment) ... sys/cam/ctl/ctl_backend_block.c All but possibly the last being ata contexts for the field name = max_iosize . In sys/sys/param.h I find: #define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */ #define DEV_BSIZE (1<" {} \; -print | = more =20= #define ATA_AHCI_DMA_ENTRIES 129 struct ata_ahci_dma_prd prd_tab[ATA_AHCI_DMA_ENTRIES]; #define ATA_DMA_ENTRIES 256 sys/dev/ata/ata-all.h and sys/powerpc/include/param.h has: #define PAGE_SHIFT 12 #define PAGE_SIZE (1L << PAGE_SHIFT) /* Page size */ #define PAGE_MASK (vm_offset_t)(PAGE_SIZE - 1) So PAGE_SIZE =3D=3D 4096 for the context. So any ATA_..._ENTRIES * = PAGE_SIZE alternatives are not involved in my problem. Looking at what dumper is assigned... static void g_disk_kerneldump(struct bio *bp, struct disk *dp) { struct g_kerneldump *gkd; struct g_geom *gp; ... if (dp->d_dump =3D=3D NULL) { g_io_deliver(bp, ENODEV); return; } gkd->di.dumper =3D dp->d_dump; ... } where sys/cam/ata/ata_da.c has: static cam_status adaregister(struct cam_periph *periph, void *arg) { struct ada_softc *softc; ... softc->disk->d_dump =3D adadump; ... } adadump has no logic to limit its I/O requests by the dma.max_iosize = when given a length bigger than that. sys/cam/ata/ata_da.c has no text = "dma" at all. But adadump does have: adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, = size_t length) { ... if ((softc->flags & ADA_FLAG_CAN_48BIT) && (lba + count >=3D ATA_MAX_28BIT_LBA || count >=3D 256)) { ata_48bit_cmd(&ccb.ataio, ATA_WRITE_DMA48, 0, lba, count); } else { ata_28bit_cmd(&ccb.ataio, ATA_WRITE_DMA, 0, lba, count); } ... } which makes the I/O a DMA based I/O for sure. I do not see that sys/cam/ata/... explicitly uses or exposes = ata_channel's dma.max_iosize in any way. As a matter of interfacing I would expect that --just like the dumper = field gets into the appropriate cam code-- any abstraction spanning = dma.max_iosize sorts of issues would also reference something that gets = into the cam code that matches up with the dumper cam code. There seems to be no such interface. One could imagine a new dumpinfo = field (look for the dumper_adjusted_maxsize below): static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (di->maxiosizemaxiosize : = DFLTPHYS; ... max_trans_sz =3D di->dumper_adjusted_maxsize(di->priv, = max_trans_sz); ... printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } (Middle layers would need to be set up to allow plugging in the value = into dumpinfo's new field and sys/cam/ata/... would need ata_channel's = dma.max_iosize access and use of it.) In many cases dumper_adjusted_maxsize might be an identity operation (no = adjustment) or a simple maximum operation but for sys/cam/ata/ata_da.c = contexts its main purpose would be to apply DMA size limitations if they = are smaller than the parameter passed in. Out of all this my overall conclusion is that there is a hole in the = FreeBSD design and without some design changes the technique is to = change the constant values used in cb_dumpdata to values that happen to = work. In this simpler line of things it leaves me wondering if something like = DFLTPHYS/2 would be appropriate for dumper contexts in official = 10.1-STABLE FreeBSD for now: static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (di->maxiosizemaxiosize = : DFLTPHYS/2; ... printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } More of the existing ch->dma.max_iosize assignments would not be = exceeded and so more contexts could then generate panic dumps. Context for the experiment that prompted the above looking around: $ freebsd-version -ku; uname -a 10.1-RELEASE-p6 10.1-STABLE FreeBSD FBSDG5M1 10.1-RELEASE-p6 FreeBSD 10.1-RELEASE-p6 #21 r279264M: = Sun Mar 1 03:31:59 PST 2015 = root@FBSDG5M1:/usr/obj/usr/home/markmi/src_10_1_releng/sys/GENERIC64vtsc = powerpc $ svnlite st ? .snap M sys/ddb/db_main.c M sys/ddb/db_script.c M sys/powerpc/conf ? sys/powerpc/conf/GENERIC64vtsc M sys/powerpc/ofw/ofw_machdep.c M sys/powerpc/ofw/ofwcall64.S M sys/powerpc/powerpc/dump_machdep.c $ svnlite info Path: . Working Copy Root Path: /usr/src URL: https://svn0.us-west.freebsd.org/base/stable/10 Relative URL: ^/stable/10 Repository Root: https://svn0.us-west.freebsd.org/base Repository UUID: ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f Revision: 279201 Node Kind: directory Schedule: normal Last Changed Author: pluknet Last Changed Rev: 279201 Last Changed Date: 2015-02-23 00:45:42 -0800 (Mon, 23 Feb 2015) $ svnlite diff sys/powerpc/powerpc/dump_machdep.c | more Index: sys/powerpc/powerpc/dump_machdep.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/powerpc/powerpc/dump_machdep.c (revision 279201) +++ sys/powerpc/powerpc/dump_machdep.c (working copy) @@ -113,6 +113,11 @@ cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; + u_int max_trans_sz =3D (0=3D=3Ddi) ? 0 : = (di->maxiosizemaxiosize : DFLTPHYS; + /* If md->md_size turns out to be 0 the = above avoids derefercing di. + * The original code that ignored = di->maxiosize had that property + * overall. So this update does too. + */ vm_offset_t va; size_t counter, ofs, resid, sz; int c, error, twiddle; @@ -124,10 +129,10 @@ ofs =3D 0; /* Logical offset within the chunk */ resid =3D md->md_size; - printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); + printf(" chunk %d: %lu bytes max_trans_sz %lu ", seqnr, = (u_long)resid, (u_long)max_trans_sz); while (resid) { - sz =3D (resid > DFLTPHYS) ? DFLTPHYS : resid; + sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; va =3D pmap_dumpsys_map(md, ofs, &sz); counter +=3D sz; if (counter >> 24) { =3D=3D=3D Mark Millard markmi at dsl-only.net On 2015-Mar-1, at 04:14 AM, Mark Millard wrote: Context: 10.1-STABLE powerpc64 for PowerMac G5 I'm unable to get panic dumps because the DMA size is rejected, 64K = being too big. I'd like to get things to the point where panic dumps are = possible for that context. Looking around I find: root@FBSDG5M1:/usr/src # grep DFLTPHYS sys/sys/*.h sys/sys/param.h:#ifndef DFLTPHYS sys/sys/param.h:#define DFLTPHYS (64 * 1024) /* default max = raw I/O transfer size */ sys/sys/param.h:#define MAXDUMPPGS (DFLTPHYS/PAGE_SIZE) root@FBSDG5M1:/usr/src # grep DFLTPHYS sys/powerpc/powerpc/* sys/powerpc/powerpc/dump_machdep.c: sz =3D (resid > = DFLTPHYS) ? DFLTPHYS : resid; static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; ... resid =3D md->md_size; ... while (resid) { sz =3D (resid > DFLTPHYS) ? DFLTPHYS : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } Which may well be where the 64K is from. sys/sys/conf.h has: struct dumperinfo { dumper_t *dumper; /* Dumping function. */ void *priv; /* Private parts. */ u_int blocksize; /* Size of block in bytes. */ u_int maxiosize; /* Max size allowed for an individual I/O = */ off_t mediaoffset; /* Initial offset in bytes. */ off_t mediasize; /* Space available in bytes. */ }; So it would appear that maxiosize from dumperinfo was supposed to be = involved. But at this level nothing is checking dumperinfo's maxiosize = field value to avoid using anything bigger. It may be that the di->dumper is supposed to deal with allowed sizes = being smaller than its size parameter indicates (sz here). But then = exposing maxiosize in dumperinfo would seem a bit odd as an interface. My initial guess would be that cb_dumpdata should be more like: static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (di->maxiosizemaxiosize : = DFLTPHYS; ... printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } I have assumed that even when 0=3D=3Dresid that 0!=3Darg: the origin = code would not dereference di in that kind of context so a little more = conditional logic might be required if that property needs to be = preserved. Anyone know if I seem to be going in a reasonable direction for this? I've only noted the large transfer size that I found. Many other places = use a di->dumper with the size of something much smaller or with a = smaller symbolic constant (such as having value 512). Again there is no = maxiosize handling. It seems there there is an expected (implicit?) = minimum size for maxiosize such that these various things would always = fit. =46rom that point of view I'm just objecting to DFLTPHYS being that = minimum I guess: I want a smaller minimum so that I can get dumps from = my existing configuration. =3D=3D=3D Mark Millard markmi at dsl-only.net From owner-freebsd-ppc@FreeBSD.ORG Mon Mar 2 22:49:24 2015 Return-Path: Delivered-To: freebsd-ppc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id E9BDF904 for ; Mon, 2 Mar 2015 22:49:24 +0000 (UTC) Received: from asp.reflexion.net (outbound-242.asp.reflexion.net [69.84.129.242]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8B49D329 for ; Mon, 2 Mar 2015 22:49:24 +0000 (UTC) Received: (qmail 6945 invoked from network); 2 Mar 2015 22:49:22 -0000 Received: from unknown (HELO mail-cs-01.app.dca.reflexion.local) (10.81.19.1) by 0 (rfx-qmail) with SMTP; 2 Mar 2015 22:49:22 -0000 Received: by mail-cs-01.app.dca.reflexion.local (Reflexion email security v7.40.1) with SMTP; Mon, 02 Mar 2015 17:49:22 -0500 (EST) Received: (qmail 22890 invoked from network); 2 Mar 2015 22:49:22 -0000 Received: from unknown (HELO iron2.pdx.net) (69.64.224.71) by 0 (rfx-qmail) with (DHE-RSA-AES256-SHA encrypted) SMTP; 2 Mar 2015 22:49:22 -0000 X-No-Relay: not in my network X-No-Relay: not in my network X-No-Relay: not in my network Received: from [192.168.1.8] (c-67-189-19-145.hsd1.or.comcast.net [67.189.19.145]) by iron2.pdx.net (Postfix) with ESMTPSA id 5D9AE1C405E; Mon, 2 Mar 2015 14:49:17 -0800 (PST) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2070.6\)) Subject: Why official powerpc64 FreeBSD's PowerMac G5 booting sometimes works and sometimes hangs From: Mark Millard In-Reply-To: Date: Mon, 2 Mar 2015 14:49:20 -0800 Content-Transfer-Encoding: quoted-printable Message-Id: <21F3006A-19DA-44F7-8F37-F5FFE8555715@dsl-only.net> References: To: FreeBSD PowerPC ML , Nathan Whitehorn , Justin Hibbits X-Mailer: Apple Mail (2.2070.6) X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Mar 2015 22:49:25 -0000 Various PowerMac G5 configurations have variable behavior when booting: = sometimes hanging up and other times booting fine. This is one of the = things that any proposed fix had to be able to explain beyond just = seeming to work: How does the fix remove a source of uncontrolled = variability? Just what is varying that is to be avoided? Sometimes ofmsr on the PowerMac G5 Quad-Core that I most frequently use = looks like (ofmsr addresses specific to my build of the time): (kgdb) x/5gx 0xc3b328 0xc3b328 : 0x1000000000003030 0x0000000000000001 0xc3b338 : 0x0000000001c35ec0 0x0000000000000000 0xc3b348 : 0x000000007ff7e800 So ofmsr[1]=3D=3D1. Other times ofmsr for the same build looks like: (kgdb) x/5gx 0xc3b328 0xc3b328 : 0x1000000000003030 0x0000000000000000 0xc3b338 : 0x0000000001c35ec0 0x0000000000000000 0xc3b348 : 0x000000007ff7e800 So ofwmsr[1]=3D=3D0. So far I've not observed any other ofmsr[1] values. I'll keep monitoring = for a while.=20 ofmsr[1] is the source of the boot-to-boot variability in what is copied = to SPRG0 before ofwcall in official FreeBSD powerpc64 builds for my = testing contexts. This copy to SPRG0 happens via openfirmware_core and = its use of ofw_sprg_prepare. Leaving the FreeBSD SPRG0 value in place (ignoring ofwmsr[1]) when = preparing to call ofwcall sidesteps this particular uncontrolled = variability. The result is highly reliable booting for the G5's I'm = testing on: no hangs so far. Thus instead of: __asm __volatile("mfsprg0 %0\n\t" "mtsprg0 %1\n\t" "mtsprg1 %2\n\t" "mtsprg2 %3\n\t" "mtsprg3 %4\n\t" : "=3D&r"(ofw_sprg0_save) : "r"(ofmsr[1]), "r"(ofmsr[2]), "r"(ofmsr[3]), "r"(ofmsr[4])); in my builds I'm using code that does: __asm __volatile("mfsprg0 %0\n\t" "mtsprg1 %1\n\t" "mtsprg2 %2\n\t" "mtsprg3 %3\n\t" : "=3D&r"(ofw_sprg0_save) : "r"(ofmsr[2]), "r"(ofmsr[3]), "r"(ofmsr[4])); =3D=3D=3D Mark Millard markmi at dsl-only.net From owner-freebsd-ppc@FreeBSD.ORG Tue Mar 3 08:12:08 2015 Return-Path: Delivered-To: freebsd-ppc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 1A856145 for ; Tue, 3 Mar 2015 08:12:08 +0000 (UTC) Received: from asp.reflexion.net (outbound-242.asp.reflexion.net [69.84.129.242]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C92601B8 for ; Tue, 3 Mar 2015 08:12:07 +0000 (UTC) Received: (qmail 20344 invoked from network); 3 Mar 2015 08:11:59 -0000 Received: from unknown (HELO mail-cs-01.app.dca.reflexion.local) (10.81.19.1) by 0 (rfx-qmail) with SMTP; 3 Mar 2015 08:11:59 -0000 Received: by mail-cs-01.app.dca.reflexion.local (Reflexion email security v7.40.1) with SMTP; Tue, 03 Mar 2015 03:11:59 -0500 (EST) Received: (qmail 25040 invoked from network); 3 Mar 2015 08:11:59 -0000 Received: from unknown (HELO iron2.pdx.net) (69.64.224.71) by 0 (rfx-qmail) with (DHE-RSA-AES256-SHA encrypted) SMTP; 3 Mar 2015 08:11:59 -0000 X-No-Relay: not in my network Received: from [192.168.1.8] (c-67-189-19-145.hsd1.or.comcast.net [67.189.19.145]) by iron2.pdx.net (Postfix) with ESMTPSA id 1C20D1C405E for ; Tue, 3 Mar 2015 00:11:58 -0800 (PST) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2070.6\)) Subject: Re: cb_dumpdata vs. PowerMac G5's (or at least my SSD context): add involvement of dumpinfo's maxiosize value? From: Mark Millard In-Reply-To: <9BF9F7F8-16B3-4E23-8393-B72D01C96215@dsl-only.net> Date: Tue, 3 Mar 2015 00:11:57 -0800 Content-Transfer-Encoding: quoted-printable Message-Id: <82C75BAE-2EB0-4A25-BEF6-E7FF7C7AE9DC@dsl-only.net> References: <84EBF11A-FB29-440B-BA0F-9FA94F1501AD@dsl-only.net> <9F6AE9A1-CDE0-47F9-9EF6-1C3710A5C59B@dsl-only.net> <9BF9F7F8-16B3-4E23-8393-B72D01C96215@dsl-only.net> To: FreeBSD PowerPC ML X-Mailer: Apple Mail (2.2070.6) X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Mar 2015 08:12:08 -0000 The code on 11.0-CURRENT had been updated on 2015-Jan-7 and seems better = in that it involves di->maxiosize --but it would still be broken for my = context because in that context even if the 11.0-CURRENT code was in = use: 0) adadump in sys/cam/ata/ata_da.c would be in use as di->dumper for my = context and it always does DMA style I/O. 1) The ata_channel has the property: dma.max_iosize < di->maxiosize. (So = far as I know this kind of relationship is possibly valid as long as = non-DMA I/O is allowed in some form. Otherwise di->maxiosize is too = large for my context --and that would be geom's problem since it = assigned the value(?).) 2) Nothing else from dumpsys_cb_dumpdata in sys/kern/kern_dump.c and = what it calls or from the parts of sys/geom/... that contribute to = di->maxiosize involves the ata_channel's dma.max_iosize. 3) Both sys/powerpc/powermac/ata_dbdma.c's ata_dbdma_load and = sys/dev/ata/ata_dma.c's ata_dmaload check the ata_channel's = dma.maxiosize vs. the requested byte count and return a failure code = after a message when the request is too big: static int ata_dmaload(struct ata_request *request, void *addr, int *entries) { struct ata_channel *ch =3D device_get_softc(request->parent); ... if (request->bytecount > ch->dma.max_iosize) { device_printf(request->parent, "FAILURE - oversized DMA transfer attempt %d > = %d\n", request->bytecount, ch->dma.max_iosize); return EIO; } ... } and static int ata_dbdma_load(struct ata_request *request, void *addr, int *entries) { struct ata_channel *ch =3D device_get_softc(request->parent); ... if (request->bytecount > ch->dma.max_iosize) { device_printf(request->dev, "FAILURE - oversized DMA transfer attempt %d > %d\n", request->bytecount, ch->dma.max_iosize); return EIO; } ... } So overall those would be the failures and the messages that I would get = unless I change something and build my own kernel. As far as I can tell there was no intent for the 11.0-CURRENT's update = in this area to fix this sort of thing: it was just a refactoring of = existing code without adding additional interfaces between the parts to = make more contexts able to dump in official FreeBSD builds. =3D=3D=3D Mark Millard markmi at dsl-only.net On 2015-Mar-1, at 07:07 PM, Mark Millard wrote: Justing H. wrote: > This was working in the original powerpc64 dump code. Look at = r257941,=20 > which was the original code that I committed. I guess the DMA size=20 > clamping didn't get migrated to the new dump code. So looking around... Using Sticky Revision 257941 shows /head at 257941. sys/powerpc/aim/mmu_oea64.c is what was changed in 257941: adding = moea64_dumpsys_map and moea64_scan_md and the MMUMETHOD entries = mmu_scan_md and mmu_dumpsys_map . For /stable/10/sys/powerpc/aim/mmu_oea64.c the MFC that includes 257941 = is revision 260672 and the most recent code is 279920. = moea64_dumpsys_map, moea64_scan_md, mmu_scan_md, and mmu_dumpsys_map are = still there. First a reminder of the usage context for the two routines (pmap_scan_md = and pmap_dumpsys_map route to the matching moea64_.* routines). static int foreach_chunk(callback_t cb, void *arg) { struct pmap_md *md; int error, seqnr; seqnr =3D 0; md =3D pmap_scan_md(NULL); while (md !=3D NULL) { error =3D (*cb)(md, seqnr++, arg); if (error) return (-error); md =3D pmap_scan_md(md); } return (seqnr); } ... (The below is from my DFLTPHYS/2 variant of the original.) ... static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (0=3D=3Ddi) ? 0 : = (di->maxiosizemaxiosize : DFLTPHYS/2; /* If md->md_size turns out to be 0 the = above avoids derefercing di. * The original code that ignored = di->maxiosize had that property * overall. So this update does too. */ ... while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; va =3D pmap_dumpsys_map(md, ofs, &sz); ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); pmap_dumpsys_unmap(md, ofs, va); ... } printf("... %s\n", (error) ? "fail" : "ok"); return (error); } Then the routine that the signature/interface gives the potential to = adjust the size: vm_offset_t moea64_dumpsys_map(mmu_t mmu, struct pmap_md *md, vm_size_t ofs, vm_size_t *sz) { if (md->md_vaddr =3D=3D ~0UL) return (md->md_paddr + ofs); else return (md->md_vaddr + ofs); } This code ignores its sz argument. NULL could have been passed in for sz = and nothing would change. As stands pmap_dumpsys_map/moea64_dumpsys_map only determine the = starting address, leaving sz alone. It is not clear to me that moea64_dumpsys_map would have access to the = dma.max_iosize information for the ata_channel that happens to be in = use. Summary of my looking at pmap_scan_md and pmap_dumpsys_map usage: no = effect on the DMA size used and it may not be the appropriate context = for an ata_channel's dma.max_iosize based sz adjustment. My change to DFLTPHYS/2 as I listed earlier as a possibility did allow = chunks to be written --until chunk 29 got an error in my only test so = far. With DFLTPHYS it was no-go. Anyone with a context that gets a 64*1024 dma.max_iosize would not see = the "no-go" problem and for all I know there are such PowerMac G5 = contexts. So to know if the problem is being tested requires = establishing ata_channel's dma.max_iosize is both involved and is = smaller than 64*1024. I've definitely got that context. =3D=3D=3D Mark Millard markmi at dsl-only.net On 2015-Mar-1, at 04:47 PM, Mark Millard wrote: Unfortunately reporting the trace of finding what is happening for the = DMA size panic-dump issue for powerpc64 on PowerMac G5's (and others = FreeBSDs?) is rather long... My test of trying a variant of my example code still ended up trying for = a 64K DMA when only 32K is allowed according to the error message it = generated. It would appear the dumperinfo's maxiosize is too big as well. Looking = around... $ find sys -name '*.[hcsm]' -exec grep "\" {} \; -print = | more "FAILURE - oversized DMA transfer attempt %d > = %d\n", sys/dev/ata/ata-dma.c "FAILURE - oversized DMA transfer attempt %d > %d\n", sys/powerpc/powermac/ata_dbdma.c static int ata_dmaload(struct ata_request *request, void *addr, int *entries) { struct ata_channel *ch =3D device_get_softc(request->parent); ... if (request->bytecount > ch->dma.max_iosize) { device_printf(request->parent, "FAILURE - oversized DMA transfer attempt %d > = %d\n", request->bytecount, ch->dma.max_iosize); return EIO; } ... } and static int ata_dbdma_load(struct ata_request *request, void *addr, int *entries) { struct ata_channel *ch =3D device_get_softc(request->parent); ... if (request->bytecount > ch->dma.max_iosize) { device_printf(request->dev, "FAILURE - oversized DMA transfer attempt %d > %d\n", request->bytecount, ch->dma.max_iosize); return EIO; } ... } These suggest that the dumperinfo's maxiosize might sometimes be = legitimately bigger than ata_channel's dma.max_iosize since = dma.max_iosize would be very specific to DMA transfers. So it would appear that either: A) ata_channel's dma.max_iosize should also be considered in = dump_machdep.c . or B) dumperinfo's maxiosize value should in part be based on ata_channel's = dma.max_iosize when an ata_channel is involved and DMA would be = involved. Then looking... $ find sys -name '*.[hcSm]' -exec grep "\" {} \; -print | = more =20= maxdumpsz =3D di->maxiosize; sys/mips/mips/minidump_machdep.c maxdumppgs =3D min(di->maxiosize / PAGE_SIZE, MAXDUMPPGS); sys/x86/x86/dump_machdep.c gkd->di.maxiosize =3D DFLTPHYS; sys/geom/raid/g_raid.c gkd->di.maxiosize =3D dp->d_maxsize; sys/geom/geom_disk.c maxdumpsz =3D min(di->maxiosize, MAXDUMPPGS * PAGE_SIZE); sys/i386/i386/minidump_machdep.c maxdumpsz =3D min(di->maxiosize, MAXDUMPPGS * PAGE_SIZE); sys/amd64/amd64/minidump_machdep.c u_int maxiosize; /* Max size allowed for an individual I/O = */ sys/sys/conf.h maxdumpsz =3D di->maxiosize; sys/arm/arm/minidump_machdep.c u_int max_trans_sz =3D (0=3D=3Ddi) ? 0 : (di->maxiosizemaxiosize : DFLTPHYS; * The original code that ignored = di->maxiosize had that property sys/powerpc/powerpc/dump_machdep.c static void g_disk_kerneldump(struct bio *bp, struct disk *dp) { struct g_kerneldump *gkd; struct g_geom *gp; gkd =3D (struct g_kerneldump*)bp->bio_data; ... gkd->di.maxiosize =3D dp->d_maxsize; ... } So that would trace back to disk's d_maxsize. The only assignment to the = field that I find is in g_disk_access: g_disk_access(struct g_provider *pp, int r, int w, int e) { struct disk *dp; struct g_disk_softc *sc; int error; g_trace(G_T_ACCESS, "g_disk_access(%s, %d, %d, %d)", pp->name, r, w, e); g_topology_assert(); sc =3D pp->private; if (sc =3D=3D NULL || (dp =3D sc->dp) =3D=3D NULL || = dp->d_destroyed) { ... return (ENXIO); } ... if ((pp->acr + pp->acw + pp->ace) =3D=3D 0 && (r + w + e) > 0) { ... if (dp->d_maxsize =3D=3D 0) { printf("WARNING: Disk drive %s%d has no = d_maxsize\n", dp->d_name, dp->d_unit); dp->d_maxsize =3D DFLTPHYS; } ... } So it appears that the caller(s) of disk_create need to supply the value = to the field. Looking at sys/cam/ata/ata_da.c's calling code... #ifndef ata_disk_firmware_geom_adjust #define ata_disk_firmware_geom_adjust(disk) #endif ... static cam_status adaregister(struct cam_periph *periph, void *arg) { struct ada_softc *softc; struct ccb_pathinq cpi; struct ccb_getdev *cgd; char announce_buf[80], buf1[32]; struct disk_params *dp; caddr_t match; u_int maxio; int legacy_id, quirks; ... bzero(&cpi, sizeof(cpi)); xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code =3D XPT_PATH_INQ; xpt_action((union ccb *)&cpi); ... maxio =3D cpi.maxio; /* Honor max I/O size of SIM */ if (maxio =3D=3D 0) maxio =3D DFLTPHYS; /* traditional default */ else if (maxio > MAXPHYS) maxio =3D MAXPHYS; /* for safety */ if (softc->flags & ADA_FLAG_CAN_48BIT) maxio =3D min(maxio, 65536 * softc->params.secsize); else /* 28bit ATA command limit = */ maxio =3D min(maxio, 256 * softc->params.secsize); softc->disk->d_maxsize =3D maxio; ... ata_disk_firmware_geom_adjust(softc->disk); ... } So far I do not see any hint of a ata_channel's dma.max_iosize being = involved in setting d_maxsize. (Only pc98 and sparc64 seem to have = ata_disk_firmware_geom_adjust definitions.) As overall there may not be a global requirement to use DMA this may = well make sense. But it would mean that when DMA is to be used and it is an ata_channel = context that the ata_channel's dma.max_iosize should be consulted. (Not = that ata_channel need be the only context with such an issue. But it is = the one involved in my problem.) Looking around I find the following assignments: $ find sys -name '*.[hcSm]' -exec grep "\" {} \; -print | = more = =20 ch->dma.max_iosize =3D (ATA_SIIPRB_DMA_ENTRIES - 1) * PAGE_SIZE; sys/dev/ata/chipsets/ata-siliconimage.c ch->dma.max_iosize =3D 65536; sys/dev/ata/chipsets/ata-promise.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-serverworks.c ch->dma.max_iosize =3D (ATA_AHCI_DMA_ENTRIES - 1) * PAGE_SIZE; sys/dev/ata/chipsets/ata-ahci.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-cyrix.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-national.c if (ch->dma.max_iosize > 256 * 512) ch->dma.max_iosize =3D 256 * 512; sys/dev/ata/chipsets/ata-acerlabs.c ch->dma.max_iosize =3D 64 * DEV_BSIZE; sys/dev/ata/chipsets/ata-marvell.c ... (no assignment) ... sys/dev/ata/ata-all.c ... (no assignment) ... sys/dev/ata/ata-all.h if (ch->dma.max_iosize =3D=3D 0) ch->dma.max_iosize =3D MIN((ATA_DMA_ENTRIES - 1) * PAGE_SIZE, = MAXPHYS); NULL, NULL, ch->dma.max_iosize, NULL, NULL, ch->dma.max_iosize, if (request->bytecount > ch->dma.max_iosize) { request->bytecount, ch->dma.max_iosize); sys/dev/ata/ata-dma.c ... (no assignment) ... sys/arm/mv/mv_sata.c ... (no assignment) ... sys/powerpc/powermac/ata_dbdma.c ... (no assignment) ... sys/cam/ctl/ctl_backend_block.c All but possibly the last being ata contexts for the field name = max_iosize . In sys/sys/param.h I find: #define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */ #define DEV_BSIZE (1<" {} \; -print | = more =20= #define ATA_AHCI_DMA_ENTRIES 129 struct ata_ahci_dma_prd prd_tab[ATA_AHCI_DMA_ENTRIES]; #define ATA_DMA_ENTRIES 256 sys/dev/ata/ata-all.h and sys/powerpc/include/param.h has: #define PAGE_SHIFT 12 #define PAGE_SIZE (1L << PAGE_SHIFT) /* Page size */ #define PAGE_MASK (vm_offset_t)(PAGE_SIZE - 1) So PAGE_SIZE =3D=3D 4096 for the context. So any ATA_..._ENTRIES * = PAGE_SIZE alternatives are not involved in my problem. Looking at what dumper is assigned... static void g_disk_kerneldump(struct bio *bp, struct disk *dp) { struct g_kerneldump *gkd; struct g_geom *gp; ... if (dp->d_dump =3D=3D NULL) { g_io_deliver(bp, ENODEV); return; } gkd->di.dumper =3D dp->d_dump; ... } where sys/cam/ata/ata_da.c has: static cam_status adaregister(struct cam_periph *periph, void *arg) { struct ada_softc *softc; ... softc->disk->d_dump =3D adadump; ... } adadump has no logic to limit its I/O requests by the dma.max_iosize = when given a length bigger than that. sys/cam/ata/ata_da.c has no text = "dma" at all. But adadump does have: adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, = size_t length) { ... if ((softc->flags & ADA_FLAG_CAN_48BIT) && (lba + count >=3D ATA_MAX_28BIT_LBA || count >=3D 256)) { ata_48bit_cmd(&ccb.ataio, ATA_WRITE_DMA48, 0, lba, count); } else { ata_28bit_cmd(&ccb.ataio, ATA_WRITE_DMA, 0, lba, count); } ... } which makes the I/O a DMA based I/O for sure. I do not see that sys/cam/ata/... explicitly uses or exposes = ata_channel's dma.max_iosize in any way. As a matter of interfacing I would expect that --just like the dumper = field gets into the appropriate cam code-- any abstraction spanning = dma.max_iosize sorts of issues would also reference something that gets = into the cam code that matches up with the dumper cam code. There seems to be no such interface. One could imagine a new dumpinfo = field (look for the dumper_adjusted_maxsize below): static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (di->maxiosizemaxiosize : = DFLTPHYS; ... max_trans_sz =3D di->dumper_adjusted_maxsize(di->priv, = max_trans_sz); ... printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } (Middle layers would need to be set up to allow plugging in the value = into dumpinfo's new field and sys/cam/ata/... would need ata_channel's = dma.max_iosize access and use of it.) In many cases dumper_adjusted_maxsize might be an identity operation (no = adjustment) or a simple maximum operation but for sys/cam/ata/ata_da.c = contexts its main purpose would be to apply DMA size limitations if they = are smaller than the parameter passed in. Out of all this my overall conclusion is that there is a hole in the = FreeBSD design and without some design changes the technique is to = change the constant values used in cb_dumpdata to values that happen to = work. In this simpler line of things it leaves me wondering if something like = DFLTPHYS/2 would be appropriate for dumper contexts in official = 10.1-STABLE FreeBSD for now: static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (di->maxiosizemaxiosize : = DFLTPHYS/2; ... printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } More of the existing ch->dma.max_iosize assignments would not be = exceeded and so more contexts could then generate panic dumps. Context for the experiment that prompted the above looking around: $ freebsd-version -ku; uname -a 10.1-RELEASE-p6 10.1-STABLE FreeBSD FBSDG5M1 10.1-RELEASE-p6 FreeBSD 10.1-RELEASE-p6 #21 r279264M: = Sun Mar 1 03:31:59 PST 2015 = root@FBSDG5M1:/usr/obj/usr/home/markmi/src_10_1_releng/sys/GENERIC64vtsc = powerpc $ svnlite st ? .snap M sys/ddb/db_main.c M sys/ddb/db_script.c M sys/powerpc/conf ? sys/powerpc/conf/GENERIC64vtsc M sys/powerpc/ofw/ofw_machdep.c M sys/powerpc/ofw/ofwcall64.S M sys/powerpc/powerpc/dump_machdep.c $ svnlite info Path: . Working Copy Root Path: /usr/src URL: https://svn0.us-west.freebsd.org/base/stable/10 Relative URL: ^/stable/10 Repository Root: https://svn0.us-west.freebsd.org/base Repository UUID: ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f Revision: 279201 Node Kind: directory Schedule: normal Last Changed Author: pluknet Last Changed Rev: 279201 Last Changed Date: 2015-02-23 00:45:42 -0800 (Mon, 23 Feb 2015) $ svnlite diff sys/powerpc/powerpc/dump_machdep.c | more Index: sys/powerpc/powerpc/dump_machdep.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/powerpc/powerpc/dump_machdep.c (revision 279201) +++ sys/powerpc/powerpc/dump_machdep.c (working copy) @@ -113,6 +113,11 @@ cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; + u_int max_trans_sz =3D (0=3D=3Ddi) ? 0 : = (di->maxiosizemaxiosize : DFLTPHYS; + /* If md->md_size turns out to be 0 the = above avoids derefercing di. + * The original code that ignored = di->maxiosize had that property + * overall. So this update does too. + */ vm_offset_t va; size_t counter, ofs, resid, sz; int c, error, twiddle; @@ -124,10 +129,10 @@ ofs =3D 0; /* Logical offset within the chunk */ resid =3D md->md_size; - printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); + printf(" chunk %d: %lu bytes max_trans_sz %lu ", seqnr, = (u_long)resid, (u_long)max_trans_sz); while (resid) { - sz =3D (resid > DFLTPHYS) ? DFLTPHYS : resid; + sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; va =3D pmap_dumpsys_map(md, ofs, &sz); counter +=3D sz; if (counter >> 24) { =3D=3D=3D Mark Millard markmi at dsl-only.net On 2015-Mar-1, at 04:14 AM, Mark Millard wrote: Context: 10.1-STABLE powerpc64 for PowerMac G5 I'm unable to get panic dumps because the DMA size is rejected, 64K = being too big. I'd like to get things to the point where panic dumps are = possible for that context. Looking around I find: root@FBSDG5M1:/usr/src # grep DFLTPHYS sys/sys/*.h sys/sys/param.h:#ifndef DFLTPHYS sys/sys/param.h:#define DFLTPHYS (64 * 1024) /* default max = raw I/O transfer size */ sys/sys/param.h:#define MAXDUMPPGS (DFLTPHYS/PAGE_SIZE) root@FBSDG5M1:/usr/src # grep DFLTPHYS sys/powerpc/powerpc/* sys/powerpc/powerpc/dump_machdep.c: sz =3D (resid > = DFLTPHYS) ? DFLTPHYS : resid; static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; ... resid =3D md->md_size; ... while (resid) { sz =3D (resid > DFLTPHYS) ? DFLTPHYS : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } Which may well be where the 64K is from. sys/sys/conf.h has: struct dumperinfo { dumper_t *dumper; /* Dumping function. */ void *priv; /* Private parts. */ u_int blocksize; /* Size of block in bytes. */ u_int maxiosize; /* Max size allowed for an individual I/O = */ off_t mediaoffset; /* Initial offset in bytes. */ off_t mediasize; /* Space available in bytes. */ }; So it would appear that maxiosize from dumperinfo was supposed to be = involved. But at this level nothing is checking dumperinfo's maxiosize = field value to avoid using anything bigger. It may be that the di->dumper is supposed to deal with allowed sizes = being smaller than its size parameter indicates (sz here). But then = exposing maxiosize in dumperinfo would seem a bit odd as an interface. My initial guess would be that cb_dumpdata should be more like: static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di =3D (struct dumperinfo*)arg; u_int max_trans_sz =3D (di->maxiosizemaxiosize : = DFLTPHYS; ... printf(" chunk %d: %lu bytes ", seqnr, (u_long)resid); while (resid) { sz =3D (resid > max_trans_sz) ? max_trans_sz : resid; ... error =3D di->dumper(di->priv, (void*)va, 0, dumplo, sz); ... } I have assumed that even when 0=3D=3Dresid that 0!=3Darg: the origin = code would not dereference di in that kind of context so a little more = conditional logic might be required if that property needs to be = preserved. Anyone know if I seem to be going in a reasonable direction for this? I've only noted the large transfer size that I found. Many other places = use a di->dumper with the size of something much smaller or with a = smaller symbolic constant (such as having value 512). Again there is no = maxiosize handling. It seems there there is an expected (implicit?) = minimum size for maxiosize such that these various things would always = fit. =46rom that point of view I'm just objecting to DFLTPHYS being that = minimum I guess: I want a smaller minimum so that I can get dumps from = my existing configuration. =3D=3D=3D Mark Millard markmi at dsl-only.net