Файловый менеджер - Редактировать - /var/www/xthruster/html/wp-content/uploads/flags/Documentation.tar
Назад
sound/cards/multisound.sh 0000755 00000110334 14722053057 0011541 0 ustar 00 #! /bin/sh # # Turtle Beach MultiSound Driver Notes # -- Andrew Veliath <andrewtv@usa.net> # # Last update: September 10, 1998 # Corresponding msnd driver: 0.8.3 # # ** This file is a README (top part) and shell archive (bottom part). # The corresponding archived utility sources can be unpacked by # running `sh MultiSound' (the utilities are only needed for the # Pinnacle and Fiji cards). ** # # # -=-=- Getting Firmware -=-=- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # See the section `Obtaining and Creating Firmware Files' in this # document for instructions on obtaining the necessary firmware # files. # # # Supported Features # ~~~~~~~~~~~~~~~~~~ # # Currently, full-duplex digital audio (/dev/dsp only, /dev/audio is # not currently available) and mixer functionality (/dev/mixer) are # supported (memory mapped digital audio is not yet supported). # Digital transfers and monitoring can be done as well if you have # the digital daughterboard (see the section on using the S/PDIF port # for more information). # # Support for the Turtle Beach MultiSound Hurricane architecture is # composed of the following modules (these can also operate compiled # into the kernel): # # snd-msnd-lib - MultiSound base (requires snd) # # snd-msnd-classic - Base audio/mixer support for Classic, Monetery and # Tahiti cards # # snd-msnd-pinnacle - Base audio/mixer support for Pinnacle and Fiji cards # # # Important Notes - Read Before Using # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # The firmware files are not included (may change in future). You # must obtain these images from Turtle Beach (they are included in # the MultiSound Development Kits), and place them in /etc/sound for # example, and give the full paths in the Linux configuration. If # you are compiling in support for the MultiSound driver rather than # using it as a module, these firmware files must be accessible # during kernel compilation. # # Please note these files must be binary files, not assembler. See # the section later in this document for instructions to obtain these # files. # # # Configuring Card Resources # ~~~~~~~~~~~~~~~~~~~~~~~~~~ # # ** This section is very important, as your card may not work at all # or your machine may crash if you do not do this correctly. ** # # * Classic/Monterey/Tahiti # # These cards are configured through the driver snd-msnd-classic. You must # know the io port, then the driver will select the irq and memory resources # on the card. It is up to you to know if these are free locations or now, # a conflict can lock the machine up. # # * Pinnacle/Fiji # # The Pinnacle and Fiji cards have an extra config port, either # 0x250, 0x260 or 0x270. This port can be disabled to have the card # configured strictly through PnP, however you lose the ability to # access the IDE controller and joystick devices on this card when # using PnP. The included pinnaclecfg program in this shell archive # can be used to configure the card in non-PnP mode, and in PnP mode # you can use isapnptools. These are described briefly here. # # pinnaclecfg is not required; you can use the snd-msnd-pinnacle module # to fully configure the card as well. However, pinnaclecfg can be # used to change the resource values of a particular device after the # snd-msnd-pinnacle module has been loaded. If you are compiling the # driver into the kernel, you must set these values during compile # time, however other peripheral resource values can be changed with # the pinnaclecfg program after the kernel is loaded. # # # *** PnP mode # # Use pnpdump to obtain a sample configuration if you can; I was able # to obtain one with the command `pnpdump 1 0x203' -- this may vary # for you (running pnpdump by itself did not work for me). Then, # edit this file and use isapnp to uncomment and set the card values. # Use these values when inserting the snd-msnd-pinnacle module. Using # this method, you can set the resources for the DSP and the Kurzweil # synth (Pinnacle). Since Linux does not directly support PnP # devices, you may have difficulty when using the card in PnP mode # when it the driver is compiled into the kernel. Using non-PnP mode # is preferable in this case. # # Here is an example mypinnacle.conf for isapnp that sets the card to # io base 0x210, irq 5 and mem 0xd8000, and also sets the Kurzweil # synth to 0x330 and irq 9 (may need editing for your system): # # (READPORT 0x0203) # (CSN 2) # (IDENTIFY *) # # # DSP # (CONFIGURE BVJ0440/-1 (LD 0 # (INT 0 (IRQ 5 (MODE +E))) (IO 0 (BASE 0x0210)) (MEM 0 (BASE 0x0d8000)) # (ACT Y))) # # # Kurzweil Synth (Pinnacle Only) # (CONFIGURE BVJ0440/-1 (LD 1 # (IO 0 (BASE 0x0330)) (INT 0 (IRQ 9 (MODE +E))) # (ACT Y))) # # (WAITFORKEY) # # # *** Non-PnP mode # # The second way is by running the card in non-PnP mode. This # actually has some advantages in that you can access some other # devices on the card, such as the joystick and IDE controller. To # configure the card, unpack this shell archive and build the # pinnaclecfg program. Using this program, you can assign the # resource values to the card's devices, or disable the devices. As # an alternative to using pinnaclecfg, you can specify many of the # configuration values when loading the snd-msnd-pinnacle module (or # during kernel configuration when compiling the driver into the # kernel). # # If you specify cfg=0x250 for the snd-msnd-pinnacle module, it # automatically configure the card to the given io, irq and memory # values using that config port (the config port is jumper selectable # on the card to 0x250, 0x260 or 0x270). # # See the `snd-msnd-pinnacle Additional Options' section below for more # information on these parameters (also, if you compile the driver # directly into the kernel, these extra parameters can be useful # here). # # # ** It is very easy to cause problems in your machine if you choose a # resource value which is incorrect. ** # # # Examples # ~~~~~~~~ # # * MultiSound Classic/Monterey/Tahiti: # # modprobe snd # insmod snd-msnd-lib # insmod snd-msnd-classic io=0x290 irq=7 mem=0xd0000 # # * MultiSound Pinnacle in PnP mode: # # modprobe snd # insmod snd-msnd-lib # isapnp mypinnacle.conf # insmod snd-msnd-pinnacle io=0x210 irq=5 mem=0xd8000 <-- match mypinnacle.conf values # # * MultiSound Pinnacle in non-PnP mode (replace 0x250 with your configuration port, # one of 0x250, 0x260 or 0x270): # # modprobe snd # insmod snd-msnd-lib # insmod snd-msnd-pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 # # * To use the MPU-compatible Kurzweil synth on the Pinnacle in PnP # mode, add the following (assumes you did `isapnp mypinnacle.conf'): # # insmod snd # insmod mpu401 io=0x330 irq=9 <-- match mypinnacle.conf values # # * To use the MPU-compatible Kurzweil synth on the Pinnacle in non-PnP # mode, add the following. Note how we first configure the peripheral's # resources, _then_ install a Linux driver for it: # # insmod snd # pinnaclecfg 0x250 mpu 0x330 9 # insmod mpu401 io=0x330 irq=9 # # -- OR you can use the following sequence without pinnaclecfg in non-PnP mode: # # modprobe snd # insmod snd-msnd-lib # insmod snd-msnd-pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 mpu_io=0x330 mpu_irq=9 # insmod snd # insmod mpu401 io=0x330 irq=9 # # * To setup the joystick port on the Pinnacle in non-PnP mode (though # you have to find the actual Linux joystick driver elsewhere), you # can use pinnaclecfg: # # pinnaclecfg 0x250 joystick 0x200 # # -- OR you can configure this using snd-msnd-pinnacle with the following: # # modprobe snd # insmod snd-msnd-lib # insmod snd-msnd-pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 joystick_io=0x200 # # # snd-msnd-classic, snd-msnd-pinnacle Required Options # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # If the following options are not given, the module will not load. # Examine the kernel message log for informative error messages. # WARNING--probing isn't supported so try to make sure you have the # correct shared memory area, otherwise you may experience problems. # # io I/O base of DSP, e.g. io=0x210 # irq IRQ number, e.g. irq=5 # mem Shared memory area, e.g. mem=0xd8000 # # # snd-msnd-classic, snd-msnd-pinnacle Additional Options # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # fifosize The digital audio FIFOs, in kilobytes. If not # specified, the default will be used. Increasing # this value will reduce the chance of a FIFO # underflow at the expense of increasing overall # latency. For example, fifosize=512 will # allocate 512kB read and write FIFOs (1MB total). # While this may reduce dropouts, a heavy machine # load will undoubtedly starve the FIFO of data # and you will eventually get dropouts. One # option is to alter the scheduling priority of # the playback process, using `nice' or some form # of POSIX soft real-time scheduling. # # calibrate_signal Setting this to one calibrates the ADCs to the # signal, zero calibrates to the card (defaults # to zero). # # # snd-msnd-pinnacle Additional Options # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # digital Specify digital=1 to enable the S/PDIF input # if you have the digital daughterboard # adapter. This will enable access to the # DIGITAL1 input for the soundcard in the mixer. # Some mixer programs might have trouble setting # the DIGITAL1 source as an input. If you have # trouble, you can try the setdigital.c program # at the bottom of this document. # # cfg Non-PnP configuration port for the Pinnacle # and Fiji (typically 0x250, 0x260 or 0x270, # depending on the jumper configuration). If # this option is omitted, then it is assumed # that the card is in PnP mode, and that the # specified DSP resource values are already # configured with PnP (i.e. it won't attempt to # do any sort of configuration). # # When the Pinnacle is in non-PnP mode, you can use the following # options to configure particular devices. If a full specification # for a device is not given, then the device is not configured. Note # that you still must use a Linux driver for any of these devices # once their resources are setup (such as the Linux joystick driver, # or the MPU401 driver from OSS for the Kurzweil synth). # # mpu_io I/O port of MPU (on-board Kurzweil synth) # mpu_irq IRQ of MPU (on-board Kurzweil synth) # ide_io0 First I/O port of IDE controller # ide_io1 Second I/O port of IDE controller # ide_irq IRQ IDE controller # joystick_io I/O port of joystick # # # Obtaining and Creating Firmware Files # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # For the Classic/Tahiti/Monterey # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # Download to /tmp and unzip the following file from Turtle Beach: # # ftp://ftp.voyetra.com/pub/tbs/msndcl/msndvkit.zip # # When unzipped, unzip the file named MsndFiles.zip. Then copy the # following firmware files to /etc/sound (note the file renaming): # # cp DSPCODE/MSNDINIT.BIN /etc/sound/msndinit.bin # cp DSPCODE/MSNDPERM.REB /etc/sound/msndperm.bin # # When configuring the Linux kernel, specify /etc/sound/msndinit.bin and # /etc/sound/msndperm.bin for the two firmware files (Linux kernel # versions older than 2.2 do not ask for firmware paths, and are # hardcoded to /etc/sound). # # If you are compiling the driver into the kernel, these files must # be accessible during compilation, but will not be needed later. # The files must remain, however, if the driver is used as a module. # # # For the Pinnacle/Fiji # ~~~~~~~~~~~~~~~~~~~~~ # # Download to /tmp and unzip the following file from Turtle Beach (be # sure to use the entire URL; some have had trouble navigating to the # URL): # # ftp://ftp.voyetra.com/pub/tbs/pinn/pnddk100.zip # # Unpack this shell archive, and run make in the created directory # (you need a C compiler and flex to build the utilities). This # should give you the executables conv, pinnaclecfg and setdigital. # conv is only used temporarily here to create the firmware files, # while pinnaclecfg is used to configure the Pinnacle or Fiji card in # non-PnP mode, and setdigital can be used to set the S/PDIF input on # the mixer (pinnaclecfg and setdigital should be copied to a # convenient place, possibly run during system initialization). # # To generating the firmware files with the `conv' program, we create # the binary firmware files by doing the following conversion # (assuming the archive unpacked into a directory named PINNDDK): # # ./conv < PINNDDK/dspcode/pndspini.asm > /etc/sound/pndspini.bin # ./conv < PINNDDK/dspcode/pndsperm.asm > /etc/sound/pndsperm.bin # # The conv (and conv.l) program is not needed after conversion and can # be safely deleted. Then, when configuring the Linux kernel, specify # /etc/sound/pndspini.bin and /etc/sound/pndsperm.bin for the two # firmware files (Linux kernel versions older than 2.2 do not ask for # firmware paths, and are hardcoded to /etc/sound). # # If you are compiling the driver into the kernel, these files must # be accessible during compilation, but will not be needed later. # The files must remain, however, if the driver is used as a module. # # # Using Digital I/O with the S/PDIF Port # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # If you have a Pinnacle or Fiji with the digital daughterboard and # want to set it as the input source, you can use this program if you # have trouble trying to do it with a mixer program (be sure to # insert the module with the digital=1 option, or say Y to the option # during compiled-in kernel operation). Upon selection of the S/PDIF # port, you should be able monitor and record from it. # # There is something to note about using the S/PDIF port. Digital # timing is taken from the digital signal, so if a signal is not # connected to the port and it is selected as recording input, you # will find PCM playback to be distorted in playback rate. Also, # attempting to record at a sampling rate other than the DAT rate may # be problematic (i.e. trying to record at 8000Hz when the DAT signal # is 44100Hz). If you have a problem with this, set the recording # input to analog if you need to record at a rate other than that of # the DAT rate. # # # -- Shell archive attached below, just run `sh MultiSound' to extract. # Contains Pinnacle/Fiji utilities to convert firmware, configure # in non-PnP mode, and select the DIGITAL1 input for the mixer. # # #!/bin/sh # This is a shell archive (produced by GNU sharutils 4.2). # To extract the files from this archive, save it to some FILE, remove # everything before the `!/bin/sh' line above, then type `sh FILE'. # # Made on 1998-12-04 10:07 EST by <andrewtv@ztransform.velsoft.com>. # Source directory was `/home/andrewtv/programming/pinnacle/pinnacle'. # # Existing files will *not* be overwritten unless `-c' is specified. # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 2064 -rw-rw-r-- MultiSound.d/setdigital.c # 10224 -rw-rw-r-- MultiSound.d/pinnaclecfg.c # 106 -rw-rw-r-- MultiSound.d/Makefile # 146 -rw-rw-r-- MultiSound.d/conv.l # 1491 -rw-rw-r-- MultiSound.d/msndreset.c # save_IFS="${IFS}" IFS="${IFS}:" gettext_dir=FAILED locale_dir=FAILED first_param="$1" for dir in $PATH do if test "$gettext_dir" = FAILED && test -f $dir/gettext \ && ($dir/gettext --version >/dev/null 2>&1) then set `$dir/gettext --version 2>&1` if test "$3" = GNU then gettext_dir=$dir fi fi if test "$locale_dir" = FAILED && test -f $dir/shar \ && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) then locale_dir=`$dir/shar --print-text-domain-dir` fi done IFS="$save_IFS" if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED then echo=echo else TEXTDOMAINDIR=$locale_dir export TEXTDOMAINDIR TEXTDOMAIN=sharutils export TEXTDOMAIN echo="$gettext_dir/gettext -s" fi touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo $echo 'WARNING: not restoring timestamps. Consider getting and' $echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # if mkdir _sh01426; then $echo 'x -' 'creating lock directory' else $echo 'failed to create lock directory' exit 1 fi # ============= MultiSound.d/setdigital.c ============== if test ! -d 'MultiSound.d'; then $echo 'x -' 'creating directory' 'MultiSound.d' mkdir 'MultiSound.d' fi if test -f 'MultiSound.d/setdigital.c' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'MultiSound.d/setdigital.c' '(file already exists)' else $echo 'x -' extracting 'MultiSound.d/setdigital.c' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/setdigital.c' && /********************************************************************* X * X * setdigital.c - sets the DIGITAL1 input for a mixer X * X * Copyright (C) 1998 Andrew Veliath X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2 of the License, or X * (at your option) any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program; if not, write to the Free Software X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X ********************************************************************/ X #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/soundcard.h> X int main(int argc, char *argv[]) { X int fd; X unsigned long recmask, recsrc; X X if (argc != 2) { X fprintf(stderr, "usage: setdigital <mixer device>\n"); X exit(1); X } X X if ((fd = open(argv[1], O_RDWR)) < 0) { X perror(argv[1]); X exit(1); X } X X if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask) < 0) { X fprintf(stderr, "error: ioctl read recording mask failed\n"); X perror("ioctl"); X close(fd); X exit(1); X } X X if (!(recmask & SOUND_MASK_DIGITAL1)) { X fprintf(stderr, "error: cannot find DIGITAL1 device in mixer\n"); X close(fd); X exit(1); X } X X if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) < 0) { X fprintf(stderr, "error: ioctl read recording source failed\n"); X perror("ioctl"); X close(fd); X exit(1); X } X X recsrc |= SOUND_MASK_DIGITAL1; X X if (ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) < 0) { X fprintf(stderr, "error: ioctl write recording source failed\n"); X perror("ioctl"); X close(fd); X exit(1); X } X X close(fd); X X return 0; } SHAR_EOF $shar_touch -am 1204092598 'MultiSound.d/setdigital.c' && chmod 0664 'MultiSound.d/setdigital.c' || $echo 'restore of' 'MultiSound.d/setdigital.c' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'MultiSound.d/setdigital.c:' 'MD5 check failed' e87217fc3e71288102ba41fd81f71ec4 MultiSound.d/setdigital.c SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/setdigital.c'`" test 2064 -eq "$shar_count" || $echo 'MultiSound.d/setdigital.c:' 'original size' '2064,' 'current size' "$shar_count!" fi fi # ============= MultiSound.d/pinnaclecfg.c ============== if test -f 'MultiSound.d/pinnaclecfg.c' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'MultiSound.d/pinnaclecfg.c' '(file already exists)' else $echo 'x -' extracting 'MultiSound.d/pinnaclecfg.c' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/pinnaclecfg.c' && /********************************************************************* X * X * pinnaclecfg.c - Pinnacle/Fiji Device Configuration Program X * X * This is for NON-PnP mode only. For PnP mode, use isapnptools. X * X * This is Linux-specific, and must be run with root permissions. X * X * Part of the Turtle Beach MultiSound Sound Card Driver for Linux X * X * Copyright (C) 1998 Andrew Veliath X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2 of the License, or X * (at your option) any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program; if not, write to the Free Software X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X ********************************************************************/ X #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <asm/types.h> #include <sys/io.h> X #define IREG_LOGDEVICE 0x07 #define IREG_ACTIVATE 0x30 #define LD_ACTIVATE 0x01 #define LD_DISACTIVATE 0x00 #define IREG_EECONTROL 0x3F #define IREG_MEMBASEHI 0x40 #define IREG_MEMBASELO 0x41 #define IREG_MEMCONTROL 0x42 #define IREG_MEMRANGEHI 0x43 #define IREG_MEMRANGELO 0x44 #define MEMTYPE_8BIT 0x00 #define MEMTYPE_16BIT 0x02 #define MEMTYPE_RANGE 0x00 #define MEMTYPE_HIADDR 0x01 #define IREG_IO0_BASEHI 0x60 #define IREG_IO0_BASELO 0x61 #define IREG_IO1_BASEHI 0x62 #define IREG_IO1_BASELO 0x63 #define IREG_IRQ_NUMBER 0x70 #define IREG_IRQ_TYPE 0x71 #define IRQTYPE_HIGH 0x02 #define IRQTYPE_LOW 0x00 #define IRQTYPE_LEVEL 0x01 #define IRQTYPE_EDGE 0x00 X #define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF)) #define LOBYTE(w) ((BYTE)(w)) #define MAKEWORD(low,hi) ((WORD)(((BYTE)(low))|(((WORD)((BYTE)(hi)))<<8))) X typedef __u8 BYTE; typedef __u16 USHORT; typedef __u16 WORD; X static int config_port = -1; X static int msnd_write_cfg(int cfg, int reg, int value) { X outb(reg, cfg); X outb(value, cfg + 1); X if (value != inb(cfg + 1)) { X fprintf(stderr, "error: msnd_write_cfg: I/O error\n"); X return -EIO; X } X return 0; } X static int msnd_read_cfg(int cfg, int reg) { X outb(reg, cfg); X return inb(cfg + 1); } X static int msnd_write_cfg_io0(int cfg, int num, WORD io) { X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) X return -EIO; X if (msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io))) X return -EIO; X if (msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io))) X return -EIO; X return 0; } X static int msnd_read_cfg_io0(int cfg, int num, WORD *io) { X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) X return -EIO; X X *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO0_BASELO), X msnd_read_cfg(cfg, IREG_IO0_BASEHI)); X X return 0; } X static int msnd_write_cfg_io1(int cfg, int num, WORD io) { X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) X return -EIO; X if (msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io))) X return -EIO; X if (msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io))) X return -EIO; X return 0; } X static int msnd_read_cfg_io1(int cfg, int num, WORD *io) { X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) X return -EIO; X X *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO1_BASELO), X msnd_read_cfg(cfg, IREG_IO1_BASEHI)); X X return 0; } X static int msnd_write_cfg_irq(int cfg, int num, WORD irq) { X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) X return -EIO; X if (msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq))) X return -EIO; X if (msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE)) X return -EIO; X return 0; } X static int msnd_read_cfg_irq(int cfg, int num, WORD *irq) { X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) X return -EIO; X X *irq = msnd_read_cfg(cfg, IREG_IRQ_NUMBER); X X return 0; } X static int msnd_write_cfg_mem(int cfg, int num, int mem) { X WORD wmem; X X mem >>= 8; X mem &= 0xfff; X wmem = (WORD)mem; X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) X return -EIO; X if (msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem))) X return -EIO; X if (msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem))) X return -EIO; X if (wmem && msnd_write_cfg(cfg, IREG_MEMCONTROL, (MEMTYPE_HIADDR | MEMTYPE_16BIT))) X return -EIO; X return 0; } X static int msnd_read_cfg_mem(int cfg, int num, int *mem) { X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) X return -EIO; X X *mem = MAKEWORD(msnd_read_cfg(cfg, IREG_MEMBASELO), X msnd_read_cfg(cfg, IREG_MEMBASEHI)); X *mem <<= 8; X X return 0; } X static int msnd_activate_logical(int cfg, int num) { X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) X return -EIO; X if (msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE)) X return -EIO; X return 0; } X static int msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem) { X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) X return -EIO; X if (msnd_write_cfg_io0(cfg, num, io0)) X return -EIO; X if (msnd_write_cfg_io1(cfg, num, io1)) X return -EIO; X if (msnd_write_cfg_irq(cfg, num, irq)) X return -EIO; X if (msnd_write_cfg_mem(cfg, num, mem)) X return -EIO; X if (msnd_activate_logical(cfg, num)) X return -EIO; X return 0; } X static int msnd_read_cfg_logical(int cfg, int num, WORD *io0, WORD *io1, WORD *irq, int *mem) { X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) X return -EIO; X if (msnd_read_cfg_io0(cfg, num, io0)) X return -EIO; X if (msnd_read_cfg_io1(cfg, num, io1)) X return -EIO; X if (msnd_read_cfg_irq(cfg, num, irq)) X return -EIO; X if (msnd_read_cfg_mem(cfg, num, mem)) X return -EIO; X return 0; } X static void usage(void) { X fprintf(stderr, X "\n" X "pinnaclecfg 1.0\n" X "\n" X "usage: pinnaclecfg <config port> [device config]\n" X "\n" X "This is for use with the card in NON-PnP mode only.\n" X "\n" X "Available devices (not all available for Fiji):\n" X "\n" X " Device Description\n" X " -------------------------------------------------------------------\n" X " reset Reset all devices (i.e. disable)\n" X " show Display current device configurations\n" X "\n" X " dsp <io> <irq> <mem> Audio device\n" X " mpu <io> <irq> Internal Kurzweil synth\n" X " ide <io0> <io1> <irq> On-board IDE controller\n" X " joystick <io> Joystick port\n" X "\n"); X exit(1); } X static int cfg_reset(void) { X int i; X X for (i = 0; i < 4; ++i) X msnd_write_cfg_logical(config_port, i, 0, 0, 0, 0); X X return 0; } X static int cfg_show(void) { X int i; X int count = 0; X X for (i = 0; i < 4; ++i) { X WORD io0, io1, irq; X int mem; X msnd_read_cfg_logical(config_port, i, &io0, &io1, &irq, &mem); X switch (i) { X case 0: X if (io0 || irq || mem) { X printf("dsp 0x%x %d 0x%x\n", io0, irq, mem); X ++count; X } X break; X case 1: X if (io0 || irq) { X printf("mpu 0x%x %d\n", io0, irq); X ++count; X } X break; X case 2: X if (io0 || io1 || irq) { X printf("ide 0x%x 0x%x %d\n", io0, io1, irq); X ++count; X } X break; X case 3: X if (io0) { X printf("joystick 0x%x\n", io0); X ++count; X } X break; X } X } X X if (count == 0) X fprintf(stderr, "no devices configured\n"); X X return 0; } X static int cfg_dsp(int argc, char *argv[]) { X int io, irq, mem; X X if (argc < 3 || X sscanf(argv[0], "0x%x", &io) != 1 || X sscanf(argv[1], "%d", &irq) != 1 || X sscanf(argv[2], "0x%x", &mem) != 1) X usage(); X X if (!(io == 0x290 || X io == 0x260 || X io == 0x250 || X io == 0x240 || X io == 0x230 || X io == 0x220 || X io == 0x210 || X io == 0x3e0)) { X fprintf(stderr, "error: io must be one of " X "210, 220, 230, 240, 250, 260, 290, or 3E0\n"); X usage(); X } X X if (!(irq == 5 || X irq == 7 || X irq == 9 || X irq == 10 || X irq == 11 || X irq == 12)) { X fprintf(stderr, "error: irq must be one of " X "5, 7, 9, 10, 11 or 12\n"); X usage(); X } X X if (!(mem == 0xb0000 || X mem == 0xc8000 || X mem == 0xd0000 || X mem == 0xd8000 || X mem == 0xe0000 || X mem == 0xe8000)) { X fprintf(stderr, "error: mem must be one of " X "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n"); X usage(); X } X X return msnd_write_cfg_logical(config_port, 0, io, 0, irq, mem); } X static int cfg_mpu(int argc, char *argv[]) { X int io, irq; X X if (argc < 2 || X sscanf(argv[0], "0x%x", &io) != 1 || X sscanf(argv[1], "%d", &irq) != 1) X usage(); X X return msnd_write_cfg_logical(config_port, 1, io, 0, irq, 0); } X static int cfg_ide(int argc, char *argv[]) { X int io0, io1, irq; X X if (argc < 3 || X sscanf(argv[0], "0x%x", &io0) != 1 || X sscanf(argv[0], "0x%x", &io1) != 1 || X sscanf(argv[1], "%d", &irq) != 1) X usage(); X X return msnd_write_cfg_logical(config_port, 2, io0, io1, irq, 0); } X static int cfg_joystick(int argc, char *argv[]) { X int io; X X if (argc < 1 || X sscanf(argv[0], "0x%x", &io) != 1) X usage(); X X return msnd_write_cfg_logical(config_port, 3, io, 0, 0, 0); } X int main(int argc, char *argv[]) { X char *device; X int rv = 0; X X --argc; ++argv; X X if (argc < 2) X usage(); X X sscanf(argv[0], "0x%x", &config_port); X if (config_port != 0x250 && config_port != 0x260 && config_port != 0x270) { X fprintf(stderr, "error: <config port> must be 0x250, 0x260 or 0x270\n"); X exit(1); X } X if (ioperm(config_port, 2, 1)) { X perror("ioperm"); X fprintf(stderr, "note: pinnaclecfg must be run as root\n"); X exit(1); X } X device = argv[1]; X X argc -= 2; argv += 2; X X if (strcmp(device, "reset") == 0) X rv = cfg_reset(); X else if (strcmp(device, "show") == 0) X rv = cfg_show(); X else if (strcmp(device, "dsp") == 0) X rv = cfg_dsp(argc, argv); X else if (strcmp(device, "mpu") == 0) X rv = cfg_mpu(argc, argv); X else if (strcmp(device, "ide") == 0) X rv = cfg_ide(argc, argv); X else if (strcmp(device, "joystick") == 0) X rv = cfg_joystick(argc, argv); X else { X fprintf(stderr, "error: unknown device %s\n", device); X usage(); X } X X if (rv) X fprintf(stderr, "error: device configuration failed\n"); X X return 0; } SHAR_EOF $shar_touch -am 1204092598 'MultiSound.d/pinnaclecfg.c' && chmod 0664 'MultiSound.d/pinnaclecfg.c' || $echo 'restore of' 'MultiSound.d/pinnaclecfg.c' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'MultiSound.d/pinnaclecfg.c:' 'MD5 check failed' 366bdf27f0db767a3c7921d0a6db20fe MultiSound.d/pinnaclecfg.c SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/pinnaclecfg.c'`" test 10224 -eq "$shar_count" || $echo 'MultiSound.d/pinnaclecfg.c:' 'original size' '10224,' 'current size' "$shar_count!" fi fi # ============= MultiSound.d/Makefile ============== if test -f 'MultiSound.d/Makefile' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'MultiSound.d/Makefile' '(file already exists)' else $echo 'x -' extracting 'MultiSound.d/Makefile' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/Makefile' && CC = gcc CFLAGS = -O PROGS = setdigital msndreset pinnaclecfg conv X all: $(PROGS) X clean: X rm -f $(PROGS) SHAR_EOF $shar_touch -am 1204092398 'MultiSound.d/Makefile' && chmod 0664 'MultiSound.d/Makefile' || $echo 'restore of' 'MultiSound.d/Makefile' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'MultiSound.d/Makefile:' 'MD5 check failed' 76ca8bb44e3882edcf79c97df6c81845 MultiSound.d/Makefile SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/Makefile'`" test 106 -eq "$shar_count" || $echo 'MultiSound.d/Makefile:' 'original size' '106,' 'current size' "$shar_count!" fi fi # ============= MultiSound.d/conv.l ============== if test -f 'MultiSound.d/conv.l' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'MultiSound.d/conv.l' '(file already exists)' else $echo 'x -' extracting 'MultiSound.d/conv.l' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/conv.l' && %% [ \n\t,\r] \;.* DB [0-9A-Fa-f]+H { int n; sscanf(yytext, "%xH", &n); printf("%c", n); } %% int yywrap() { return 1; } void main() { yylex(); } SHAR_EOF $shar_touch -am 0828231798 'MultiSound.d/conv.l' && chmod 0664 'MultiSound.d/conv.l' || $echo 'restore of' 'MultiSound.d/conv.l' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'MultiSound.d/conv.l:' 'MD5 check failed' d2411fc32cd71a00dcdc1f009e858dd2 MultiSound.d/conv.l SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/conv.l'`" test 146 -eq "$shar_count" || $echo 'MultiSound.d/conv.l:' 'original size' '146,' 'current size' "$shar_count!" fi fi # ============= MultiSound.d/msndreset.c ============== if test -f 'MultiSound.d/msndreset.c' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'MultiSound.d/msndreset.c' '(file already exists)' else $echo 'x -' extracting 'MultiSound.d/msndreset.c' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/msndreset.c' && /********************************************************************* X * X * msndreset.c - resets the MultiSound card X * X * Copyright (C) 1998 Andrew Veliath X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2 of the License, or X * (at your option) any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program; if not, write to the Free Software X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X ********************************************************************/ X #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/soundcard.h> X int main(int argc, char *argv[]) { X int fd; X X if (argc != 2) { X fprintf(stderr, "usage: msndreset <mixer device>\n"); X exit(1); X } X X if ((fd = open(argv[1], O_RDWR)) < 0) { X perror(argv[1]); X exit(1); X } X X if (ioctl(fd, SOUND_MIXER_PRIVATE1, 0) < 0) { X fprintf(stderr, "error: msnd ioctl reset failed\n"); X perror("ioctl"); X close(fd); X exit(1); X } X X close(fd); X X return 0; } SHAR_EOF $shar_touch -am 1204100698 'MultiSound.d/msndreset.c' && chmod 0664 'MultiSound.d/msndreset.c' || $echo 'restore of' 'MultiSound.d/msndreset.c' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'MultiSound.d/msndreset.c:' 'MD5 check failed' c52f876521084e8eb25e12e01dcccb8a MultiSound.d/msndreset.c SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/msndreset.c'`" test 1491 -eq "$shar_count" || $echo 'MultiSound.d/msndreset.c:' 'original size' '1491,' 'current size' "$shar_count!" fi fi rm -fr _sh01426 exit 0 admin-guide/aoe/udev-install.sh 0000644 00000001524 14722053057 0012445 0 ustar 00 # install the aoe-specific udev rules from udev.txt into # the system's udev configuration # me="`basename $0`" # find udev.conf, often /etc/udev/udev.conf # (or environment can specify where to find udev.conf) # if test -z "$conf"; then if test -r /etc/udev/udev.conf; then conf=/etc/udev/udev.conf else conf="`find /etc -type f -name udev.conf 2> /dev/null`" if test -z "$conf" || test ! -r "$conf"; then echo "$me Error: no udev.conf found" 1>&2 exit 1 fi fi fi # find the directory where udev rules are stored, often # /etc/udev/rules.d # rules_d="`sed -n '/^udev_rules=/{ s!udev_rules=!!; s!\"!!g; p; }' $conf`" if test -z "$rules_d" ; then rules_d=/etc/udev/rules.d fi if test ! -d "$rules_d"; then echo "$me Error: cannot find udev rules directory" 1>&2 exit 1 fi sh -xc "cp `dirname $0`/udev.txt $rules_d/60-aoe.rules" admin-guide/aoe/status.sh 0000644 00000001266 14722053057 0011364 0 ustar 00 #! /bin/sh # collate and present sysfs information about AoE storage # # A more complete version of this script is aoe-stat, in the # aoetools. set -e format="%8s\t%8s\t%8s\n" me=`basename $0` sysd=${sysfs_dir:-/sys} # printf "$format" device mac netif state # Suse 9.1 Pro doesn't put /sys in /etc/mtab #test -z "`mount | grep sysfs`" && { test ! -d "$sysd/block" && { echo "$me Error: sysfs is not mounted" 1>&2 exit 1 } for d in `ls -d $sysd/block/etherd* 2>/dev/null | grep -v p` end; do # maybe ls comes up empty, so we use "end" test $d = end && continue dev=`echo "$d" | sed 's/.*!//'` printf "$format" \ "$dev" \ "`cat \"$d/netif\"`" \ "`cat \"$d/state\"`" done | sort admin-guide/aoe/autoload.sh 0000644 00000000527 14722053057 0011650 0 ustar 00 #!/bin/sh # set aoe to autoload by installing the # aliases in /etc/modprobe.d/ f=/etc/modprobe.d/aoe.conf if test ! -r $f || test ! -w $f; then echo "cannot configure $f for module autoloading" 1>&2 exit 1 fi grep major-152 $f >/dev/null if [ $? = 1 ]; then echo alias block-major-152 aoe >> $f echo alias char-major-152 aoe >> $f fi admin-guide/cifs/winucase_convert.pl 0000755 00000003115 14722053057 0013576 0 ustar 00 #!/usr/bin/perl -w # # winucase_convert.pl -- convert "Windows 8 Upper Case Mapping Table.txt" to # a two-level set of C arrays. # # Copyright 2013: Jeff Layton <jlayton@redhat.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # while(<>) { next if (!/^0x(..)(..)\t0x(....)\t/); $firstchar = hex($1); $secondchar = hex($2); $uppercase = hex($3); $top[$firstchar][$secondchar] = $uppercase; } for ($i = 0; $i < 256; $i++) { next if (!$top[$i]); printf("static const wchar_t t2_%2.2x[256] = {", $i); for ($j = 0; $j < 256; $j++) { if (($j % 8) == 0) { print "\n\t"; } else { print " "; } printf("0x%4.4x,", $top[$i][$j] ? $top[$i][$j] : 0); } print "\n};\n\n"; } printf("static const wchar_t *const toplevel[256] = {", $i); for ($i = 0; $i < 256; $i++) { if (($i % 8) == 0) { print "\n\t"; } elsif ($top[$i]) { print " "; } else { print " "; } if ($top[$i]) { printf("t2_%2.2x,", $i); } else { print "NULL,"; } } print "\n};\n\n"; features/scripts/features-refresh.sh 0000755 00000005424 14722053057 0013674 0 ustar 00 # # Small script that refreshes the kernel feature support status in place. # for F_FILE in Documentation/features/*/*/arch-support.txt; do F=$(grep "^# Kconfig:" "$F_FILE" | cut -c26-) # # Each feature F is identified by a pair (O, K), where 'O' can # be either the empty string (for 'nop') or "not" (the logical # negation operator '!'); other operators are not supported. # O="" K=$F if [[ "$F" == !* ]]; then O="not" K=$(echo $F | sed -e 's/^!//g') fi # # F := (O, K) is 'valid' iff there is a Kconfig file (for some # arch) which contains K. # # Notice that this definition entails an 'asymmetry' between # the case 'O = ""' and the case 'O = "not"'. E.g., F may be # _invalid_ if: # # [case 'O = ""'] # 1) no arch provides support for F, # 2) K does not exist (e.g., it was renamed/mis-typed); # # [case 'O = "not"'] # 3) all archs provide support for F, # 4) as in (2). # # The rationale for adopting this definition (and, thus, for # keeping the asymmetry) is: # # We want to be able to 'detect' (2) (or (4)). # # (1) and (3) may further warn the developers about the fact # that K can be removed. # F_VALID="false" for ARCH_DIR in arch/*/; do K_FILES=$(find $ARCH_DIR -name "Kconfig*") K_GREP=$(grep "$K" $K_FILES) if [ ! -z "$K_GREP" ]; then F_VALID="true" break fi done if [ "$F_VALID" = "false" ]; then printf "WARNING: '%s' is not a valid Kconfig\n" "$F" fi T_FILE="$F_FILE.tmp" grep "^#" $F_FILE > $T_FILE echo " -----------------------" >> $T_FILE echo " | arch |status|" >> $T_FILE echo " -----------------------" >> $T_FILE for ARCH_DIR in arch/*/; do ARCH=$(echo $ARCH_DIR | sed -e 's/arch//g' | sed -e 's/\///g') K_FILES=$(find $ARCH_DIR -name "Kconfig*") K_GREP=$(grep "$K" $K_FILES) # # Arch support status values for (O, K) are updated according # to the following rules. # # - ("", K) is 'supported by a given arch', if there is a # Kconfig file for that arch which contains K; # # - ("not", K) is 'supported by a given arch', if there is # no Kconfig file for that arch which contains K; # # - otherwise: preserve the previous status value (if any), # default to 'not yet supported'. # # Notice that, according these rules, invalid features may be # updated/modified. # if [ "$O" = "" ] && [ ! -z "$K_GREP" ]; then printf " |%12s: | ok |\n" "$ARCH" >> $T_FILE elif [ "$O" = "not" ] && [ -z "$K_GREP" ]; then printf " |%12s: | ok |\n" "$ARCH" >> $T_FILE else S=$(grep -v "^#" "$F_FILE" | grep " $ARCH:") if [ ! -z "$S" ]; then echo "$S" >> $T_FILE else printf " |%12s: | TODO |\n" "$ARCH" \ >> $T_FILE fi fi done echo " -----------------------" >> $T_FILE mv $T_FILE $F_FILE done features/list-arch.sh 0000755 00000001307 14722053057 0010615 0 ustar 00 # # Small script that visualizes the kernel feature support status # of an architecture. # # (If no arguments are given then it will print the host architecture's status.) # ARCH=${1:-$(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/')} cd $(dirname $0) echo "#" echo "# Kernel feature support matrix of the '$ARCH' architecture:" echo "#" for F in */*/arch-support.txt; do SUBSYS=$(echo $F | cut -d/ -f1) N=$(grep -h "^# Feature name:" $F | cut -c25-) C=$(grep -h "^# Kconfig:" $F | cut -c25-) D=$(grep -h "^# description:" $F | cut -c25-) S=$(grep -hv "^#" $F | grep -w $ARCH | cut -d\| -f3) printf "%10s/%-22s:%s| %35s # %s\n" "$SUBSYS" "$N" "$S" "$C" "$D" done arm64/kasan-offsets.sh 0000644 00000001303 14722053057 0010577 0 ustar 00 #!/bin/sh # Print out the KASAN_SHADOW_OFFSETS required to place the KASAN SHADOW # start address at the mid-point of the kernel VA space print_kasan_offset () { printf "%02d\t" $1 printf "0x%08x00000000\n" $(( (0xffffffff & (-1 << ($1 - 1 - 32))) \ + (1 << ($1 - 32 - $2)) \ - (1 << (64 - 32 - $2)) )) } echo KASAN_SHADOW_SCALE_SHIFT = 3 printf "VABITS\tKASAN_SHADOW_OFFSET\n" print_kasan_offset 48 3 print_kasan_offset 47 3 print_kasan_offset 42 3 print_kasan_offset 39 3 print_kasan_offset 36 3 echo echo KASAN_SHADOW_SCALE_SHIFT = 4 printf "VABITS\tKASAN_SHADOW_OFFSET\n" print_kasan_offset 48 4 print_kasan_offset 47 4 print_kasan_offset 42 4 print_kasan_offset 39 4 print_kasan_offset 36 4 Kconfig 0000644 00000000550 14722053057 0006054 0 ustar 00 config WARN_MISSING_DOCUMENTS bool "Warn if there's a missing documentation file" depends on COMPILE_TEST help It is not uncommon that a document gets renamed. This option makes the Kernel to check for missing dependencies, warning when something is missing. Works only if the Kernel is built from a git tree. If unsure, select 'N'. s390/config3270.sh 0000644 00000003731 14722053057 0007370 0 ustar 00 #!/bin/sh # # config3270 -- Autoconfigure /dev/3270/* and /etc/inittab # # Usage: # config3270 # # Output: # /tmp/mkdev3270 # # Operation: # 1. Run this script # 2. Run the script it produces: /tmp/mkdev3270 # 3. Issue "telinit q" or reboot, as appropriate. # P=/proc/tty/driver/tty3270 ROOT= D=$ROOT/dev SUBD=3270 TTY=$SUBD/tty TUB=$SUBD/tub SCR=$ROOT/tmp/mkdev3270 SCRTMP=$SCR.a GETTYLINE=:2345:respawn:/sbin/mingetty INITTAB=$ROOT/etc/inittab NINITTAB=$ROOT/etc/NEWinittab OINITTAB=$ROOT/etc/OLDinittab ADDNOTE=\\"# Additional mingettys for the 3270/tty* driver, tub3270 ---\\" if ! ls $P > /dev/null 2>&1; then modprobe tub3270 > /dev/null 2>&1 fi ls $P > /dev/null 2>&1 || exit 1 # Initialize two files, one for /dev/3270 commands and one # to replace the /etc/inittab file (old one saved in OLDinittab) echo "#!/bin/sh" > $SCR || exit 1 echo " " >> $SCR echo "# Script built by /sbin/config3270" >> $SCR if [ ! -d /dev/dasd ]; then echo rm -rf "$D/$SUBD/*" >> $SCR fi echo "grep -v $TTY $INITTAB > $NINITTAB" > $SCRTMP || exit 1 echo "echo $ADDNOTE >> $NINITTAB" >> $SCRTMP if [ ! -d /dev/dasd ]; then echo mkdir -p $D/$SUBD >> $SCR fi # Now query the tub3270 driver for 3270 device information # and add appropriate mknod and mingetty lines to our files echo what=config > $P while read devno maj min;do if [ $min = 0 ]; then fsmaj=$maj if [ ! -d /dev/dasd ]; then echo mknod $D/$TUB c $fsmaj 0 >> $SCR echo chmod 666 $D/$TUB >> $SCR fi elif [ $maj = CONSOLE ]; then if [ ! -d /dev/dasd ]; then echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR fi else if [ ! -d /dev/dasd ]; then echo mknod $D/$TTY$devno c $maj $min >>$SCR echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR fi echo "echo t$min$GETTYLINE $TTY$devno >> $NINITTAB" >> $SCRTMP fi done < $P echo mv $INITTAB $OINITTAB >> $SCRTMP || exit 1 echo mv $NINITTAB $INITTAB >> $SCRTMP cat $SCRTMP >> $SCR rm $SCRTMP exit 0 media/Makefile 0000644 00000003771 14722053057 0007300 0 ustar 00 # SPDX-License-Identifier: GPL-2.0 # Rules to convert a .h file to inline RST documentation SRC_DIR=$(srctree)/Documentation/media PARSER = $(srctree)/Documentation/sphinx/parse-headers.pl UAPI = $(srctree)/include/uapi/linux KAPI = $(srctree)/include/linux FILES = audio.h.rst ca.h.rst dmx.h.rst frontend.h.rst net.h.rst video.h.rst \ videodev2.h.rst media.h.rst cec.h.rst lirc.h.rst TARGETS := $(addprefix $(BUILDDIR)/, $(FILES)) gen_rst = \ echo ${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions; \ ${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions quiet_gen_rst = echo ' PARSE $(patsubst $(srctree)/%,%,$<)'; \ ${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions silent_gen_rst = ${gen_rst} $(BUILDDIR)/audio.h.rst: ${UAPI}/dvb/audio.h ${PARSER} $(SRC_DIR)/audio.h.rst.exceptions @$($(quiet)gen_rst) $(BUILDDIR)/ca.h.rst: ${UAPI}/dvb/ca.h ${PARSER} $(SRC_DIR)/ca.h.rst.exceptions @$($(quiet)gen_rst) $(BUILDDIR)/dmx.h.rst: ${UAPI}/dvb/dmx.h ${PARSER} $(SRC_DIR)/dmx.h.rst.exceptions @$($(quiet)gen_rst) $(BUILDDIR)/frontend.h.rst: ${UAPI}/dvb/frontend.h ${PARSER} $(SRC_DIR)/frontend.h.rst.exceptions @$($(quiet)gen_rst) $(BUILDDIR)/net.h.rst: ${UAPI}/dvb/net.h ${PARSER} $(SRC_DIR)/net.h.rst.exceptions @$($(quiet)gen_rst) $(BUILDDIR)/video.h.rst: ${UAPI}/dvb/video.h ${PARSER} $(SRC_DIR)/video.h.rst.exceptions @$($(quiet)gen_rst) $(BUILDDIR)/videodev2.h.rst: ${UAPI}/videodev2.h ${PARSER} $(SRC_DIR)/videodev2.h.rst.exceptions @$($(quiet)gen_rst) $(BUILDDIR)/media.h.rst: ${UAPI}/media.h ${PARSER} $(SRC_DIR)/media.h.rst.exceptions @$($(quiet)gen_rst) $(BUILDDIR)/cec.h.rst: ${UAPI}/cec.h ${PARSER} $(SRC_DIR)/cec.h.rst.exceptions @$($(quiet)gen_rst) $(BUILDDIR)/lirc.h.rst: ${UAPI}/lirc.h ${PARSER} $(SRC_DIR)/lirc.h.rst.exceptions @$($(quiet)gen_rst) # Media build rules .PHONY: all html epub xml latex all: $(IMGDOT) $(BUILDDIR) ${TARGETS} html: all epub: all xml: all latex: $(IMGPDF) all linkcheck: clean: -rm -f $(DOTTGT) $(IMGTGT) ${TARGETS} 2>/dev/null $(BUILDDIR): $(Q)mkdir -p $@ trace/postprocess/trace-pagealloc-postprocess.pl 0000644 00000030561 14722053057 0016202 0 ustar 00 #!/usr/bin/env perl # This is a POC (proof of concept or piece of crap, take your pick) for reading the # text representation of trace output related to page allocation. It makes an attempt # to extract some high-level information on what is going on. The accuracy of the parser # may vary considerably # # Example usage: trace-pagealloc-postprocess.pl < /sys/kernel/debug/tracing/trace_pipe # other options # --prepend-parent Report on the parent proc and PID # --read-procstat If the trace lacks process info, get it from /proc # --ignore-pid Aggregate processes of the same name together # # Copyright (c) IBM Corporation 2009 # Author: Mel Gorman <mel@csn.ul.ie> use strict; use Getopt::Long; # Tracepoint events use constant MM_PAGE_ALLOC => 1; use constant MM_PAGE_FREE => 2; use constant MM_PAGE_FREE_BATCHED => 3; use constant MM_PAGE_PCPU_DRAIN => 4; use constant MM_PAGE_ALLOC_ZONE_LOCKED => 5; use constant MM_PAGE_ALLOC_EXTFRAG => 6; use constant EVENT_UNKNOWN => 7; # Constants used to track state use constant STATE_PCPU_PAGES_DRAINED => 8; use constant STATE_PCPU_PAGES_REFILLED => 9; # High-level events extrapolated from tracepoints use constant HIGH_PCPU_DRAINS => 10; use constant HIGH_PCPU_REFILLS => 11; use constant HIGH_EXT_FRAGMENT => 12; use constant HIGH_EXT_FRAGMENT_SEVERE => 13; use constant HIGH_EXT_FRAGMENT_MODERATE => 14; use constant HIGH_EXT_FRAGMENT_CHANGED => 15; my %perprocesspid; my %perprocess; my $opt_ignorepid; my $opt_read_procstat; my $opt_prepend_parent; # Catch sigint and exit on request my $sigint_report = 0; my $sigint_exit = 0; my $sigint_pending = 0; my $sigint_received = 0; sub sigint_handler { my $current_time = time; if ($current_time - 2 > $sigint_received) { print "SIGINT received, report pending. Hit ctrl-c again to exit\n"; $sigint_report = 1; } else { if (!$sigint_exit) { print "Second SIGINT received quickly, exiting\n"; } $sigint_exit++; } if ($sigint_exit > 3) { print "Many SIGINTs received, exiting now without report\n"; exit; } $sigint_received = $current_time; $sigint_pending = 1; } $SIG{INT} = "sigint_handler"; # Parse command line options GetOptions( 'ignore-pid' => \$opt_ignorepid, 'read-procstat' => \$opt_read_procstat, 'prepend-parent' => \$opt_prepend_parent, ); # Defaults for dynamically discovered regex's my $regex_fragdetails_default = 'page=([0-9a-f]*) pfn=([0-9]*) alloc_order=([-0-9]*) fallback_order=([-0-9]*) pageblock_order=([-0-9]*) alloc_migratetype=([-0-9]*) fallback_migratetype=([-0-9]*) fragmenting=([-0-9]) change_ownership=([-0-9])'; # Dyanically discovered regex my $regex_fragdetails; # Static regex used. Specified like this for readability and for use with /o # (process_pid) (cpus ) ( time ) (tpoint ) (details) my $regex_traceevent = '\s*([a-zA-Z0-9-]*)\s*(\[[0-9]*\])\s*([0-9.]*):\s*([a-zA-Z_]*):\s*(.*)'; my $regex_statname = '[-0-9]*\s\((.*)\).*'; my $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z]\s([0-9]*).*'; sub generate_traceevent_regex { my $event = shift; my $default = shift; my $regex; # Read the event format or use the default if (!open (FORMAT, "/sys/kernel/debug/tracing/events/$event/format")) { $regex = $default; } else { my $line; while (!eof(FORMAT)) { $line = <FORMAT>; if ($line =~ /^print fmt:\s"(.*)",.*/) { $regex = $1; $regex =~ s/%p/\([0-9a-f]*\)/g; $regex =~ s/%d/\([-0-9]*\)/g; $regex =~ s/%lu/\([0-9]*\)/g; } } } # Verify fields are in the right order my $tuple; foreach $tuple (split /\s/, $regex) { my ($key, $value) = split(/=/, $tuple); my $expected = shift; if ($key ne $expected) { print("WARNING: Format not as expected '$key' != '$expected'"); $regex =~ s/$key=\((.*)\)/$key=$1/; } } if (defined shift) { die("Fewer fields than expected in format"); } return $regex; } $regex_fragdetails = generate_traceevent_regex("kmem/mm_page_alloc_extfrag", $regex_fragdetails_default, "page", "pfn", "alloc_order", "fallback_order", "pageblock_order", "alloc_migratetype", "fallback_migratetype", "fragmenting", "change_ownership"); sub read_statline($) { my $pid = $_[0]; my $statline; if (open(STAT, "/proc/$pid/stat")) { $statline = <STAT>; close(STAT); } if ($statline eq '') { $statline = "-1 (UNKNOWN_PROCESS_NAME) R 0"; } return $statline; } sub guess_process_pid($$) { my $pid = $_[0]; my $statline = $_[1]; if ($pid == 0) { return "swapper-0"; } if ($statline !~ /$regex_statname/o) { die("Failed to math stat line for process name :: $statline"); } return "$1-$pid"; } sub parent_info($$) { my $pid = $_[0]; my $statline = $_[1]; my $ppid; if ($pid == 0) { return "NOPARENT-0"; } if ($statline !~ /$regex_statppid/o) { die("Failed to match stat line process ppid:: $statline"); } # Read the ppid stat line $ppid = $1; return guess_process_pid($ppid, read_statline($ppid)); } sub process_events { my $traceevent; my $process_pid; my $cpus; my $timestamp; my $tracepoint; my $details; my $statline; # Read each line of the event log EVENT_PROCESS: while ($traceevent = <STDIN>) { if ($traceevent =~ /$regex_traceevent/o) { $process_pid = $1; $tracepoint = $4; if ($opt_read_procstat || $opt_prepend_parent) { $process_pid =~ /(.*)-([0-9]*)$/; my $process = $1; my $pid = $2; $statline = read_statline($pid); if ($opt_read_procstat && $process eq '') { $process_pid = guess_process_pid($pid, $statline); } if ($opt_prepend_parent) { $process_pid = parent_info($pid, $statline) . " :: $process_pid"; } } # Unnecessary in this script. Uncomment if required # $cpus = $2; # $timestamp = $3; } else { next; } # Perl Switch() sucks majorly if ($tracepoint eq "mm_page_alloc") { $perprocesspid{$process_pid}->{MM_PAGE_ALLOC}++; } elsif ($tracepoint eq "mm_page_free") { $perprocesspid{$process_pid}->{MM_PAGE_FREE}++ } elsif ($tracepoint eq "mm_page_free_batched") { $perprocesspid{$process_pid}->{MM_PAGE_FREE_BATCHED}++; } elsif ($tracepoint eq "mm_page_pcpu_drain") { $perprocesspid{$process_pid}->{MM_PAGE_PCPU_DRAIN}++; $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_DRAINED}++; } elsif ($tracepoint eq "mm_page_alloc_zone_locked") { $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_ZONE_LOCKED}++; $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_REFILLED}++; } elsif ($tracepoint eq "mm_page_alloc_extfrag") { # Extract the details of the event now $details = $5; my ($page, $pfn); my ($alloc_order, $fallback_order, $pageblock_order); my ($alloc_migratetype, $fallback_migratetype); my ($fragmenting, $change_ownership); if ($details !~ /$regex_fragdetails/o) { print "WARNING: Failed to parse mm_page_alloc_extfrag as expected\n"; next; } $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_EXTFRAG}++; $page = $1; $pfn = $2; $alloc_order = $3; $fallback_order = $4; $pageblock_order = $5; $alloc_migratetype = $6; $fallback_migratetype = $7; $fragmenting = $8; $change_ownership = $9; if ($fragmenting) { $perprocesspid{$process_pid}->{HIGH_EXT_FRAG}++; if ($fallback_order <= 3) { $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_SEVERE}++; } else { $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_MODERATE}++; } } if ($change_ownership) { $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_CHANGED}++; } } else { $perprocesspid{$process_pid}->{EVENT_UNKNOWN}++; } # Catch a full pcpu drain event if ($perprocesspid{$process_pid}->{STATE_PCPU_PAGES_DRAINED} && $tracepoint ne "mm_page_pcpu_drain") { $perprocesspid{$process_pid}->{HIGH_PCPU_DRAINS}++; $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_DRAINED} = 0; } # Catch a full pcpu refill event if ($perprocesspid{$process_pid}->{STATE_PCPU_PAGES_REFILLED} && $tracepoint ne "mm_page_alloc_zone_locked") { $perprocesspid{$process_pid}->{HIGH_PCPU_REFILLS}++; $perprocesspid{$process_pid}->{STATE_PCPU_PAGES_REFILLED} = 0; } if ($sigint_pending) { last EVENT_PROCESS; } } } sub dump_stats { my $hashref = shift; my %stats = %$hashref; # Dump per-process stats my $process_pid; my $max_strlen = 0; # Get the maximum process name foreach $process_pid (keys %perprocesspid) { my $len = length($process_pid); if ($len > $max_strlen) { $max_strlen = $len; } } $max_strlen += 2; printf("\n"); printf("%-" . $max_strlen . "s %8s %10s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n", "Process", "Pages", "Pages", "Pages", "Pages", "PCPU", "PCPU", "PCPU", "Fragment", "Fragment", "MigType", "Fragment", "Fragment", "Unknown"); printf("%-" . $max_strlen . "s %8s %10s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n", "details", "allocd", "allocd", "freed", "freed", "pages", "drains", "refills", "Fallback", "Causing", "Changed", "Severe", "Moderate", ""); printf("%-" . $max_strlen . "s %8s %10s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n", "", "", "under lock", "direct", "pagevec", "drain", "", "", "", "", "", "", "", ""); foreach $process_pid (keys %stats) { # Dump final aggregates if ($stats{$process_pid}->{STATE_PCPU_PAGES_DRAINED}) { $stats{$process_pid}->{HIGH_PCPU_DRAINS}++; $stats{$process_pid}->{STATE_PCPU_PAGES_DRAINED} = 0; } if ($stats{$process_pid}->{STATE_PCPU_PAGES_REFILLED}) { $stats{$process_pid}->{HIGH_PCPU_REFILLS}++; $stats{$process_pid}->{STATE_PCPU_PAGES_REFILLED} = 0; } printf("%-" . $max_strlen . "s %8d %10d %8d %8d %8d %8d %8d %8d %8d %8d %8d %8d %8d\n", $process_pid, $stats{$process_pid}->{MM_PAGE_ALLOC}, $stats{$process_pid}->{MM_PAGE_ALLOC_ZONE_LOCKED}, $stats{$process_pid}->{MM_PAGE_FREE}, $stats{$process_pid}->{MM_PAGE_FREE_BATCHED}, $stats{$process_pid}->{MM_PAGE_PCPU_DRAIN}, $stats{$process_pid}->{HIGH_PCPU_DRAINS}, $stats{$process_pid}->{HIGH_PCPU_REFILLS}, $stats{$process_pid}->{MM_PAGE_ALLOC_EXTFRAG}, $stats{$process_pid}->{HIGH_EXT_FRAG}, $stats{$process_pid}->{HIGH_EXT_FRAGMENT_CHANGED}, $stats{$process_pid}->{HIGH_EXT_FRAGMENT_SEVERE}, $stats{$process_pid}->{HIGH_EXT_FRAGMENT_MODERATE}, $stats{$process_pid}->{EVENT_UNKNOWN}); } } sub aggregate_perprocesspid() { my $process_pid; my $process; undef %perprocess; foreach $process_pid (keys %perprocesspid) { $process = $process_pid; $process =~ s/-([0-9])*$//; if ($process eq '') { $process = "NO_PROCESS_NAME"; } $perprocess{$process}->{MM_PAGE_ALLOC} += $perprocesspid{$process_pid}->{MM_PAGE_ALLOC}; $perprocess{$process}->{MM_PAGE_ALLOC_ZONE_LOCKED} += $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_ZONE_LOCKED}; $perprocess{$process}->{MM_PAGE_FREE} += $perprocesspid{$process_pid}->{MM_PAGE_FREE}; $perprocess{$process}->{MM_PAGE_FREE_BATCHED} += $perprocesspid{$process_pid}->{MM_PAGE_FREE_BATCHED}; $perprocess{$process}->{MM_PAGE_PCPU_DRAIN} += $perprocesspid{$process_pid}->{MM_PAGE_PCPU_DRAIN}; $perprocess{$process}->{HIGH_PCPU_DRAINS} += $perprocesspid{$process_pid}->{HIGH_PCPU_DRAINS}; $perprocess{$process}->{HIGH_PCPU_REFILLS} += $perprocesspid{$process_pid}->{HIGH_PCPU_REFILLS}; $perprocess{$process}->{MM_PAGE_ALLOC_EXTFRAG} += $perprocesspid{$process_pid}->{MM_PAGE_ALLOC_EXTFRAG}; $perprocess{$process}->{HIGH_EXT_FRAG} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAG}; $perprocess{$process}->{HIGH_EXT_FRAGMENT_CHANGED} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_CHANGED}; $perprocess{$process}->{HIGH_EXT_FRAGMENT_SEVERE} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_SEVERE}; $perprocess{$process}->{HIGH_EXT_FRAGMENT_MODERATE} += $perprocesspid{$process_pid}->{HIGH_EXT_FRAGMENT_MODERATE}; $perprocess{$process}->{EVENT_UNKNOWN} += $perprocesspid{$process_pid}->{EVENT_UNKNOWN}; } } sub report() { if (!$opt_ignorepid) { dump_stats(\%perprocesspid); } else { aggregate_perprocesspid(); dump_stats(\%perprocess); } } # Process events or signals until neither is available sub signal_loop() { my $sigint_processed; do { $sigint_processed = 0; process_events(); # Handle pending signals if any if ($sigint_pending) { my $current_time = time; if ($sigint_exit) { print "Received exit signal\n"; $sigint_pending = 0; } if ($sigint_report) { if ($current_time >= $sigint_received + 2) { report(); $sigint_report = 0; $sigint_pending = 0; $sigint_processed = 1; } } } } while ($sigint_pending || $sigint_processed); } signal_loop(); report(); trace/postprocess/trace-vmscan-postprocess.pl 0000644 00000067752 14722053057 0015556 0 ustar 00 #!/usr/bin/env perl # This is a POC for reading the text representation of trace output related to # page reclaim. It makes an attempt to extract some high-level information on # what is going on. The accuracy of the parser may vary # # Example usage: trace-vmscan-postprocess.pl < /sys/kernel/debug/tracing/trace_pipe # other options # --read-procstat If the trace lacks process info, get it from /proc # --ignore-pid Aggregate processes of the same name together # # Copyright (c) IBM Corporation 2009 # Author: Mel Gorman <mel@csn.ul.ie> use strict; use Getopt::Long; # Tracepoint events use constant MM_VMSCAN_DIRECT_RECLAIM_BEGIN => 1; use constant MM_VMSCAN_DIRECT_RECLAIM_END => 2; use constant MM_VMSCAN_KSWAPD_WAKE => 3; use constant MM_VMSCAN_KSWAPD_SLEEP => 4; use constant MM_VMSCAN_LRU_SHRINK_ACTIVE => 5; use constant MM_VMSCAN_LRU_SHRINK_INACTIVE => 6; use constant MM_VMSCAN_LRU_ISOLATE => 7; use constant MM_VMSCAN_WRITEPAGE_FILE_SYNC => 8; use constant MM_VMSCAN_WRITEPAGE_ANON_SYNC => 9; use constant MM_VMSCAN_WRITEPAGE_FILE_ASYNC => 10; use constant MM_VMSCAN_WRITEPAGE_ANON_ASYNC => 11; use constant MM_VMSCAN_WRITEPAGE_ASYNC => 12; use constant EVENT_UNKNOWN => 13; # Per-order events use constant MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER => 11; use constant MM_VMSCAN_WAKEUP_KSWAPD_PERORDER => 12; use constant MM_VMSCAN_KSWAPD_WAKE_PERORDER => 13; use constant HIGH_KSWAPD_REWAKEUP_PERORDER => 14; # Constants used to track state use constant STATE_DIRECT_BEGIN => 15; use constant STATE_DIRECT_ORDER => 16; use constant STATE_KSWAPD_BEGIN => 17; use constant STATE_KSWAPD_ORDER => 18; # High-level events extrapolated from tracepoints use constant HIGH_DIRECT_RECLAIM_LATENCY => 19; use constant HIGH_KSWAPD_LATENCY => 20; use constant HIGH_KSWAPD_REWAKEUP => 21; use constant HIGH_NR_SCANNED => 22; use constant HIGH_NR_TAKEN => 23; use constant HIGH_NR_RECLAIMED => 24; use constant HIGH_NR_FILE_SCANNED => 25; use constant HIGH_NR_ANON_SCANNED => 26; use constant HIGH_NR_FILE_RECLAIMED => 27; use constant HIGH_NR_ANON_RECLAIMED => 28; my %perprocesspid; my %perprocess; my %last_procmap; my $opt_ignorepid; my $opt_read_procstat; my $total_wakeup_kswapd; my ($total_direct_reclaim, $total_direct_nr_scanned); my ($total_direct_nr_file_scanned, $total_direct_nr_anon_scanned); my ($total_direct_latency, $total_kswapd_latency); my ($total_direct_nr_reclaimed); my ($total_direct_nr_file_reclaimed, $total_direct_nr_anon_reclaimed); my ($total_direct_writepage_file_sync, $total_direct_writepage_file_async); my ($total_direct_writepage_anon_sync, $total_direct_writepage_anon_async); my ($total_kswapd_nr_scanned, $total_kswapd_wake); my ($total_kswapd_nr_file_scanned, $total_kswapd_nr_anon_scanned); my ($total_kswapd_writepage_file_sync, $total_kswapd_writepage_file_async); my ($total_kswapd_writepage_anon_sync, $total_kswapd_writepage_anon_async); my ($total_kswapd_nr_reclaimed); my ($total_kswapd_nr_file_reclaimed, $total_kswapd_nr_anon_reclaimed); # Catch sigint and exit on request my $sigint_report = 0; my $sigint_exit = 0; my $sigint_pending = 0; my $sigint_received = 0; sub sigint_handler { my $current_time = time; if ($current_time - 2 > $sigint_received) { print "SIGINT received, report pending. Hit ctrl-c again to exit\n"; $sigint_report = 1; } else { if (!$sigint_exit) { print "Second SIGINT received quickly, exiting\n"; } $sigint_exit++; } if ($sigint_exit > 3) { print "Many SIGINTs received, exiting now without report\n"; exit; } $sigint_received = $current_time; $sigint_pending = 1; } $SIG{INT} = "sigint_handler"; # Parse command line options GetOptions( 'ignore-pid' => \$opt_ignorepid, 'read-procstat' => \$opt_read_procstat, ); # Defaults for dynamically discovered regex's my $regex_direct_begin_default = 'order=([0-9]*) may_writepage=([0-9]*) gfp_flags=([A-Z_|]*)'; my $regex_direct_end_default = 'nr_reclaimed=([0-9]*)'; my $regex_kswapd_wake_default = 'nid=([0-9]*) order=([0-9]*)'; my $regex_kswapd_sleep_default = 'nid=([0-9]*)'; my $regex_wakeup_kswapd_default = 'nid=([0-9]*) zid=([0-9]*) order=([0-9]*) gfp_flags=([A-Z_|]*)'; my $regex_lru_isolate_default = 'isolate_mode=([0-9]*) classzone_idx=([0-9]*) order=([0-9]*) nr_requested=([0-9]*) nr_scanned=([0-9]*) nr_skipped=([0-9]*) nr_taken=([0-9]*) lru=([a-z_]*)'; my $regex_lru_shrink_inactive_default = 'nid=([0-9]*) nr_scanned=([0-9]*) nr_reclaimed=([0-9]*) nr_dirty=([0-9]*) nr_writeback=([0-9]*) nr_congested=([0-9]*) nr_immediate=([0-9]*) nr_activate_anon=([0-9]*) nr_activate_file=([0-9]*) nr_ref_keep=([0-9]*) nr_unmap_fail=([0-9]*) priority=([0-9]*) flags=([A-Z_|]*)'; my $regex_lru_shrink_active_default = 'lru=([A-Z_]*) nr_scanned=([0-9]*) nr_rotated=([0-9]*) priority=([0-9]*)'; my $regex_writepage_default = 'page=([0-9a-f]*) pfn=([0-9]*) flags=([A-Z_|]*)'; # Dyanically discovered regex my $regex_direct_begin; my $regex_direct_end; my $regex_kswapd_wake; my $regex_kswapd_sleep; my $regex_wakeup_kswapd; my $regex_lru_isolate; my $regex_lru_shrink_inactive; my $regex_lru_shrink_active; my $regex_writepage; # Static regex used. Specified like this for readability and for use with /o # (process_pid) (cpus ) ( time ) (tpoint ) (details) my $regex_traceevent = '\s*([a-zA-Z0-9-]*)\s*(\[[0-9]*\])(\s*[dX.][Nnp.][Hhs.][0-9a-fA-F.]*|)\s*([0-9.]*):\s*([a-zA-Z_]*):\s*(.*)'; my $regex_statname = '[-0-9]*\s\((.*)\).*'; my $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z]\s([0-9]*).*'; sub generate_traceevent_regex { my $event = shift; my $default = shift; my $regex; # Read the event format or use the default if (!open (FORMAT, "/sys/kernel/debug/tracing/events/$event/format")) { print("WARNING: Event $event format string not found\n"); return $default; } else { my $line; while (!eof(FORMAT)) { $line = <FORMAT>; $line =~ s/, REC->.*//; if ($line =~ /^print fmt:\s"(.*)".*/) { $regex = $1; $regex =~ s/%s/\([0-9a-zA-Z|_]*\)/g; $regex =~ s/%p/\([0-9a-f]*\)/g; $regex =~ s/%d/\([-0-9]*\)/g; $regex =~ s/%ld/\([-0-9]*\)/g; $regex =~ s/%lu/\([0-9]*\)/g; } } } # Can't handle the print_flags stuff but in the context of this # script, it really doesn't matter $regex =~ s/\(REC.*\) \? __print_flags.*//; # Verify fields are in the right order my $tuple; foreach $tuple (split /\s/, $regex) { my ($key, $value) = split(/=/, $tuple); my $expected = shift; if ($key ne $expected) { print("WARNING: Format not as expected for event $event '$key' != '$expected'\n"); $regex =~ s/$key=\((.*)\)/$key=$1/; } } if (defined shift) { die("Fewer fields than expected in format"); } return $regex; } $regex_direct_begin = generate_traceevent_regex( "vmscan/mm_vmscan_direct_reclaim_begin", $regex_direct_begin_default, "order", "may_writepage", "gfp_flags"); $regex_direct_end = generate_traceevent_regex( "vmscan/mm_vmscan_direct_reclaim_end", $regex_direct_end_default, "nr_reclaimed"); $regex_kswapd_wake = generate_traceevent_regex( "vmscan/mm_vmscan_kswapd_wake", $regex_kswapd_wake_default, "nid", "order"); $regex_kswapd_sleep = generate_traceevent_regex( "vmscan/mm_vmscan_kswapd_sleep", $regex_kswapd_sleep_default, "nid"); $regex_wakeup_kswapd = generate_traceevent_regex( "vmscan/mm_vmscan_wakeup_kswapd", $regex_wakeup_kswapd_default, "nid", "zid", "order", "gfp_flags"); $regex_lru_isolate = generate_traceevent_regex( "vmscan/mm_vmscan_lru_isolate", $regex_lru_isolate_default, "isolate_mode", "classzone_idx", "order", "nr_requested", "nr_scanned", "nr_skipped", "nr_taken", "lru"); $regex_lru_shrink_inactive = generate_traceevent_regex( "vmscan/mm_vmscan_lru_shrink_inactive", $regex_lru_shrink_inactive_default, "nid", "nr_scanned", "nr_reclaimed", "nr_dirty", "nr_writeback", "nr_congested", "nr_immediate", "nr_activate_anon", "nr_activate_file", "nr_ref_keep", "nr_unmap_fail", "priority", "flags"); $regex_lru_shrink_active = generate_traceevent_regex( "vmscan/mm_vmscan_lru_shrink_active", $regex_lru_shrink_active_default, "nid", "zid", "lru", "nr_scanned", "nr_rotated", "priority"); $regex_writepage = generate_traceevent_regex( "vmscan/mm_vmscan_writepage", $regex_writepage_default, "page", "pfn", "flags"); sub read_statline($) { my $pid = $_[0]; my $statline; if (open(STAT, "/proc/$pid/stat")) { $statline = <STAT>; close(STAT); } if ($statline eq '') { $statline = "-1 (UNKNOWN_PROCESS_NAME) R 0"; } return $statline; } sub guess_process_pid($$) { my $pid = $_[0]; my $statline = $_[1]; if ($pid == 0) { return "swapper-0"; } if ($statline !~ /$regex_statname/o) { die("Failed to math stat line for process name :: $statline"); } return "$1-$pid"; } # Convert sec.usec timestamp format sub timestamp_to_ms($) { my $timestamp = $_[0]; my ($sec, $usec) = split (/\./, $timestamp); return ($sec * 1000) + ($usec / 1000); } sub process_events { my $traceevent; my $process_pid; my $cpus; my $timestamp; my $tracepoint; my $details; my $statline; # Read each line of the event log EVENT_PROCESS: while ($traceevent = <STDIN>) { if ($traceevent =~ /$regex_traceevent/o) { $process_pid = $1; $timestamp = $4; $tracepoint = $5; $process_pid =~ /(.*)-([0-9]*)$/; my $process = $1; my $pid = $2; if ($process eq "") { $process = $last_procmap{$pid}; $process_pid = "$process-$pid"; } $last_procmap{$pid} = $process; if ($opt_read_procstat) { $statline = read_statline($pid); if ($opt_read_procstat && $process eq '') { $process_pid = guess_process_pid($pid, $statline); } } } else { next; } # Perl Switch() sucks majorly if ($tracepoint eq "mm_vmscan_direct_reclaim_begin") { $timestamp = timestamp_to_ms($timestamp); $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}++; $perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN} = $timestamp; $details = $6; if ($details !~ /$regex_direct_begin/o) { print "WARNING: Failed to parse mm_vmscan_direct_reclaim_begin as expected\n"; print " $details\n"; print " $regex_direct_begin\n"; next; } my $order = $1; $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order]++; $perprocesspid{$process_pid}->{STATE_DIRECT_ORDER} = $order; } elsif ($tracepoint eq "mm_vmscan_direct_reclaim_end") { # Count the event itself my $index = $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_END}; $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_END}++; # Record how long direct reclaim took this time if (defined $perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN}) { $timestamp = timestamp_to_ms($timestamp); my $order = $perprocesspid{$process_pid}->{STATE_DIRECT_ORDER}; my $latency = ($timestamp - $perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN}); $perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index] = "$order-$latency"; } } elsif ($tracepoint eq "mm_vmscan_kswapd_wake") { $details = $6; if ($details !~ /$regex_kswapd_wake/o) { print "WARNING: Failed to parse mm_vmscan_kswapd_wake as expected\n"; print " $details\n"; print " $regex_kswapd_wake\n"; next; } my $order = $2; $perprocesspid{$process_pid}->{STATE_KSWAPD_ORDER} = $order; if (!$perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN}) { $timestamp = timestamp_to_ms($timestamp); $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}++; $perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN} = $timestamp; $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order]++; } else { $perprocesspid{$process_pid}->{HIGH_KSWAPD_REWAKEUP}++; $perprocesspid{$process_pid}->{HIGH_KSWAPD_REWAKEUP_PERORDER}[$order]++; } } elsif ($tracepoint eq "mm_vmscan_kswapd_sleep") { # Count the event itself my $index = $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_SLEEP}; $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_SLEEP}++; # Record how long kswapd was awake $timestamp = timestamp_to_ms($timestamp); my $order = $perprocesspid{$process_pid}->{STATE_KSWAPD_ORDER}; my $latency = ($timestamp - $perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN}); $perprocesspid{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index] = "$order-$latency"; $perprocesspid{$process_pid}->{STATE_KSWAPD_BEGIN} = 0; } elsif ($tracepoint eq "mm_vmscan_wakeup_kswapd") { $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}++; $details = $6; if ($details !~ /$regex_wakeup_kswapd/o) { print "WARNING: Failed to parse mm_vmscan_wakeup_kswapd as expected\n"; print " $details\n"; print " $regex_wakeup_kswapd\n"; next; } my $order = $3; $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order]++; } elsif ($tracepoint eq "mm_vmscan_lru_isolate") { $details = $6; if ($details !~ /$regex_lru_isolate/o) { print "WARNING: Failed to parse mm_vmscan_lru_isolate as expected\n"; print " $details\n"; print " $regex_lru_isolate/o\n"; next; } my $isolate_mode = $1; my $nr_scanned = $5; my $file = $8; # To closer match vmstat scanning statistics, only count isolate_both # and isolate_inactive as scanning. isolate_active is rotation # isolate_inactive == 1 # isolate_active == 2 # isolate_both == 3 if ($isolate_mode != 2) { $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned; if ($file =~ /_file/) { $perprocesspid{$process_pid}->{HIGH_NR_FILE_SCANNED} += $nr_scanned; } else { $perprocesspid{$process_pid}->{HIGH_NR_ANON_SCANNED} += $nr_scanned; } } } elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") { $details = $6; if ($details !~ /$regex_lru_shrink_inactive/o) { print "WARNING: Failed to parse mm_vmscan_lru_shrink_inactive as expected\n"; print " $details\n"; print " $regex_lru_shrink_inactive/o\n"; next; } my $nr_reclaimed = $3; my $flags = $13; my $file = 0; if ($flags =~ /RECLAIM_WB_FILE/) { $file = 1; } $perprocesspid{$process_pid}->{HIGH_NR_RECLAIMED} += $nr_reclaimed; if ($file) { $perprocesspid{$process_pid}->{HIGH_NR_FILE_RECLAIMED} += $nr_reclaimed; } else { $perprocesspid{$process_pid}->{HIGH_NR_ANON_RECLAIMED} += $nr_reclaimed; } } elsif ($tracepoint eq "mm_vmscan_writepage") { $details = $6; if ($details !~ /$regex_writepage/o) { print "WARNING: Failed to parse mm_vmscan_writepage as expected\n"; print " $details\n"; print " $regex_writepage\n"; next; } my $flags = $3; my $file = 0; my $sync_io = 0; if ($flags =~ /RECLAIM_WB_FILE/) { $file = 1; } if ($flags =~ /RECLAIM_WB_SYNC/) { $sync_io = 1; } if ($sync_io) { if ($file) { $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC}++; } else { $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC}++; } } else { if ($file) { $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC}++; } else { $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC}++; } } } else { $perprocesspid{$process_pid}->{EVENT_UNKNOWN}++; } if ($sigint_pending) { last EVENT_PROCESS; } } } sub dump_stats { my $hashref = shift; my %stats = %$hashref; # Dump per-process stats my $process_pid; my $max_strlen = 0; # Get the maximum process name foreach $process_pid (keys %perprocesspid) { my $len = length($process_pid); if ($len > $max_strlen) { $max_strlen = $len; } } $max_strlen += 2; # Work out latencies printf("\n") if !$opt_ignorepid; printf("Reclaim latencies expressed as order-latency_in_ms\n") if !$opt_ignorepid; foreach $process_pid (keys %stats) { if (!$stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[0] && !$stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[0]) { next; } printf "%-" . $max_strlen . "s ", $process_pid if !$opt_ignorepid; my $index = 0; while (defined $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index] || defined $stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index]) { if ($stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]) { printf("%s ", $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]) if !$opt_ignorepid; my ($dummy, $latency) = split(/-/, $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]); $total_direct_latency += $latency; } else { printf("%s ", $stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index]) if !$opt_ignorepid; my ($dummy, $latency) = split(/-/, $stats{$process_pid}->{HIGH_KSWAPD_LATENCY}[$index]); $total_kswapd_latency += $latency; } $index++; } print "\n" if !$opt_ignorepid; } # Print out process activity printf("\n"); printf("%-" . $max_strlen . "s %8s %10s %8s %8s %8s %8s %8s %8s\n", "Process", "Direct", "Wokeup", "Pages", "Pages", "Pages", "Pages", "Time"); printf("%-" . $max_strlen . "s %8s %10s %8s %8s %8s %8s %8s %8s\n", "details", "Rclms", "Kswapd", "Scanned", "Rclmed", "Sync-IO", "ASync-IO", "Stalled"); foreach $process_pid (keys %stats) { if (!$stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}) { next; } $total_direct_reclaim += $stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}; $total_wakeup_kswapd += $stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}; $total_direct_nr_scanned += $stats{$process_pid}->{HIGH_NR_SCANNED}; $total_direct_nr_file_scanned += $stats{$process_pid}->{HIGH_NR_FILE_SCANNED}; $total_direct_nr_anon_scanned += $stats{$process_pid}->{HIGH_NR_ANON_SCANNED}; $total_direct_nr_reclaimed += $stats{$process_pid}->{HIGH_NR_RECLAIMED}; $total_direct_nr_file_reclaimed += $stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED}; $total_direct_nr_anon_reclaimed += $stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED}; $total_direct_writepage_file_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC}; $total_direct_writepage_anon_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC}; $total_direct_writepage_file_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC}; $total_direct_writepage_anon_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC}; my $index = 0; my $this_reclaim_delay = 0; while (defined $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]) { my ($dummy, $latency) = split(/-/, $stats{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index]); $this_reclaim_delay += $latency; $index++; } printf("%-" . $max_strlen . "s %8d %10d %8u %8u %8u %8u %8.3f", $process_pid, $stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}, $stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}, $stats{$process_pid}->{HIGH_NR_SCANNED}, $stats{$process_pid}->{HIGH_NR_FILE_SCANNED}, $stats{$process_pid}->{HIGH_NR_ANON_SCANNED}, $stats{$process_pid}->{HIGH_NR_RECLAIMED}, $stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED}, $stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED}, $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC}, $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC}, $this_reclaim_delay / 1000); if ($stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}) { print " "; for (my $order = 0; $order < 20; $order++) { my $count = $stats{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order]; if ($count != 0) { print "direct-$order=$count "; } } } if ($stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}) { print " "; for (my $order = 0; $order < 20; $order++) { my $count = $stats{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order]; if ($count != 0) { print "wakeup-$order=$count "; } } } print "\n"; } # Print out kswapd activity printf("\n"); printf("%-" . $max_strlen . "s %8s %10s %8s %8s %8s %8s\n", "Kswapd", "Kswapd", "Order", "Pages", "Pages", "Pages", "Pages"); printf("%-" . $max_strlen . "s %8s %10s %8s %8s %8s %8s\n", "Instance", "Wakeups", "Re-wakeup", "Scanned", "Rclmed", "Sync-IO", "ASync-IO"); foreach $process_pid (keys %stats) { if (!$stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}) { next; } $total_kswapd_wake += $stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}; $total_kswapd_nr_scanned += $stats{$process_pid}->{HIGH_NR_SCANNED}; $total_kswapd_nr_file_scanned += $stats{$process_pid}->{HIGH_NR_FILE_SCANNED}; $total_kswapd_nr_anon_scanned += $stats{$process_pid}->{HIGH_NR_ANON_SCANNED}; $total_kswapd_nr_reclaimed += $stats{$process_pid}->{HIGH_NR_RECLAIMED}; $total_kswapd_nr_file_reclaimed += $stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED}; $total_kswapd_nr_anon_reclaimed += $stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED}; $total_kswapd_writepage_file_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC}; $total_kswapd_writepage_anon_sync += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC}; $total_kswapd_writepage_file_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC}; $total_kswapd_writepage_anon_async += $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC}; printf("%-" . $max_strlen . "s %8d %10d %8u %8u %8i %8u", $process_pid, $stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}, $stats{$process_pid}->{HIGH_KSWAPD_REWAKEUP}, $stats{$process_pid}->{HIGH_NR_SCANNED}, $stats{$process_pid}->{HIGH_NR_FILE_SCANNED}, $stats{$process_pid}->{HIGH_NR_ANON_SCANNED}, $stats{$process_pid}->{HIGH_NR_RECLAIMED}, $stats{$process_pid}->{HIGH_NR_FILE_RECLAIMED}, $stats{$process_pid}->{HIGH_NR_ANON_RECLAIMED}, $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC}, $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC} + $stats{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC}); if ($stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}) { print " "; for (my $order = 0; $order < 20; $order++) { my $count = $stats{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order]; if ($count != 0) { print "wake-$order=$count "; } } } if ($stats{$process_pid}->{HIGH_KSWAPD_REWAKEUP}) { print " "; for (my $order = 0; $order < 20; $order++) { my $count = $stats{$process_pid}->{HIGH_KSWAPD_REWAKEUP_PERORDER}[$order]; if ($count != 0) { print "rewake-$order=$count "; } } } printf("\n"); } # Print out summaries $total_direct_latency /= 1000; $total_kswapd_latency /= 1000; print "\nSummary\n"; print "Direct reclaims: $total_direct_reclaim\n"; print "Direct reclaim pages scanned: $total_direct_nr_scanned\n"; print "Direct reclaim file pages scanned: $total_direct_nr_file_scanned\n"; print "Direct reclaim anon pages scanned: $total_direct_nr_anon_scanned\n"; print "Direct reclaim pages reclaimed: $total_direct_nr_reclaimed\n"; print "Direct reclaim file pages reclaimed: $total_direct_nr_file_reclaimed\n"; print "Direct reclaim anon pages reclaimed: $total_direct_nr_anon_reclaimed\n"; print "Direct reclaim write file sync I/O: $total_direct_writepage_file_sync\n"; print "Direct reclaim write anon sync I/O: $total_direct_writepage_anon_sync\n"; print "Direct reclaim write file async I/O: $total_direct_writepage_file_async\n"; print "Direct reclaim write anon async I/O: $total_direct_writepage_anon_async\n"; print "Wake kswapd requests: $total_wakeup_kswapd\n"; printf "Time stalled direct reclaim: %-1.2f seconds\n", $total_direct_latency; print "\n"; print "Kswapd wakeups: $total_kswapd_wake\n"; print "Kswapd pages scanned: $total_kswapd_nr_scanned\n"; print "Kswapd file pages scanned: $total_kswapd_nr_file_scanned\n"; print "Kswapd anon pages scanned: $total_kswapd_nr_anon_scanned\n"; print "Kswapd pages reclaimed: $total_kswapd_nr_reclaimed\n"; print "Kswapd file pages reclaimed: $total_kswapd_nr_file_reclaimed\n"; print "Kswapd anon pages reclaimed: $total_kswapd_nr_anon_reclaimed\n"; print "Kswapd reclaim write file sync I/O: $total_kswapd_writepage_file_sync\n"; print "Kswapd reclaim write anon sync I/O: $total_kswapd_writepage_anon_sync\n"; print "Kswapd reclaim write file async I/O: $total_kswapd_writepage_file_async\n"; print "Kswapd reclaim write anon async I/O: $total_kswapd_writepage_anon_async\n"; printf "Time kswapd awake: %-1.2f seconds\n", $total_kswapd_latency; } sub aggregate_perprocesspid() { my $process_pid; my $process; undef %perprocess; foreach $process_pid (keys %perprocesspid) { $process = $process_pid; $process =~ s/-([0-9])*$//; if ($process eq '') { $process = "NO_PROCESS_NAME"; } $perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN} += $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}; $perprocess{$process}->{MM_VMSCAN_KSWAPD_WAKE} += $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE}; $perprocess{$process}->{MM_VMSCAN_WAKEUP_KSWAPD} += $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}; $perprocess{$process}->{HIGH_KSWAPD_REWAKEUP} += $perprocesspid{$process_pid}->{HIGH_KSWAPD_REWAKEUP}; $perprocess{$process}->{HIGH_NR_SCANNED} += $perprocesspid{$process_pid}->{HIGH_NR_SCANNED}; $perprocess{$process}->{HIGH_NR_FILE_SCANNED} += $perprocesspid{$process_pid}->{HIGH_NR_FILE_SCANNED}; $perprocess{$process}->{HIGH_NR_ANON_SCANNED} += $perprocesspid{$process_pid}->{HIGH_NR_ANON_SCANNED}; $perprocess{$process}->{HIGH_NR_RECLAIMED} += $perprocesspid{$process_pid}->{HIGH_NR_RECLAIMED}; $perprocess{$process}->{HIGH_NR_FILE_RECLAIMED} += $perprocesspid{$process_pid}->{HIGH_NR_FILE_RECLAIMED}; $perprocess{$process}->{HIGH_NR_ANON_RECLAIMED} += $perprocesspid{$process_pid}->{HIGH_NR_ANON_RECLAIMED}; $perprocess{$process}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_SYNC}; $perprocess{$process}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_SYNC}; $perprocess{$process}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_FILE_ASYNC}; $perprocess{$process}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC} += $perprocesspid{$process_pid}->{MM_VMSCAN_WRITEPAGE_ANON_ASYNC}; for (my $order = 0; $order < 20; $order++) { $perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order] += $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN_PERORDER}[$order]; $perprocess{$process}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order] += $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order]; $perprocess{$process}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order] += $perprocesspid{$process_pid}->{MM_VMSCAN_KSWAPD_WAKE_PERORDER}[$order]; } # Aggregate direct reclaim latencies my $wr_index = $perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_END}; my $rd_index = 0; while (defined $perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$rd_index]) { $perprocess{$process}->{HIGH_DIRECT_RECLAIM_LATENCY}[$wr_index] = $perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$rd_index]; $rd_index++; $wr_index++; } $perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_END} = $wr_index; # Aggregate kswapd latencies my $wr_index = $perprocess{$process}->{MM_VMSCAN_KSWAPD_SLEEP}; my $rd_index = 0; while (defined $perprocesspid{$process_pid}->{HIGH_KSWAPD_LATENCY}[$rd_index]) { $perprocess{$process}->{HIGH_KSWAPD_LATENCY}[$wr_index] = $perprocesspid{$process_pid}->{HIGH_KSWAPD_LATENCY}[$rd_index]; $rd_index++; $wr_index++; } $perprocess{$process}->{MM_VMSCAN_DIRECT_RECLAIM_END} = $wr_index; } } sub report() { if (!$opt_ignorepid) { dump_stats(\%perprocesspid); } else { aggregate_perprocesspid(); dump_stats(\%perprocess); } } # Process events or signals until neither is available sub signal_loop() { my $sigint_processed; do { $sigint_processed = 0; process_events(); # Handle pending signals if any if ($sigint_pending) { my $current_time = time; if ($sigint_exit) { print "Received exit signal\n"; $sigint_pending = 0; } if ($sigint_report) { if ($current_time >= $sigint_received + 2) { report(); $sigint_report = 0; $sigint_pending = 0; $sigint_processed = 1; } } } } while ($sigint_pending || $sigint_processed); } signal_loop(); report(); devicetree/bindings/Makefile 0000644 00000002066 14722053057 0012131 0 ustar 00 # SPDX-License-Identifier: GPL-2.0 DT_DOC_CHECKER ?= dt-doc-validate DT_EXTRACT_EX ?= dt-extract-example DT_MK_SCHEMA ?= dt-mk-schema DT_MK_SCHEMA_FLAGS := $(if $(DT_SCHEMA_FILES), -u) quiet_cmd_chk_binding = CHKDT $(patsubst $(srctree)/%,%,$<) cmd_chk_binding = $(DT_DOC_CHECKER) -u $(srctree)/$(src) $< ; \ $(DT_EXTRACT_EX) $< > $@ $(obj)/%.example.dts: $(src)/%.yaml FORCE $(call if_changed,chk_binding) DT_TMP_SCHEMA := processed-schema.yaml quiet_cmd_mk_schema = SCHEMA $@ cmd_mk_schema = $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $(real-prereqs) DT_DOCS = $(shell \ cd $(srctree)/$(src) && \ find * \( -name '*.yaml' ! \ -name $(DT_TMP_SCHEMA) ! \ -name '*.example.dt.yaml' \) \ ) DT_SCHEMA_FILES ?= $(addprefix $(src)/,$(DT_DOCS)) ifeq ($(CHECK_DTBS),) extra-y += $(patsubst $(src)/%.yaml,%.example.dts, $(DT_SCHEMA_FILES)) extra-y += $(patsubst $(src)/%.yaml,%.example.dt.yaml, $(DT_SCHEMA_FILES)) endif $(obj)/$(DT_TMP_SCHEMA): $(DT_SCHEMA_FILES) FORCE $(call if_changed,mk_schema) extra-y += $(DT_TMP_SCHEMA) sphinx/parse-headers.pl 0000755 00000020564 14722053057 0011154 0 ustar 00 #!/usr/bin/env perl use strict; use Text::Tabs; use Getopt::Long; use Pod::Usage; my $debug; my $help; my $man; GetOptions( "debug" => \$debug, 'usage|?' => \$help, 'help' => \$man ) or pod2usage(2); pod2usage(1) if $help; pod2usage(-exitstatus => 0, -verbose => 2) if $man; pod2usage(2) if (scalar @ARGV < 2 || scalar @ARGV > 3); my ($file_in, $file_out, $file_exceptions) = @ARGV; my $data; my %ioctls; my %defines; my %typedefs; my %enums; my %enum_symbols; my %structs; require Data::Dumper if ($debug); # # read the file and get identifiers # my $is_enum = 0; my $is_comment = 0; open IN, $file_in or die "Can't open $file_in"; while (<IN>) { $data .= $_; my $ln = $_; if (!$is_comment) { $ln =~ s,/\*.*(\*/),,g; $is_comment = 1 if ($ln =~ s,/\*.*,,); } else { if ($ln =~ s,^(.*\*/),,) { $is_comment = 0; } else { next; } } if ($is_enum && $ln =~ m/^\s*([_\w][\w\d_]+)\s*[\,=]?/) { my $s = $1; my $n = $1; $n =~ tr/A-Z/a-z/; $n =~ tr/_/-/; $enum_symbols{$s} = "\\ :ref:`$s <$n>`\\ "; $is_enum = 0 if ($is_enum && m/\}/); next; } $is_enum = 0 if ($is_enum && m/\}/); if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+_IO/) { my $s = $1; my $n = $1; $n =~ tr/A-Z/a-z/; $ioctls{$s} = "\\ :ref:`$s <$n>`\\ "; next; } if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+/) { my $s = $1; my $n = $1; $n =~ tr/A-Z/a-z/; $n =~ tr/_/-/; $defines{$s} = "\\ :ref:`$s <$n>`\\ "; next; } if ($ln =~ m/^\s*typedef\s+([_\w][\w\d_]+)\s+(.*)\s+([_\w][\w\d_]+);/) { my $s = $2; my $n = $3; $typedefs{$n} = "\\ :c:type:`$n <$s>`\\ "; next; } if ($ln =~ m/^\s*enum\s+([_\w][\w\d_]+)\s+\{/ || $ln =~ m/^\s*enum\s+([_\w][\w\d_]+)$/ || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)\s+\{/ || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)$/) { my $s = $1; $enums{$s} = "enum :c:type:`$s`\\ "; $is_enum = $1; next; } if ($ln =~ m/^\s*struct\s+([_\w][\w\d_]+)\s+\{/ || $ln =~ m/^\s*struct\s+([[_\w][\w\d_]+)$/ || $ln =~ m/^\s*typedef\s*struct\s+([_\w][\w\d_]+)\s+\{/ || $ln =~ m/^\s*typedef\s*struct\s+([[_\w][\w\d_]+)$/ ) { my $s = $1; $structs{$s} = "struct :c:type:`$s`\\ "; next; } } close IN; # # Handle multi-line typedefs # my @matches = ($data =~ m/typedef\s+struct\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g, $data =~ m/typedef\s+enum\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,); foreach my $m (@matches) { my $s = $m; $typedefs{$s} = "\\ :c:type:`$s`\\ "; next; } # # Handle exceptions, if any # my %def_reftype = ( "ioctl" => ":ref", "define" => ":ref", "symbol" => ":ref", "typedef" => ":c:type", "enum" => ":c:type", "struct" => ":c:type", ); if ($file_exceptions) { open IN, $file_exceptions or die "Can't read $file_exceptions"; while (<IN>) { next if (m/^\s*$/ || m/^\s*#/); # Parsers to ignore a symbol if (m/^ignore\s+ioctl\s+(\S+)/) { delete $ioctls{$1} if (exists($ioctls{$1})); next; } if (m/^ignore\s+define\s+(\S+)/) { delete $defines{$1} if (exists($defines{$1})); next; } if (m/^ignore\s+typedef\s+(\S+)/) { delete $typedefs{$1} if (exists($typedefs{$1})); next; } if (m/^ignore\s+enum\s+(\S+)/) { delete $enums{$1} if (exists($enums{$1})); next; } if (m/^ignore\s+struct\s+(\S+)/) { delete $structs{$1} if (exists($structs{$1})); next; } if (m/^ignore\s+symbol\s+(\S+)/) { delete $enum_symbols{$1} if (exists($enum_symbols{$1})); next; } # Parsers to replace a symbol my ($type, $old, $new, $reftype); if (m/^replace\s+(\S+)\s+(\S+)\s+(\S+)/) { $type = $1; $old = $2; $new = $3; } else { die "Can't parse $file_exceptions: $_"; } if ($new =~ m/^\:c\:(data|func|macro|type)\:\`(.+)\`/) { $reftype = ":c:$1"; $new = $2; } elsif ($new =~ m/\:ref\:\`(.+)\`/) { $reftype = ":ref"; $new = $1; } else { $reftype = $def_reftype{$type}; } $new = "$reftype:`$old <$new>`"; if ($type eq "ioctl") { $ioctls{$old} = $new if (exists($ioctls{$old})); next; } if ($type eq "define") { $defines{$old} = $new if (exists($defines{$old})); next; } if ($type eq "symbol") { $enum_symbols{$old} = $new if (exists($enum_symbols{$old})); next; } if ($type eq "typedef") { $typedefs{$old} = $new if (exists($typedefs{$old})); next; } if ($type eq "enum") { $enums{$old} = $new if (exists($enums{$old})); next; } if ($type eq "struct") { $structs{$old} = $new if (exists($structs{$old})); next; } die "Can't parse $file_exceptions: $_"; } } if ($debug) { print Data::Dumper->Dump([\%ioctls], [qw(*ioctls)]) if (%ioctls); print Data::Dumper->Dump([\%typedefs], [qw(*typedefs)]) if (%typedefs); print Data::Dumper->Dump([\%enums], [qw(*enums)]) if (%enums); print Data::Dumper->Dump([\%structs], [qw(*structs)]) if (%structs); print Data::Dumper->Dump([\%defines], [qw(*defines)]) if (%defines); print Data::Dumper->Dump([\%enum_symbols], [qw(*enum_symbols)]) if (%enum_symbols); } # # Align block # $data = expand($data); $data = " " . $data; $data =~ s/\n/\n /g; $data =~ s/\n\s+$/\n/g; $data =~ s/\n\s+\n/\n\n/g; # # Add escape codes for special characters # $data =~ s,([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^]),\\$1,g; $data =~ s,DEPRECATED,**DEPRECATED**,g; # # Add references # my $start_delim = "[ \n\t\(\=\*\@]"; my $end_delim = "(\\s|,|\\\\=|\\\\:|\\;|\\\)|\\}|\\{)"; foreach my $r (keys %ioctls) { my $s = $ioctls{$r}; $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; print "$r -> $s\n" if ($debug); $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; } foreach my $r (keys %defines) { my $s = $defines{$r}; $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; print "$r -> $s\n" if ($debug); $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; } foreach my $r (keys %enum_symbols) { my $s = $enum_symbols{$r}; $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; print "$r -> $s\n" if ($debug); $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; } foreach my $r (keys %enums) { my $s = $enums{$r}; $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; print "$r -> $s\n" if ($debug); $data =~ s/enum\s+($r)$end_delim/$s$2/g; } foreach my $r (keys %structs) { my $s = $structs{$r}; $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; print "$r -> $s\n" if ($debug); $data =~ s/struct\s+($r)$end_delim/$s$2/g; } foreach my $r (keys %typedefs) { my $s = $typedefs{$r}; $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g; print "$r -> $s\n" if ($debug); $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g; } $data =~ s/\\ ([\n\s])/\1/g; # # Generate output file # my $title = $file_in; $title =~ s,.*/,,; open OUT, "> $file_out" or die "Can't open $file_out"; print OUT ".. -*- coding: utf-8; mode: rst -*-\n\n"; print OUT "$title\n"; print OUT "=" x length($title); print OUT "\n\n.. parsed-literal::\n\n"; print OUT $data; close OUT; __END__ =head1 NAME parse_headers.pl - parse a C file, in order to identify functions, structs, enums and defines and create cross-references to a Sphinx book. =head1 SYNOPSIS B<parse_headers.pl> [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>] Where <options> can be: --debug, --help or --usage. =head1 OPTIONS =over 8 =item B<--debug> Put the script in verbose mode, useful for debugging. =item B<--usage> Prints a brief help message and exits. =item B<--help> Prints a more detailed help message and exits. =back =head1 DESCRIPTION Convert a C header or source file (C_FILE), into a ReStructured Text included via ..parsed-literal block with cross-references for the documentation files that describe the API. It accepts an optional EXCEPTIONS_FILE with describes what elements will be either ignored or be pointed to a non-default reference. The output is written at the (OUT_FILE). It is capable of identifying defines, functions, structs, typedefs, enums and enum symbols and create cross-references for all of them. It is also capable of distinguish #define used for specifying a Linux ioctl. The EXCEPTIONS_FILE contain two rules to allow ignoring a symbol or to replace the default references by a custom one. Please read Documentation/doc-guide/parse-headers.rst at the Kernel's tree for more details. =head1 BUGS Report bugs to Mauro Carvalho Chehab <mchehab@kernel.org> =head1 COPYRIGHT Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>. License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. =cut Makefile 0000644 00000012413 14722053057 0006212 0 ustar 00 # -*- makefile -*- # Makefile for Sphinx documentation # subdir-y := devicetree/bindings/ # Check for broken documentation file references ifeq ($(CONFIG_WARN_MISSING_DOCUMENTS),y) $(shell $(srctree)/scripts/documentation-file-ref-check --warn) endif # You can set these variables from the command line. SPHINXBUILD = sphinx-build SPHINXOPTS = SPHINXDIRS = . _SPHINXDIRS = $(patsubst $(srctree)/Documentation/%/conf.py,%,$(wildcard $(srctree)/Documentation/*/conf.py)) SPHINX_CONF = conf.py PAPER = BUILDDIR = $(obj)/output PDFLATEX = xelatex LATEXOPTS = -interaction=batchmode # User-friendly check for sphinx-build HAVE_SPHINX := $(shell if which $(SPHINXBUILD) >/dev/null 2>&1; then echo 1; else echo 0; fi) ifeq ($(HAVE_SPHINX),0) .DEFAULT: $(warning The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed and in PATH, or set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable.) @echo @$(srctree)/scripts/sphinx-pre-install @echo " SKIP Sphinx $@ target." else # HAVE_SPHINX export SPHINXOPTS = $(shell perl -e 'open IN,"sphinx-build --version 2>&1 |"; while (<IN>) { if (m/([\d\.]+)/) { print "-jauto" if ($$1 >= "1.7") } ;} close IN') # User-friendly check for pdflatex and latexmk HAVE_PDFLATEX := $(shell if which $(PDFLATEX) >/dev/null 2>&1; then echo 1; else echo 0; fi) HAVE_LATEXMK := $(shell if which latexmk >/dev/null 2>&1; then echo 1; else echo 0; fi) ifeq ($(HAVE_LATEXMK),1) PDFLATEX := latexmk -$(PDFLATEX) endif #HAVE_LATEXMK # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter KERNELDOC = $(srctree)/scripts/kernel-doc KERNELDOC_CONF = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC) ALLSPHINXOPTS = $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # commands; the 'cmd' from scripts/Kbuild.include is not *loopable* loop_cmd = $(echo-cmd) $(cmd_$(1)) || exit; # $2 sphinx builder e.g. "html" # $3 name of the build subfolder / e.g. "media", used as: # * dest folder relative to $(BUILDDIR) and # * cache folder relative to $(BUILDDIR)/.doctrees # $4 dest subfolder e.g. "man" for man pages at media/man # $5 reST source folder relative to $(srctree)/$(src), # e.g. "media" for the linux-tv book-set at ./Documentation/media quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4) cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media $2 && \ PYTHONDONTWRITEBYTECODE=1 \ BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \ $(SPHINXBUILD) \ -b $2 \ -c $(abspath $(srctree)/$(src)) \ -d $(abspath $(BUILDDIR)/.doctrees/$3) \ -D version=$(KERNELVERSION) -D release=$(KERNELRELEASE) \ $(ALLSPHINXOPTS) \ $(abspath $(srctree)/$(src)/$5) \ $(abspath $(BUILDDIR)/$3/$4) htmldocs: @$(srctree)/scripts/sphinx-pre-install --version-check @+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,html,$(var),,$(var))) linkcheckdocs: @$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,linkcheck,$(var),,$(var))) latexdocs: @$(srctree)/scripts/sphinx-pre-install --version-check @+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,latex,$(var),latex,$(var))) ifeq ($(HAVE_PDFLATEX),0) pdfdocs: $(warning The '$(PDFLATEX)' command was not found. Make sure you have it installed and in PATH to produce PDF output.) @echo " SKIP Sphinx $@ target." else # HAVE_PDFLATEX pdfdocs: latexdocs @$(srctree)/scripts/sphinx-pre-install --version-check $(foreach var,$(SPHINXDIRS), $(MAKE) PDFLATEX="$(PDFLATEX)" LATEXOPTS="$(LATEXOPTS)" -C $(BUILDDIR)/$(var)/latex || exit;) endif # HAVE_PDFLATEX epubdocs: @$(srctree)/scripts/sphinx-pre-install --version-check @+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,epub,$(var),epub,$(var))) xmldocs: @$(srctree)/scripts/sphinx-pre-install --version-check @+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,xml,$(var),xml,$(var))) endif # HAVE_SPHINX # The following targets are independent of HAVE_SPHINX, and the rules should # work or silently pass without Sphinx. refcheckdocs: $(Q)cd $(srctree);scripts/documentation-file-ref-check cleandocs: $(Q)rm -rf $(BUILDDIR) $(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media clean dochelp: @echo ' Linux kernel internal documentation in different formats from ReST:' @echo ' htmldocs - HTML' @echo ' latexdocs - LaTeX' @echo ' pdfdocs - PDF' @echo ' epubdocs - EPUB' @echo ' xmldocs - XML' @echo ' linkcheckdocs - check for broken external links (will connect to external hosts)' @echo ' refcheckdocs - check for references to non-existing files under Documentation' @echo ' cleandocs - clean all generated files' @echo @echo ' make SPHINXDIRS="s1 s2" [target] Generate only docs of folder s1, s2' @echo ' valid values for SPHINXDIRS are: $(_SPHINXDIRS)' @echo @echo ' make SPHINX_CONF={conf-file} [target] use *additional* sphinx-build' @echo ' configuration. This is e.g. useful to build with nit-picking config.' @echo @echo ' Default location for the generated documents is Documentation/output' EDID/Makefile 0000644 00000001303 14722053057 0006713 0 ustar 00 SOURCES := $(wildcard [0-9]*x[0-9]*.S) BIN := $(patsubst %.S, %.bin, $(SOURCES)) IHEX := $(patsubst %.S, %.bin.ihex, $(SOURCES)) CODE := $(patsubst %.S, %.c, $(SOURCES)) all: $(BIN) $(IHEX) $(CODE) clean: @rm -f *.o *.bin.ihex *.bin *.c %.o: %.S @cc -c $^ %.bin.nocrc: %.o @objcopy -Obinary $^ $@ %.crc: %.bin.nocrc @list=$$(for i in `seq 1 127`; do head -c$$i $^ | tail -c1 \ | hexdump -v -e '/1 "%02X+"'; done); \ echo "ibase=16;100-($${list%?})%100" | bc >$@ %.p: %.crc %.S @cc -c -DCRC="$$(cat $*.crc)" -o $@ $*.S %.bin: %.p @objcopy -Obinary $^ $@ %.bin.ihex: %.p @objcopy -Oihex $^ $@ @dos2unix $@ 2>/dev/null %.c: %.bin @echo "{" >$@; hexdump -f hex $^ >>$@; echo "};" >>$@ kbuild/Kconfig.select-break 0000644 00000002057 14722053057 0011672 0 ustar 00 # Select broken dependency issue # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # Test with: # # make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.select-break menuconfig # # kconfig will not complain and enable this layout for configuration. This is # currently a feature of kconfig, given select was designed to be heavy handed. # Kconfig currently does not check the list of symbols listed on a symbol's # "select" list, this is done on purpose to help load a set of known required # symbols. Because of this use of select should be used with caution. An # example of this issue is below. # # The option B and C are clearly contradicting with respect to A. # However, when A is set, C can be set as well because Kconfig does not # visit the dependencies of the select target (in this case B). And since # Kconfig does not visit the dependencies, it breaks the dependencies of B # (!A). mainmenu "Simple example to demo kconfig select broken dependency issue" config A bool "CONFIG A" config B bool "CONFIG B" depends on !A config C bool "CONFIG C" depends on A select B kbuild/Kconfig.recursion-issue-01 0000644 00000004320 14722053057 0012701 0 ustar 00 # Simple Kconfig recursive issue # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # Test with: # # make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig # # This Kconfig file has a simple recursive dependency issue. In order to # understand why this recursive dependency issue occurs lets consider what # Kconfig needs to address. We iterate over what Kconfig needs to address # by stepping through the questions it needs to address sequentially. # # * What values are possible for CORE? # # CORE_BELL_A_ADVANCED selects CORE, which means that it influences the values # that are possible for CORE. So for example if CORE_BELL_A_ADVANCED is 'y', # CORE must be 'y' too. # # * What influences CORE_BELL_A_ADVANCED ? # # As the name implies CORE_BELL_A_ADVANCED is an advanced feature of # CORE_BELL_A so naturally it depends on CORE_BELL_A. So if CORE_BELL_A is 'y' # we know CORE_BELL_A_ADVANCED can be 'y' too. # # * What influences CORE_BELL_A ? # # CORE_BELL_A depends on CORE, so CORE influences CORE_BELL_A. # # But that is a problem, because this means that in order to determine # what values are possible for CORE we ended up needing to address questions # regarding possible values of CORE itself again. Answering the original # question of what are the possible values of CORE would make the kconfig # tools run in a loop. When this happens Kconfig exits and complains about # the "recursive dependency detected" error. # # Reading the Documentation/kbuild/Kconfig.recursion-issue-01 file it may be # obvious that an easy to solution to this problem should just be the removal # of the "select CORE" from CORE_BELL_A_ADVANCED as that is implicit already # since CORE_BELL_A depends on CORE. Recursive dependency issues are not always # so trivial to resolve, we provide another example below of practical # implications of this recursive issue where the solution is perhaps not so # easy to understand. Note that matching semantics on the dependency on # CORE also consist of a solution to this recursive problem. mainmenu "Simple example to demo kconfig recursive dependency issue" config CORE tristate config CORE_BELL_A tristate depends on CORE config CORE_BELL_A_ADVANCED tristate depends on CORE_BELL_A select CORE kbuild/Kconfig.recursion-issue-02 0000644 00000005453 14722053057 0012712 0 ustar 00 # Cumulative Kconfig recursive issue # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # Test with: # # make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig # # The recursive limitations with Kconfig has some non intuitive implications on # kconfig sematics which are documented here. One known practical implication # of the recursive limitation is that drivers cannot negate features from other # drivers if they share a common core requirement and use disjoint semantics to # annotate those requirements, ie, some drivers use "depends on" while others # use "select". For instance it means if a driver A and driver B share the same # core requirement, and one uses "select" while the other uses "depends on" to # annotate this, all features that driver A selects cannot now be negated by # driver B. # # A perhaps not so obvious implication of this is that, if semantics on these # core requirements are not carefully synced, as drivers evolve features # they select or depend on end up becoming shared requirements which cannot be # negated by other drivers. # # The example provided in Documentation/kbuild/Kconfig.recursion-issue-02 # describes a simple driver core layout of example features a kernel might # have. Let's assume we have some CORE functionality, then the kernel has a # series of bells and whistles it desires to implement, its not so advanced so # it only supports bells at this time: CORE_BELL_A and CORE_BELL_B. If # CORE_BELL_A has some advanced feature CORE_BELL_A_ADVANCED which selects # CORE_BELL_A then CORE_BELL_A ends up becoming a common BELL feature which # other bells in the system cannot negate. The reason for this issue is # due to the disjoint use of semantics on expressing each bell's relationship # with CORE, one uses "depends on" while the other uses "select". Another # more important reason is that kconfig does not check for dependencies listed # under 'select' for a symbol, when such symbols are selected kconfig them # as mandatory required symbols. For more details on the heavy handed nature # of select refer to Documentation/kbuild/Kconfig.select-break # # To fix this the "depends on CORE" must be changed to "select CORE", or the # "select CORE" must be changed to "depends on CORE". # # For an example real world scenario issue refer to the attempt to remove # "select FW_LOADER" [0], in the end the simple alternative solution to this # problem consisted on matching semantics with newly introduced features. # # [0] http://lkml.kernel.org/r/1432241149-8762-1-git-send-email-mcgrof@do-not-panic.com mainmenu "Simple example to demo cumulative kconfig recursive dependency implication" config CORE tristate config CORE_BELL_A tristate depends on CORE config CORE_BELL_A_ADVANCED tristate select CORE_BELL_A config CORE_BELL_B tristate depends on !CORE_BELL_A select CORE scsi/scsi_transport_srp/Makefile 0000644 00000000301 14722053057 0013105 0 ustar 00 all: rport_state_diagram.svg rport_state_diagram.png rport_state_diagram.svg: rport_state_diagram.dot dot -Tsvg -o $@ $< rport_state_diagram.png: rport_state_diagram.dot dot -Tpng -o $@ $<
| ver. 1.4 |
Github
|
.
| PHP 7.4.3-4ubuntu2.24 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка