From:	SMTP%"MACRO32@WKUVX1.WKU.EDU" 22-JUN-1994 08:15:34.51
To:	EVERHART
CC:	
Subj:	Re: Count of bad pages - where is it?

X-Listname: "VMS Internals, MACRO, & BLISS Discussions" <MACRO32@WKUVX1.WKU.EDU>
Warnings-To: <>
Errors-To: owner-macro32@WKUVX1.WKU.EDU
Sender: owner-macro32@WKUVX1.WKU.EDU
Date: Wed, 22 Jun 1994 10:03:18 +0100
From: Arne Vajhoej <ARNE@kopc.hhs.dk>
Reply-To: MACRO32@WKUVX1.WKU.EDU
Subject: Re: Count of bad pages - where is it?
To: MACRO32@WKUVX1.WKU.EDU, David.Sneddon@woodside.otc.au
Message-Id: <01HDU7G2F6UQ90MVL8@kopc.hhs.dk>
X-Vms-To: KOPC::IN%"MACRO32@WKUVX1.WKU.EDU"
X-Vms-Cc: IN::"David.Sneddon@Woodside.otc.au"
Mime-Version: 1.0
Content-Type: TEXT/PLAIN; CHARSET=ISO-8859-1
Content-Transfer-Encoding: 8BIT

> Below is the result of a show memory command which shows that there is one
> bad page (the system was recently rebooted, there are usually many more).
> I have a program that gives me memory stats in a different format e.g. with
> percentages, global page stats etc. and has a check for bad pages.
> However the check for bad pages doesn't pick up anything.  I am examining
> the location MPW$GL_BADPAGTOTAL as this is the only reference I could find
> by checking symbols within SDA.  Since I am not getting anything, the info
> is obviously somewhere else - so the question... where is this info hidden?
> There were no other symbols that looked like they obviously had the info
> I was after.
> DEC are currently looking at why these errors are occurring but as yet have
> no answers.  I was thinking of having a detached job which checks on a
> regular basis and notifies me when new errors have occurred.  (As well as
> getting the original program mentioned above to give me the correct info.)
> 
>               System Memory Resources on 22-JUN-1994 10:29:52.37
> 
> Physical Memory Usage (pages):     Total        Free      In Use    Modified
>   Main Memory (32.00Mb)            65536       12265       50843        2428
> 
>   Bad Pages                        Total     Dynamic  I/O Errors      Static
>                                        1           1           0           0
> 
> Of the physical pages in use, 35806 pages are permanently allocated to VMS.

Nick de Smith once wrote the little piece of DCL attached below.
I have not tested it with bad pages, but everything else works fine !

                                                          Arne

Arne Vajhxj                             local DECNET:  KO::ARNE
Computer Department                     PSI:           PSI%238310013040::ARNE
Business School of Southern Denmark     Internet:      ARNE@KO.HHS.DK

================================================================================

$       Setv = 'F$Verify( "No" )
$!+
$!      SHOW_MEMORY.COM         A DCL form of the DCL SHOW MEMORY command
$!
$!      Author          : Nick de Smith         NICK@NCDLAB.ULCC.AC.UK
$!      Date            : 19-Jul-91
$!
$!      Edit    Edit date       By      Why
$!       01     19-Jul-91       NMdS    New
$!
$       Copyright = ") 1991 by Nick de Smith"
$!
$!      This software is provided for interest only. It may not be lent,
$!      copied or used in any way for the purpose of profit. The author
$!      accepts no responsibility for any action that may result from the
$!      use of this software.
$!      This software may be copied (keeping this copyright notice) and used
$!      freely providing the above conditions are observed.
$!
$! Description:
$!      This is a weird, sick, and nasty DCL command file that does the equivalent of a DCL
$!      SHOW MEMORY command for and VAX/VMS configuration. It should always be accurate.
$!      No images except DCL.EXE are used.
$!
$!      I suppose that if there is any value in this sort of rubbish, it is to demonstrate
$!      the usage of bizarre or little known features of DCL. NO UNDOCUMENTED FEATURE is used herein.
$!      The corollary of this, of course, is that no documented feature is unused! (not quite true).
$!
$       Set Symbol /Scope=( NoLocal )                                    ! Insulate ourselves
$!
$       Name    = F$Parse( F$Environment( "PROCEDURE" ),,, "NAME" )
$       Info    = "%" + Name + "-I, "                                    ! Information message
$       Warn    = "%" + Name + "-W, "                                    ! Warning message
$       Fatal   = "%" + Name + "-F, "                                    ! Fatal error message
$       Say     = "Write SYS$OUTPUT"                                     ! Print to terminal
$!
$       Call GET_MEMORY                                                  ! Collect all the memory info
$!
$! We now have:
$!      Physical_Pages          Number of pages available for the system this boot
$!      Real_Physical_Pages     Number of pages of memory actually fitted to the VAX
$!      Free_Pages              Number of pages on the free list
$!      Modified_Pages          Number of pages on the modified list
$!      Inuse_Pages             Number of pages in use by the system (including VMS)
$!      VMS_Pages               Number of the "Inuse_Pages" in use by VMS
$!      Bad_Pages               Number of bad pages in the system (both at boot, and since boot)
$!
$       Say F$Fao( "!/Physical Memory Usage (pages):     Total        Free      In Use    Modified" )
$       Say F$Fao( "  Main Memory !10<(!UL.!ASMb)!>         !7UL     !7UL     !7UL     !7UL", -
                Physical_Pages / 2048, F$Element( (Physical_Pages / 512) .and. 3, ",", "00,25,50,75" ), Physical_pages, -
                Free_Pages, Inuse_Pages, Modified_Pages )
$!
$       If Physical_Pages .ne. Real_Physical_Pages
$       Then    Say "!/The SYSGEN parameter PHYSICALPAGES has been used to constrain this system"
$               Say F$Fao( "There are !UL page!%S (!UL.!AS) configured in this VAX", Real_Physical_Pages, -
                        Real_Physical_Pages / 2048, F$Element( (Real_Physical_Pages / 512) .and. 3, ",", "00,25,50,75" ) )
$       Endif
$       Say F$Fao( "!/Of the physical pages in use, !UL page!%S are permanently allocated to VMS.", VMS_Pages )
$!
$! The following FAO is an example of the conditional FAO. If it blows up on your system, replace the control string with
$! something more sensible, like "Total of !UL bad page!%S found".
$!
$       Say F$Fao( "!/There !0UL!1%Cis!%Eare!%F !-!UL bad page!%S", Bad_Pages )
$!
$       Exit
$!
$ GET_MEMORY:   SubRoutine
$! From SYS$SYSTEM:SYS.MAP for VMS V5.4-2 - should be good for and VMS V5 system
$       EXE$GL_RPB      = %x80008484                                    ! => System Restart Parameter Block
$       MMG$GL_PHYPGCNT = %x800080c0                                    ! Configured (SYSGEN) limit on pages
$       SCH$GL_FREECNT  = %x80004018                                    ! Number of free pages
$               PFN$C_BADPAGLST = %x02                                   ! ...Offset to count of bad pages in longwords
$       SCH$GL_MFYCNT   = %x8000401c                                    ! Number of modified pages
$       PFN$GL_PHYPGCNT = %x80004024                                    ! Physical pages for process use
$!
$! From $NDTDEF  - Nexus Device Type codes
$       NDT$_MPM0       = %x0040                                        ! Multiport Memory 0
$       NDT$_MPM3       = %x0043                                        !     ''      ''   3
$!
$! From $RPBDEF - Restart Parameter Block
$       RPB$L_MEMDSC    = %xBC                                          ! Offset into RPB for memory descriptors
$       RPB$C_NMEMDSC   = %x8                                           ! Max. number of memory descriptor
$!typedef struct MEMDSC {
$!      unsigned page_count     : 24;                           /* Number of pages in this descriptor */
$!      unsigned tr_number      : 8;                            /* Adaptor type number   */
$!      unsigned base_pfn       : 32;                           /* Base PFN for this memory  */
$!} MEMDSC, *MEMDSC_PTR;
$       RPB$C_MEMDSCSIZ = %x8                                           ! Size of a memory descriptor
$       RPB$L_BOOTR5    = %x30                                          ! Offset into RPB copy of boot time R5
$               RPB$M_MPM       = %x00000800                            ! Use MultiPortMemory only
$               RPB$M_USEMPM    = %x00001000                            ! Use MultiPortMemory as well as local memory
$       RPB$L_BADPGS    = %x104                                         ! Count of bad pages at boot time
$!
$       RPB             = F$CvUI( 0, 32, F$Fao( "!AD", 4, EXE$GL_RPB ) ) ! => RPB
$       Boot_R5         = F$CvUI( 0, 32, F$Fao( "!AD", 4, RPB + RPB$L_BOOTR5 ) ) ! R5 flags used when booting the system
$       Local_Pages     = 0                                             ! Count of local memory pages
$       Multiport_Pages = 0                                             ! Count of multiport memory pages
$!
$       Loop     = RPB$C_NMEMDSC
$       MEMDSC = RPB + RPB$L_MEMDSC                                     ! => first memory descriptor
$!
$ 10$:  If Loop .eq. 0 Then Goto 20$
$       Page_Count      = F$CvUI( 0, 24, F$Fao( "!AD", 3, MEMDSC ) )    ! Get the page count
$       If Page_Count .eq. 0 Then Goto 20$
$       TR_Number       = F$CvUI( 24, 8, F$Fao( "!AD", 4, MEMDSC ) )    ! Get the adaptor number
$       MEMDSC = MEMDSC + RPB$C_MEMDSCSIZ
$       Loop = Loop - 1
$!
$!      If adapter is within MPM range, then its multiport memory. An assumption is made here that all memory
$!      with adaptor numbers in the range NDT$_MPM0 to NDT$_MPM3 is multiport memory, and that no multiport
$!      memory has an adaptor number outside of this range.
$!
$       If (TR_Number .ge. NDT$_MPM0) .and. (TR_Number .le. NDT$_MPM3)
$       Then    Multiport_Pages = Multiport_Pages + Page_Count
$       Else    Local_Pages = Local_Pages + Page_Count
$       EndIf
$!
$       Goto 10$                                                        ! Get next memory adaptor
$ 20$:
$!
$! Check the boot flags (/R5:xxxxxxxx) for the memory configuration (really for 11/782s only)
$!
$       If (Boot_R5 .and. RPB$M_MPM) .ne. 0                             ! If this is a multiprocessor configuration...
$       Then    Real_Physical_Pages == Multiport_Pages                  ! ...then we are only using shared memory
$       Else    Real_Physical_Pages == Local_Pages                      ! The system is using the local memory
$               If (Boot_R5 .and. RPB$M_USEMPM) .ne. 0                  ! If USEMPM is set, we are using MPM as well...
$               Then    Real_Physical_Pages == Real_Physical_Pages + Multiport_Pages ! ...so add in the multiport memory pages
$               EndIf
$       EndIf
$!
$! Check to see if the SYSGEN PHYSICALPAGES parameter has been used to limit the usable number of pages
$!
$       PHYSICALPAGES = F$CvUI( 0, 32, F$Fao( "!AD", 4, MMG$GL_PHYPGCNT ) ) ! SYSGEN PHYSICALPAGES parameter
$       If Real_Physical_Pages .gt. PHYSICALPAGES                       ! If the physical memory count is higher...
$       Then    Physical_Pages == PHYSICALPAGES                         ! ...Usable pages have been limited by SYSGEN
$       Else    Physical_Pages == Real_Physical_Pages                   ! else all memory is enabled
$       EndIf
$!
$       VMS_Pages == Physical_Pages - F$CvUI( 0, 32, F$Fao( "!AD", 4, PFN$GL_PHYPGCNT ) ) ! Get pages used by VMS
$       Bad_Pages == F$CvUI( 0, 32, F$Fao( "!AD", 4, RPB + RPB$L_BADPGS ) )   ! # of bad pages at boot
$       Bad_Pages == Bad_Pages + F$CvUI( 0, 32, F$Fao( "!AD", 4, SCH$GL_FREECNT + 4 * PFN$C_BADPAGLST ) ) ! # of bad pages since boot
$       VMS_Pages == VMS_Pages - Bad_Pages                               ! Don't count bad pages to VMS
$       Free_Pages      == F$CvUI( 0, 32, F$Fao( "!AD", 4, SCH$GL_FREECNT ) ) ! Get count of free pages
$       Modified_Pages  == F$CvUI( 0, 32, F$Fao( "!AD", 4, SCH$GL_MFYCNT ) ) ! Get count of modified pages
$       Inuse_Pages     == Physical_Pages - Free_Pages - Modified_Pages  ! Get pages not used by the lists
$       Return
$!
$ END:  Setv = F$Verify( Setv )
