Merge branch 'akpm' (patches from Andrew)

Merge second patchbomb from Andrew Morton:

 - most of the rest of MM

 - lots of misc things

 - procfs updates

 - printk feature work

 - updates to get_maintainer, MAINTAINERS, checkpatch

 - lib/ updates

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (96 commits)
  exit,stats: /* obey this comment */
  coredump: add __printf attribute to cn_*printf functions
  coredump: use from_kuid/kgid when formatting corename
  fs/reiserfs: remove unneeded cast
  NILFS2: support NFSv2 export
  fs/befs/btree.c: remove unneeded initializations
  fs/minix: remove unneeded cast
  init/do_mounts.c: add create_dev() failure log
  kasan: remove duplicate definition of the macro KASAN_FREE_PAGE
  fs/efs: femove unneeded cast
  checkpatch: emit "NOTE: <types>" message only once after multiple files
  checkpatch: emit an error when there's a diff in a changelog
  checkpatch: validate MODULE_LICENSE content
  checkpatch: add multi-line handling for PREFER_ETHER_ADDR_COPY
  checkpatch: suggest using eth_zero_addr() and eth_broadcast_addr()
  checkpatch: fix processing of MEMSET issues
  checkpatch: suggest using ether_addr_equal*()
  checkpatch: avoid NOT_UNIFIED_DIFF errors on cover-letter.patch files
  checkpatch: remove local from codespell path
  checkpatch: add --showfile to allow input via pipe to show filenames
  ...
This commit is contained in:
Linus Torvalds 2015-06-26 09:52:05 -07:00
commit 47a469421d
94 changed files with 2040 additions and 1345 deletions

View File

@ -84,6 +84,7 @@ Mayuresh Janorkar <mayur@ti.com>
Michael Buesch <m@bues.ch>
Michel Dänzer <michel@tungstengraphics.com>
Mitesh shah <mshah@teja.com>
Mohit Kumar <mohit.kumar@st.com> <mohit.kumar.dhaka@gmail.com>
Morten Welinder <terra@gnome.org>
Morten Welinder <welinder@anemone.rentec.com>
Morten Welinder <welinder@darter.rentec.com>
@ -95,10 +96,12 @@ Patrick Mochel <mochel@digitalimplant.org>
Peter A Jonsson <pj@ludd.ltu.se>
Peter Oruba <peter@oruba.de>
Peter Oruba <peter.oruba@amd.com>
Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com>
Praveen BP <praveenbp@ti.com>
Rajesh Shah <rajesh.shah@intel.com>
Ralf Baechle <ralf@linux-mips.org>
Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
Randy Dunlap <rdunlap@infradead.org> <rdunlap@xenotime.net>
Rémi Denis-Courmont <rdenis@simphalempin.com>
Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Rudolf Marek <R.Marek@sh.cvut.cz>

View File

@ -1,7 +1,7 @@
What: /config/pcie-gadget
Date: Feb 2011
KernelVersion: 2.6.37
Contact: Pratyush Anand <pratyush.anand@st.com>
Contact: Pratyush Anand <pratyush.anand@gmail.com>
Description:
Interface is used to configure selected dual mode PCIe controller

View File

@ -98,4 +98,13 @@ Description: The /dev/kmsg character device node provides userspace access
logic is used internally when messages are printed to the
console, /proc/kmsg or the syslog() syscall.
By default, kernel tries to avoid fragments by concatenating
when it can and fragments are rare; however, when extended
console support is enabled, the in-kernel concatenation is
disabled and /dev/kmsg output will contain more fragments. If
the log consumer performs concatenation, the end result
should be the same. In the future, the in-kernel concatenation
may be removed entirely and /dev/kmsg users are recommended to
implement fragment handling.
Users: dmesg(1), userspace kernel log consumers

View File

@ -4,14 +4,14 @@ driver is bound with root hub device.
What: /sys/bus/usb/devices/.../get_dev_desc
Date: March 2014
Contact: Pratyush Anand <pratyush.anand@st.com>
Contact: Pratyush Anand <pratyush.anand@gmail.com>
Description:
Write to this node to issue "Get Device Descriptor"
for Link Layer Validation device. It is needed for TD.7.06.
What: /sys/bus/usb/devices/.../u1_timeout
Date: March 2014
Contact: Pratyush Anand <pratyush.anand@st.com>
Contact: Pratyush Anand <pratyush.anand@gmail.com>
Description:
Set "U1 timeout" for the downstream port where Link Layer
Validation device is connected. Timeout value must be between 0
@ -19,7 +19,7 @@ Description:
What: /sys/bus/usb/devices/.../u2_timeout
Date: March 2014
Contact: Pratyush Anand <pratyush.anand@st.com>
Contact: Pratyush Anand <pratyush.anand@gmail.com>
Description:
Set "U2 timeout" for the downstream port where Link Layer
Validation device is connected. Timeout value must be between 0
@ -27,21 +27,21 @@ Description:
What: /sys/bus/usb/devices/.../hot_reset
Date: March 2014
Contact: Pratyush Anand <pratyush.anand@st.com>
Contact: Pratyush Anand <pratyush.anand@gmail.com>
Description:
Write to this node to issue "Reset" for Link Layer Validation
device. It is needed for TD.7.29, TD.7.31, TD.7.34 and TD.7.35.
What: /sys/bus/usb/devices/.../u3_entry
Date: March 2014
Contact: Pratyush Anand <pratyush.anand@st.com>
Contact: Pratyush Anand <pratyush.anand@gmail.com>
Description:
Write to this node to issue "U3 entry" for Link Layer
Validation device. It is needed for TD.7.35 and TD.7.36.
What: /sys/bus/usb/devices/.../u3_exit
Date: March 2014
Contact: Pratyush Anand <pratyush.anand@st.com>
Contact: Pratyush Anand <pratyush.anand@gmail.com>
Description:
Write to this node to issue "U3 exit" for Link Layer
Validation device. It is needed for TD.7.36.

View File

@ -0,0 +1,24 @@
What: /sys/class/zram-control/
Date: August 2015
KernelVersion: 4.2
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Description:
The zram-control/ class sub-directory belongs to zram
device class
What: /sys/class/zram-control/hot_add
Date: August 2015
KernelVersion: 4.2
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Description:
RO attribute. Read operation will cause zram to add a new
device and return its device id back to user (so one can
use /dev/zram<id>), or error code.
What: /sys/class/zram-control/hot_remove
Date: August 2015
KernelVersion: 4.2
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Description:
WO attribute. Remove a specific /dev/zramX device, where X
is a device_id provided by user.

View File

@ -19,7 +19,9 @@ Following shows a typical sequence of steps for using zram.
1) Load Module:
modprobe zram num_devices=4
This creates 4 devices: /dev/zram{0,1,2,3}
(num_devices parameter is optional. Default: 1)
num_devices parameter is optional and tells zram how many devices should be
pre-created. Default: 1.
2) Set max number of compression streams
Compression backend may use up to max_comp_streams compression streams,
@ -97,7 +99,24 @@ size of the disk when not in use so a huge zram is wasteful.
mkfs.ext4 /dev/zram1
mount /dev/zram1 /tmp
7) Stats:
7) Add/remove zram devices
zram provides a control interface, which enables dynamic (on-demand) device
addition and removal.
In order to add a new /dev/zramX device, perform read operation on hot_add
attribute. This will return either new device's device id (meaning that you
can use /dev/zram<id>) or error code.
Example:
cat /sys/class/zram-control/hot_add
1
To remove the existing /dev/zramX device (where X is a device id)
execute
echo X > /sys/class/zram-control/hot_remove
8) Stats:
Per-device statistics are exported as various nodes under /sys/block/zram<id>/
A brief description of exported device attritbutes. For more details please
@ -126,7 +145,7 @@ mem_used_max RW the maximum amount memory zram have consumed to
mem_limit RW the maximum amount of memory ZRAM can use to store
the compressed data
num_migrated RO the number of objects migrated migrated by compaction
compact WO trigger memory compaction
WARNING
=======
@ -172,11 +191,11 @@ line of text and contains the following stats separated by whitespace:
zero_pages
num_migrated
8) Deactivate:
9) Deactivate:
swapoff /dev/zram0
umount /dev/zram1
9) Reset:
10) Reset:
Write any positive value to 'reset' sysfs node
echo 1 > /sys/block/zram0/reset
echo 1 > /sys/block/zram1/reset

View File

@ -2,7 +2,7 @@ Spear PCIe Gadget Driver:
Author
=============
Pratyush Anand (pratyush.anand@st.com)
Pratyush Anand (pratyush.anand@gmail.com)
Location
============

View File

@ -2,6 +2,7 @@
started by Ingo Molnar <mingo@redhat.com>, 2001.09.17
2.6 port and netpoll api by Matt Mackall <mpm@selenic.com>, Sep 9 2003
IPv6 support by Cong Wang <xiyou.wangcong@gmail.com>, Jan 1 2013
Extended console support by Tejun Heo <tj@kernel.org>, May 1 2015
Please send bug reports to Matt Mackall <mpm@selenic.com>
Satyam Sharma <satyam.sharma@gmail.com>, and Cong Wang <xiyou.wangcong@gmail.com>
@ -24,9 +25,10 @@ Sender and receiver configuration:
It takes a string configuration parameter "netconsole" in the
following format:
netconsole=[src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]
netconsole=[+][src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]
where
+ if present, enable extended console support
src-port source for UDP packets (defaults to 6665)
src-ip source IP to use (interface address)
dev network interface (eth0)
@ -107,6 +109,7 @@ To remove a target:
The interface exposes these parameters of a netconsole target to userspace:
enabled Is this target currently enabled? (read-write)
extended Extended mode enabled (read-write)
dev_name Local network interface name (read-write)
local_port Source UDP port to use (read-write)
remote_port Remote agent's UDP port (read-write)
@ -132,6 +135,36 @@ You can also update the local interface dynamically. This is especially
useful if you want to use interfaces that have newly come up (and may not
have existed when netconsole was loaded / initialized).
Extended console:
=================
If '+' is prefixed to the configuration line or "extended" config file
is set to 1, extended console support is enabled. An example boot
param follows.
linux netconsole=+4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc
Log messages are transmitted with extended metadata header in the
following format which is the same as /dev/kmsg.
<level>,<sequnum>,<timestamp>,<contflag>;<message text>
Non printable characters in <message text> are escaped using "\xff"
notation. If the message contains optional dictionary, verbatim
newline is used as the delimeter.
If a message doesn't fit in certain number of bytes (currently 1000),
the message is split into multiple fragments by netconsole. These
fragments are transmitted with "ncfrag" header field added.
ncfrag=<byte-offset>/<total-bytes>
For example, assuming a lot smaller chunk size, a message "the first
chunk, the 2nd chunk." may be split as follows.
6,416,1758426,-,ncfrag=0/31;the first chunk,
6,416,1758426,-,ncfrag=16/31; the 2nd chunk.
Miscellaneous notes:
====================

View File

@ -197,8 +197,8 @@ core_pattern is used to specify a core dumpfile pattern name.
%P global pid (init PID namespace)
%i tid
%I global tid (init PID namespace)
%u uid
%g gid
%u uid (in initial user namespace)
%g gid (in initial user namespace)
%d dump mode, matches PR_SET_DUMPABLE and
/proc/sys/fs/suid_dumpable
%s signal number

View File

@ -26,8 +26,22 @@ Zswap evicts pages from compressed cache on an LRU basis to the backing swap
device when the compressed pool reaches its size limit. This requirement had
been identified in prior community discussions.
To enabled zswap, the "enabled" attribute must be set to 1 at boot time. e.g.
zswap.enabled=1
Zswap is disabled by default but can be enabled at boot time by setting
the "enabled" attribute to 1 at boot time. ie: zswap.enabled=1. Zswap
can also be enabled and disabled at runtime using the sysfs interface.
An example command to enable zswap at runtime, assuming sysfs is mounted
at /sys, is:
echo 1 > /sys/modules/zswap/parameters/enabled
When zswap is disabled at runtime it will stop storing pages that are
being swapped out. However, it will _not_ immediately write out or fault
back into memory all of the pages stored in the compressed pool. The
pages stored in zswap will remain in the compressed pool until they are
either invalidated or faulted back into memory. In order to force all
pages out of the compressed pool, a swapoff on the swap device(s) will
fault back into memory all swapped out pages, including those in the
compressed pool.
Design:

View File

@ -259,7 +259,7 @@ S: Maintained
F: drivers/platform/x86/acer-wmi.c
ACPI
M: Rafael J. Wysocki <rjw@rjwysocki.net>
M: "Rafael J. Wysocki" <rjw@rjwysocki.net>
M: Len Brown <lenb@kernel.org>
L: linux-acpi@vger.kernel.org
W: https://01.org/linux-acpi
@ -280,7 +280,7 @@ F: tools/power/acpi/
ACPI COMPONENT ARCHITECTURE (ACPICA)
M: Robert Moore <robert.moore@intel.com>
M: Lv Zheng <lv.zheng@intel.com>
M: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
M: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
L: linux-acpi@vger.kernel.org
L: devel@acpica.org
W: https://acpica.org/
@ -2515,7 +2515,7 @@ F: arch/powerpc/oprofile/*cell*
F: arch/powerpc/platforms/cell/
CEPH DISTRIBUTED FILE SYSTEM CLIENT
M: Yan, Zheng <zyan@redhat.com>
M: "Yan, Zheng" <zyan@redhat.com>
M: Sage Weil <sage@redhat.com>
L: ceph-devel@vger.kernel.org
W: http://ceph.com/
@ -2829,7 +2829,7 @@ S: Maintained
F: drivers/net/ethernet/ti/cpmac.c
CPU FREQUENCY DRIVERS
M: Rafael J. Wysocki <rjw@rjwysocki.net>
M: "Rafael J. Wysocki" <rjw@rjwysocki.net>
M: Viresh Kumar <viresh.kumar@linaro.org>
L: linux-pm@vger.kernel.org
S: Maintained
@ -2868,7 +2868,7 @@ F: drivers/cpuidle/cpuidle-exynos.c
F: arch/arm/mach-exynos/pm.c
CPUIDLE DRIVERS
M: Rafael J. Wysocki <rjw@rjwysocki.net>
M: "Rafael J. Wysocki" <rjw@rjwysocki.net>
M: Daniel Lezcano <daniel.lezcano@linaro.org>
L: linux-pm@vger.kernel.org
S: Maintained
@ -4103,7 +4103,7 @@ F: include/uapi/scsi/fc/
FILE LOCKING (flock() and fcntl()/lockf())
M: Jeff Layton <jlayton@poochiereds.net>
M: J. Bruce Fields <bfields@fieldses.org>
M: "J. Bruce Fields" <bfields@fieldses.org>
L: linux-fsdevel@vger.kernel.org
S: Maintained
F: include/linux/fcntl.h
@ -4299,7 +4299,7 @@ F: sound/soc/fsl/imx*
F: sound/soc/fsl/mpc8610_hpcd.c
FREESCALE QORIQ MANAGEMENT COMPLEX DRIVER
M: J. German Rivera <German.Rivera@freescale.com>
M: "J. German Rivera" <German.Rivera@freescale.com>
L: linux-kernel@vger.kernel.org
S: Maintained
F: drivers/staging/fsl-mc/
@ -4581,7 +4581,7 @@ S: Maintained
F: drivers/media/usb/gspca/
GUID PARTITION TABLE (GPT)
M: Davidlohr Bueso <davidlohr@hp.com>
M: Davidlohr Bueso <dave@stgolabs.net>
L: linux-efi@vger.kernel.org
S: Maintained
F: block/partitions/efi.*
@ -4871,7 +4871,7 @@ S: Maintained
F: fs/hugetlbfs/
Hyper-V CORE AND DRIVERS
M: K. Y. Srinivasan <kys@microsoft.com>
M: "K. Y. Srinivasan" <kys@microsoft.com>
M: Haiyang Zhang <haiyangz@microsoft.com>
L: devel@linuxdriverproject.org
S: Maintained
@ -5233,7 +5233,7 @@ K: \b(ABS|SYN)_MT_
INTEL ASoC BDW/HSW DRIVERS
M: Jie Yang <yang.jie@linux.intel.com>
L: alsa-devel@alsa-project.org
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported
F: sound/soc/intel/sst-haswell*
F: sound/soc/intel/sst-dsp*
@ -6825,7 +6825,7 @@ F: drivers/net/ethernet/natsemi/natsemi.c
NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER
M: Daniel Mack <zonque@gmail.com>
S: Maintained
L: alsa-devel@alsa-project.org
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
W: http://www.native-instruments.com
F: sound/usb/caiaq/
@ -7243,7 +7243,7 @@ F: arch/arm/mach-omap2/prm*
OMAP AUDIO SUPPORT
M: Peter Ujfalusi <peter.ujfalusi@ti.com>
M: Jarkko Nikula <jarkko.nikula@bitmer.com>
L: alsa-devel@alsa-project.org (subscribers-only)
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L: linux-omap@vger.kernel.org
S: Maintained
F: sound/soc/omap/
@ -7945,7 +7945,7 @@ F: include/linux/power_supply.h
F: drivers/power/
PNP SUPPORT
M: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
M: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
S: Maintained
F: drivers/pnp/
@ -8951,7 +8951,7 @@ F: drivers/mmc/host/sdhci-spear.c
SECURITY SUBSYSTEM
M: James Morris <james.l.morris@oracle.com>
M: Serge E. Hallyn <serge@hallyn.com>
M: "Serge E. Hallyn" <serge@hallyn.com>
L: linux-security-module@vger.kernel.org (suggested Cc:)
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git
W: http://kernsec.org/
@ -9171,7 +9171,7 @@ F: arch/arm/mach-davinci/
F: drivers/i2c/busses/i2c-davinci.c
TI DAVINCI SERIES MEDIA DRIVER
M: Lad, Prabhakar <prabhakar.csengg@gmail.com>
M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
@ -9181,7 +9181,7 @@ F: drivers/media/platform/davinci/
F: include/media/davinci/
TI AM437X VPFE DRIVER
M: Lad, Prabhakar <prabhakar.csengg@gmail.com>
M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
@ -9190,7 +9190,7 @@ S: Maintained
F: drivers/media/platform/am437x/
OV2659 OMNIVISION SENSOR DRIVER
M: Lad, Prabhakar <prabhakar.csengg@gmail.com>
M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
@ -9755,7 +9755,7 @@ F: fs/sysv/
F: include/linux/sysv_fs.h
TARGET SUBSYSTEM
M: Nicholas A. Bellinger <nab@linux-iscsi.org>
M: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
L: linux-scsi@vger.kernel.org
L: target-devel@vger.kernel.org
W: http://www.linux-iscsi.org
@ -9897,7 +9897,7 @@ F: include/linux/if_team.h
F: include/uapi/linux/if_team.h
TECHNOLOGIC SYSTEMS TS-5500 PLATFORM SUPPORT
M: Savoir-faire Linux Inc. <kernel@savoirfairelinux.com>
M: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
S: Maintained
F: arch/x86/platform/ts5500/

View File

@ -499,6 +499,13 @@ config ARCH_HAS_ELF_RANDOMIZE
- arch_mmap_rnd()
- arch_randomize_brk()
config HAVE_COPY_THREAD_TLS
bool
help
Architecture provides copy_thread_tls to accept tls argument via
normal C parameter passing, rather than extracting the syscall
argument from pt_regs.
#
# ABI hall of shame
#

View File

@ -63,15 +63,6 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
return pte_wrprotect(pte);
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
static inline void arch_clear_hugepage_flags(struct page *page)
{
clear_bit(PG_dcache_clean, &page->flags);

View File

@ -96,15 +96,6 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
return pte_wrprotect(pte);
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
static inline void arch_clear_hugepage_flags(struct page *page)
{
clear_bit(PG_dcache_clean, &page->flags);

View File

@ -209,17 +209,18 @@ dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
* the same here.
*/
static inline int
dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
enum dma_data_direction direction)
{
int i;
struct scatterlist *sg;
for (i = 0; i < nents; i++) {
for_each_sg(sglist, sg, nents, i) {
char *virt;
sg[i].dma_address = page_to_bus(sg_page(&sg[i])) + sg[i].offset;
virt = sg_virt(&sg[i]);
dma_cache_sync(dev, virt, sg[i].length, direction);
sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset;
virt = sg_virt(sg);
dma_cache_sync(dev, virt, sg->length, direction);
}
return nents;
@ -321,14 +322,14 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
}
static inline void
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
int nents, enum dma_data_direction direction)
{
int i;
struct scatterlist *sg;
for (i = 0; i < nents; i++) {
dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, direction);
}
for_each_sg(sglist, sg, nents, i)
dma_cache_sync(dev, sg_virt(sg), sg->length, direction);
}
/* Now for the API extensions over the pci_ one */

View File

@ -35,12 +35,6 @@ extern unsigned long __nongprelbss memory_start;
extern unsigned long __nongprelbss memory_end;
extern unsigned long __nongprelbss rom_length;
/* determine if we're running from ROM */
static inline int is_in_rom(unsigned long addr)
{
return 0; /* default case: not in ROM */
}
#endif
#endif
#endif /* _ASM_SECTIONS_H */

View File

@ -119,14 +119,16 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
EXPORT_SYMBOL(dma_map_single);
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
enum dma_data_direction direction)
{
int i;
struct scatterlist *sg;
for (i=0; i<nents; i++)
frv_cache_wback_inv(sg_dma_address(&sg[i]),
sg_dma_address(&sg[i]) + sg_dma_len(&sg[i]));
for_each_sg(sglist, sg, nents, i) {
frv_cache_wback_inv(sg_dma_address(sg),
sg_dma_address(sg) + sg_dma_len(sg));
}
BUG_ON(direction == DMA_NONE);

View File

@ -50,19 +50,20 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
EXPORT_SYMBOL(dma_map_single);
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
enum dma_data_direction direction)
{
unsigned long dampr2;
void *vaddr;
int i;
struct scatterlist *sg;
BUG_ON(direction == DMA_NONE);
dampr2 = __get_DAMPR(2);
for (i = 0; i < nents; i++) {
vaddr = kmap_atomic_primary(sg_page(&sg[i]));
for_each_sg(sglist, sg, nents, i) {
vaddr = kmap_atomic_primary(sg_page(sg));
frv_dcache_writeback((unsigned long) vaddr,
(unsigned long) vaddr + PAGE_SIZE);

View File

@ -65,15 +65,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
return *ptep;
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
static inline void arch_clear_hugepage_flags(struct page *page)
{
}

View File

@ -67,15 +67,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
return *ptep;
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
static inline void arch_clear_hugepage_flags(struct page *page)
{
}

View File

@ -110,15 +110,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
return *ptep;
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
static inline void arch_clear_hugepage_flags(struct page *page)
{
}

View File

@ -168,15 +168,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
return *ptep;
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
static inline void arch_clear_hugepage_flags(struct page *page)
{
}

View File

@ -37,9 +37,6 @@ static inline int prepare_hugepage_range(struct file *file,
#define arch_clear_hugepage_flags(page) do { } while (0)
int arch_prepare_hugepage(struct page *page);
void arch_release_hugepage(struct page *page);
static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{

View File

@ -17,7 +17,10 @@
#define PAGE_DEFAULT_ACC 0
#define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4)
#define HPAGE_SHIFT 20
#include <asm/setup.h>
#ifndef __ASSEMBLY__
extern int HPAGE_SHIFT;
#define HPAGE_SIZE (1UL << HPAGE_SHIFT)
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
@ -27,9 +30,6 @@
#define ARCH_HAS_PREPARE_HUGEPAGE
#define ARCH_HAS_HUGEPAGE_CLEAR_FLUSH
#include <asm/setup.h>
#ifndef __ASSEMBLY__
static inline void storage_key_init_range(unsigned long start, unsigned long end)
{
#if PAGE_DEFAULT_KEY

View File

@ -202,7 +202,7 @@ COMPAT_SYSCALL_WRAP1(epoll_create1, int, flags);
COMPAT_SYSCALL_WRAP2(tkill, int, pid, int, sig);
COMPAT_SYSCALL_WRAP3(tgkill, int, tgid, int, pid, int, sig);
COMPAT_SYSCALL_WRAP5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, unsigned long, flags);
COMPAT_SYSCALL_WRAP5(clone, unsigned long, newsp, unsigned long, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, int, tls_val);
COMPAT_SYSCALL_WRAP5(clone, unsigned long, newsp, unsigned long, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, unsigned long, tls);
COMPAT_SYSCALL_WRAP2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags);
COMPAT_SYSCALL_WRAP4(prlimit64, pid_t, pid, unsigned int, resource, const struct rlimit64 __user *, new_rlim, struct rlimit64 __user *, old_rlim);
COMPAT_SYSCALL_WRAP5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag);

View File

@ -880,6 +880,8 @@ void __init setup_arch(char **cmdline_p)
*/
setup_hwcaps();
HPAGE_SHIFT = MACHINE_HAS_HPAGE ? 20 : 0;
/*
* Create kernel page tables and switch to virtual addressing.
*/

View File

@ -86,31 +86,16 @@ static inline pte_t __pmd_to_pte(pmd_t pmd)
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte)
{
pmd_t pmd;
pmd_t pmd = __pte_to_pmd(pte);
pmd = __pte_to_pmd(pte);
if (!MACHINE_HAS_HPAGE) {
/* Emulated huge ptes loose the dirty and young bit */
pmd_val(pmd) &= ~_SEGMENT_ENTRY_ORIGIN;
pmd_val(pmd) |= pte_page(pte)[1].index;
} else
pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE;
pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE;
*(pmd_t *) ptep = pmd;
}
pte_t huge_ptep_get(pte_t *ptep)
{
unsigned long origin;
pmd_t pmd;
pmd_t pmd = *(pmd_t *) ptep;
pmd = *(pmd_t *) ptep;
if (!MACHINE_HAS_HPAGE && pmd_present(pmd)) {
origin = pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN;
pmd_val(pmd) &= ~_SEGMENT_ENTRY_ORIGIN;
pmd_val(pmd) |= *(unsigned long *) origin;
/* Emulated huge ptes are young and dirty by definition */
pmd_val(pmd) |= _SEGMENT_ENTRY_YOUNG | _SEGMENT_ENTRY_DIRTY;
}
return __pmd_to_pte(pmd);
}
@ -125,45 +110,6 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
return pte;
}
int arch_prepare_hugepage(struct page *page)
{
unsigned long addr = page_to_phys(page);
pte_t pte;
pte_t *ptep;
int i;
if (MACHINE_HAS_HPAGE)
return 0;
ptep = (pte_t *) pte_alloc_one(&init_mm, addr);
if (!ptep)
return -ENOMEM;
pte_val(pte) = addr;
for (i = 0; i < PTRS_PER_PTE; i++) {
set_pte_at(&init_mm, addr + i * PAGE_SIZE, ptep + i, pte);
pte_val(pte) += PAGE_SIZE;
}
page[1].index = (unsigned long) ptep;
return 0;
}
void arch_release_hugepage(struct page *page)
{
pte_t *ptep;
if (MACHINE_HAS_HPAGE)
return;
ptep = (pte_t *) page[1].index;
if (!ptep)
return;
clear_table((unsigned long *) ptep, _PAGE_INVALID,
PTRS_PER_PTE * sizeof(pte_t));
page_table_free(&init_mm, (unsigned long *) ptep);
page[1].index = 0;
}
pte_t *huge_pte_alloc(struct mm_struct *mm,
unsigned long addr, unsigned long sz)
{
@ -195,10 +141,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
int pmd_huge(pmd_t pmd)
{
if (!MACHINE_HAS_HPAGE)
return 0;
return !!(pmd_val(pmd) & _SEGMENT_ENTRY_LARGE);
return pmd_large(pmd);
}
int pud_huge(pud_t pud)

View File

@ -31,6 +31,8 @@
#define ALLOC_ORDER 2
#define FRAG_MASK 0x03
int HPAGE_SHIFT;
unsigned long *crst_table_alloc(struct mm_struct *mm)
{
struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER);

View File

@ -79,15 +79,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
return *ptep;
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
static inline void arch_clear_hugepage_flags(struct page *page)
{
clear_bit(PG_dcache_clean, &page->flags);

View File

@ -78,15 +78,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
return *ptep;
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
static inline void arch_clear_hugepage_flags(struct page *page)
{
}

View File

@ -94,15 +94,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
return *ptep;
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
static inline void arch_clear_hugepage_flags(struct page *page)
{
}

View File

@ -80,15 +80,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
return *ptep;
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
static inline void arch_clear_hugepage_flags(struct page *page)
{
}

View File

@ -1303,12 +1303,11 @@ const char *device_get_devnode(struct device *dev,
return dev_name(dev);
/* replace '!' in the name with '/' */
*tmp = kstrdup(dev_name(dev), GFP_KERNEL);
if (!*tmp)
s = kstrdup(dev_name(dev), GFP_KERNEL);
if (!s)
return NULL;
while ((s = strchr(*tmp, '!')))
s[0] = '/';
return *tmp;
strreplace(s, '!', '/');
return *tmp = s;
}
/**

View File

@ -23,12 +23,4 @@ config ZRAM_LZ4_COMPRESS
default n
help
This option enables LZ4 compression algorithm support. Compression
algorithm can be changed using `comp_algorithm' device attribute.
config ZRAM_DEBUG
bool "Compressed RAM block device debug support"
depends on ZRAM
default n
help
This option adds additional debugging code to the compressed
RAM block device driver.
algorithm can be changed using `comp_algorithm' device attribute.

View File

@ -274,7 +274,7 @@ ssize_t zcomp_available_show(const char *comp, char *buf)
int i = 0;
while (backends[i]) {
if (sysfs_streq(comp, backends[i]->name))
if (!strcmp(comp, backends[i]->name))
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
"[%s] ", backends[i]->name);
else
@ -286,6 +286,11 @@ ssize_t zcomp_available_show(const char *comp, char *buf)
return sz;
}
bool zcomp_available_algorithm(const char *comp)
{
return find_backend(comp) != NULL;
}
bool zcomp_set_max_streams(struct zcomp *comp, int num_strm)
{
return comp->set_max_streams(comp, num_strm);

View File

@ -51,6 +51,7 @@ struct zcomp {
};
ssize_t zcomp_available_show(const char *comp, char *buf);
bool zcomp_available_algorithm(const char *comp);
struct zcomp *zcomp_create(const char *comp, int max_strm);
void zcomp_destroy(struct zcomp *comp);

File diff suppressed because it is too large Load Diff

View File

@ -20,12 +20,6 @@
#include "zcomp.h"
/*
* Some arbitrary value. This is just to catch
* invalid value for num_devices module parameter.
*/
static const unsigned max_num_devices = 32;
/*-- Configurable parameters */
/*
@ -121,5 +115,9 @@ struct zram {
*/
u64 disksize; /* bytes */
char compressor[10];
/*
* zram is claimed so open request will be failed
*/
bool claim; /* Protected by bdev->bd_mutex */
};
#endif

View File

@ -144,7 +144,9 @@ static struct kobj_type __refdata memmap_ktype = {
*
* Common implementation of firmware_map_add() and firmware_map_add_early()
* which expects a pre-allocated struct firmware_map_entry.
**/
*
* Return: 0 always
*/
static int firmware_map_add_entry(u64 start, u64 end,
const char *type,
struct firmware_map_entry *entry)
@ -170,7 +172,7 @@ static int firmware_map_add_entry(u64 start, u64 end,
* @entry: removed entry.
*
* The caller must hold map_entries_lock, and release it properly.
**/
*/
static inline void firmware_map_remove_entry(struct firmware_map_entry *entry)
{
list_del(&entry->list);
@ -208,7 +210,7 @@ static inline void remove_sysfs_fw_map_entry(struct firmware_map_entry *entry)
kobject_put(&entry->kobj);
}
/*
/**
* firmware_map_find_entry_in_list() - Search memmap entry in a given list.
* @start: Start of the memory range.
* @end: End of the memory range (exclusive).
@ -236,7 +238,7 @@ firmware_map_find_entry_in_list(u64 start, u64 end, const char *type,
return NULL;
}
/*
/**
* firmware_map_find_entry() - Search memmap entry in map_entries.
* @start: Start of the memory range.
* @end: End of the memory range (exclusive).
@ -254,7 +256,7 @@ firmware_map_find_entry(u64 start, u64 end, const char *type)
return firmware_map_find_entry_in_list(start, end, type, &map_entries);
}
/*
/**
* firmware_map_find_entry_bootmem() - Search memmap entry in map_entries_bootmem.
* @start: Start of the memory range.
* @end: End of the memory range (exclusive).
@ -283,8 +285,8 @@ firmware_map_find_entry_bootmem(u64 start, u64 end, const char *type)
* similar to function firmware_map_add_early(). The only difference is that
* it will create the syfs entry dynamically.
*
* Returns 0 on success, or -ENOMEM if no memory could be allocated.
**/
* Return: 0 on success, or -ENOMEM if no memory could be allocated.
*/
int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type)
{
struct firmware_map_entry *entry;
@ -325,8 +327,8 @@ int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type)
*
* That function must be called before late_initcall.
*
* Returns 0 on success, or -ENOMEM if no memory could be allocated.
**/
* Return: 0 on success, or -ENOMEM if no memory could be allocated.
*/
int __init firmware_map_add_early(u64 start, u64 end, const char *type)
{
struct firmware_map_entry *entry;
@ -346,8 +348,8 @@ int __init firmware_map_add_early(u64 start, u64 end, const char *type)
*
* removes a firmware mapping entry.
*
* Returns 0 on success, or -EINVAL if no entry.
**/
* Return: 0 on success, or -EINVAL if no entry.
*/
int __meminit firmware_map_remove(u64 start, u64 end, const char *type)
{
struct firmware_map_entry *entry;

View File

@ -2024,7 +2024,6 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev)
{
char b[BDEVNAME_SIZE];
struct kobject *ko;
char *s;
int err;
/* prevent duplicates */
@ -2070,8 +2069,7 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev)
return -EBUSY;
}
bdevname(rdev->bdev,b);
while ( (s=strchr(b, '/')) != NULL)
*s = '!';
strreplace(b, '/', '!');
rdev->mddev = mddev;
printk(KERN_INFO "md: bind<%s>\n", b);

View File

@ -2451,7 +2451,7 @@ int altera_init(struct altera_config *config, const struct firmware *fw)
astate->config = config;
if (!astate->config->jtag_io) {
dprintk(KERN_INFO "%s: using byteblaster!\n", __func__);
dprintk("%s: using byteblaster!\n", __func__);
astate->config->jtag_io = netup_jtag_io_lpt;
}

View File

@ -220,7 +220,7 @@ static unsigned long lookup_addr(char *arg)
else if (!strcmp(arg, "sys_open"))
addr = (unsigned long)do_sys_open;
else if (!strcmp(arg, "do_fork"))
addr = (unsigned long)do_fork;
addr = (unsigned long)_do_fork;
else if (!strcmp(arg, "hw_break_val"))
addr = (unsigned long)&hw_break_val;
addr = (unsigned long) dereference_function_descriptor((void *)addr);

View File

@ -2,7 +2,7 @@
* drivers/misc/spear13xx_pcie_gadget.c
*
* Copyright (C) 2010 ST Microelectronics
* Pratyush Anand<pratyush.anand@st.com>
* Pratyush Anand<pratyush.anand@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any

View File

@ -79,6 +79,12 @@ static LIST_HEAD(target_list);
/* This needs to be a spinlock because write_msg() cannot sleep */
static DEFINE_SPINLOCK(target_list_lock);
/*
* Console driver for extended netconsoles. Registered on the first use to
* avoid unnecessarily enabling ext message formatting.
*/
static struct console netconsole_ext;
/**
* struct netconsole_target - Represents a configured netconsole target.
* @list: Links this target into the target_list.
@ -104,14 +110,15 @@ struct netconsole_target {
#ifdef CONFIG_NETCONSOLE_DYNAMIC
struct config_item item;
#endif
int enabled;
struct mutex mutex;
bool enabled;
bool extended;
struct netpoll np;
};
#ifdef CONFIG_NETCONSOLE_DYNAMIC
static struct configfs_subsystem netconsole_subsys;
static DEFINE_MUTEX(dynamic_netconsole_mutex);
static int __init dynamic_netconsole_init(void)
{
@ -185,9 +192,13 @@ static struct netconsole_target *alloc_param_target(char *target_config)
strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ);
nt->np.local_port = 6665;
nt->np.remote_port = 6666;
mutex_init(&nt->mutex);
eth_broadcast_addr(nt->np.remote_mac);
if (*target_config == '+') {
nt->extended = true;
target_config++;
}
/* Parse parameters and setup netpoll */
err = netpoll_parse_options(&nt->np, target_config);
if (err)
@ -197,7 +208,7 @@ static struct netconsole_target *alloc_param_target(char *target_config)
if (err)
goto fail;
nt->enabled = 1;
nt->enabled = true;
return nt;
@ -258,6 +269,11 @@ static ssize_t show_enabled(struct netconsole_target *nt, char *buf)
return snprintf(buf, PAGE_SIZE, "%d\n", nt->enabled);
}
static ssize_t show_extended(struct netconsole_target *nt, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", nt->extended);
}
static ssize_t show_dev_name(struct netconsole_target *nt, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n", nt->np.dev_name);
@ -322,13 +338,18 @@ static ssize_t store_enabled(struct netconsole_target *nt,
return err;
if (enabled < 0 || enabled > 1)
return -EINVAL;
if (enabled == nt->enabled) {
if ((bool)enabled == nt->enabled) {
pr_info("network logging has already %s\n",
nt->enabled ? "started" : "stopped");
return -EINVAL;
}
if (enabled) { /* 1 */
if (enabled) { /* true */
if (nt->extended && !(netconsole_ext.flags & CON_ENABLED)) {
netconsole_ext.flags |= CON_ENABLED;
register_console(&netconsole_ext);
}
/*
* Skip netpoll_parse_options() -- all the attributes are
* already configured via configfs. Just print them out.
@ -340,13 +361,13 @@ static ssize_t store_enabled(struct netconsole_target *nt,
return err;
pr_info("netconsole: network logging started\n");
} else { /* 0 */
} else { /* false */
/* We need to disable the netconsole before cleaning it up
* otherwise we might end up in write_msg() with
* nt->np.dev == NULL and nt->enabled == 1
* nt->np.dev == NULL and nt->enabled == true
*/
spin_lock_irqsave(&target_list_lock, flags);
nt->enabled = 0;
nt->enabled = false;
spin_unlock_irqrestore(&target_list_lock, flags);
netpoll_cleanup(&nt->np);
}
@ -356,6 +377,30 @@ static ssize_t store_enabled(struct netconsole_target *nt,
return strnlen(buf, count);
}
static ssize_t store_extended(struct netconsole_target *nt,
const char *buf,
size_t count)
{
int extended;
int err;
if (nt->enabled) {
pr_err("target (%s) is enabled, disable to update parameters\n",
config_item_name(&nt->item));
return -EINVAL;
}
err = kstrtoint(buf, 10, &extended);
if (err < 0)
return err;
if (extended < 0 || extended > 1)
return -EINVAL;
nt->extended = extended;
return strnlen(buf, count);
}
static ssize_t store_dev_name(struct netconsole_target *nt,
const char *buf,
size_t count)
@ -508,6 +553,7 @@ static struct netconsole_target_attr netconsole_target_##_name = \
__CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, show_##_name, store_##_name)
NETCONSOLE_TARGET_ATTR_RW(enabled);
NETCONSOLE_TARGET_ATTR_RW(extended);
NETCONSOLE_TARGET_ATTR_RW(dev_name);
NETCONSOLE_TARGET_ATTR_RW(local_port);
NETCONSOLE_TARGET_ATTR_RW(remote_port);
@ -518,6 +564,7 @@ NETCONSOLE_TARGET_ATTR_RW(remote_mac);
static struct configfs_attribute *netconsole_target_attrs[] = {
&netconsole_target_enabled.attr,
&netconsole_target_extended.attr,
&netconsole_target_dev_name.attr,
&netconsole_target_local_port.attr,
&netconsole_target_remote_port.attr,
@ -562,10 +609,10 @@ static ssize_t netconsole_target_attr_store(struct config_item *item,
struct netconsole_target_attr *na =
container_of(attr, struct netconsole_target_attr, attr);
mutex_lock(&nt->mutex);
mutex_lock(&dynamic_netconsole_mutex);
if (na->store)
ret = na->store(nt, buf, count);
mutex_unlock(&nt->mutex);
mutex_unlock(&dynamic_netconsole_mutex);
return ret;
}
@ -594,7 +641,7 @@ static struct config_item *make_netconsole_target(struct config_group *group,
/*
* Allocate and initialize with defaults.
* Target is disabled at creation (enabled == 0).
* Target is disabled at creation (!enabled).
*/
nt = kzalloc(sizeof(*nt), GFP_KERNEL);
if (!nt)
@ -604,7 +651,6 @@ static struct config_item *make_netconsole_target(struct config_group *group,
strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ);
nt->np.local_port = 6665;
nt->np.remote_port = 6666;
mutex_init(&nt->mutex);
eth_broadcast_addr(nt->np.remote_mac);
/* Initialize the config_item member */
@ -695,7 +741,7 @@ static int netconsole_netdev_event(struct notifier_block *this,
spin_lock_irqsave(&target_list_lock, flags);
dev_put(nt->np.dev);
nt->np.dev = NULL;
nt->enabled = 0;
nt->enabled = false;
stopped = true;
netconsole_target_put(nt);
goto restart;
@ -729,6 +775,82 @@ static struct notifier_block netconsole_netdev_notifier = {
.notifier_call = netconsole_netdev_event,
};
/**
* send_ext_msg_udp - send extended log message to target
* @nt: target to send message to
* @msg: extended log message to send
* @msg_len: length of message
*
* Transfer extended log @msg to @nt. If @msg is longer than
* MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with
* ncfrag header field added to identify them.
*/
static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
int msg_len)
{
static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
const char *header, *body;
int offset = 0;
int header_len, body_len;
if (msg_len <= MAX_PRINT_CHUNK) {
netpoll_send_udp(&nt->np, msg, msg_len);
return;
}
/* need to insert extra header fields, detect header and body */
header = msg;
body = memchr(msg, ';', msg_len);
if (WARN_ON_ONCE(!body))
return;
header_len = body - header;
body_len = msg_len - header_len - 1;
body++;
/*
* Transfer multiple chunks with the following extra header.
* "ncfrag=<byte-offset>/<total-bytes>"
*/
memcpy(buf, header, header_len);
while (offset < body_len) {
int this_header = header_len;
int this_chunk;
this_header += scnprintf(buf + this_header,
sizeof(buf) - this_header,
",ncfrag=%d/%d;", offset, body_len);
this_chunk = min(body_len - offset,
MAX_PRINT_CHUNK - this_header);
if (WARN_ON_ONCE(this_chunk <= 0))
return;
memcpy(buf + this_header, body + offset, this_chunk);
netpoll_send_udp(&nt->np, buf, this_header + this_chunk);
offset += this_chunk;
}
}
static void write_ext_msg(struct console *con, const char *msg,
unsigned int len)
{
struct netconsole_target *nt;
unsigned long flags;
if ((oops_only && !oops_in_progress) || list_empty(&target_list))
return;
spin_lock_irqsave(&target_list_lock, flags);
list_for_each_entry(nt, &target_list, list)
if (nt->extended && nt->enabled && netif_running(nt->np.dev))
send_ext_msg_udp(nt, msg, len);
spin_unlock_irqrestore(&target_list_lock, flags);
}
static void write_msg(struct console *con, const char *msg, unsigned int len)
{
int frag, left;
@ -744,8 +866,7 @@ static void write_msg(struct console *con, const char *msg, unsigned int len)
spin_lock_irqsave(&target_list_lock, flags);
list_for_each_entry(nt, &target_list, list) {
netconsole_target_get(nt);
if (nt->enabled && netif_running(nt->np.dev)) {
if (!nt->extended && nt->enabled && netif_running(nt->np.dev)) {
/*
* We nest this inside the for-each-target loop above
* so that we're able to get as much logging out to
@ -760,11 +881,16 @@ static void write_msg(struct console *con, const char *msg, unsigned int len)
left -= frag;
}
}
netconsole_target_put(nt);
}
spin_unlock_irqrestore(&target_list_lock, flags);
}
static struct console netconsole_ext = {
.name = "netcon_ext",
.flags = CON_EXTENDED, /* starts disabled, registered on first use */
.write = write_ext_msg,
};
static struct console netconsole = {
.name = "netcon",
.flags = CON_ENABLED,
@ -787,7 +913,11 @@ static int __init init_netconsole(void)
goto fail;
}
/* Dump existing printks when we register */
netconsole.flags |= CON_PRINTBUFFER;
if (nt->extended)
netconsole_ext.flags |= CON_PRINTBUFFER |
CON_ENABLED;
else
netconsole.flags |= CON_PRINTBUFFER;
spin_lock_irqsave(&target_list_lock, flags);
list_add(&nt->list, &target_list);
@ -803,6 +933,8 @@ static int __init init_netconsole(void)
if (err)
goto undonotifier;
if (netconsole_ext.flags & CON_ENABLED)
register_console(&netconsole_ext);
register_console(&netconsole);
pr_info("network logging started\n");
@ -831,6 +963,7 @@ static void __exit cleanup_netconsole(void)
{
struct netconsole_target *nt, *tmp;
unregister_console(&netconsole_ext);
unregister_console(&netconsole);
dynamic_netconsole_exit();
unregister_netdevice_notifier(&netconsole_netdev_notifier);

View File

@ -4,8 +4,8 @@
* SPEAr13xx PCIe Glue Layer Source Code
*
* Copyright (C) 2010-2014 ST Microelectronics
* Pratyush Anand <pratyush.anand@st.com>
* Mohit Kumar <mohit.kumar@st.com>
* Pratyush Anand <pratyush.anand@gmail.com>
* Mohit Kumar <mohit.kumar.dhaka@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
@ -386,5 +386,5 @@ static int __init spear13xx_pcie_init(void)
module_init(spear13xx_pcie_init);
MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver");
MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>");
MODULE_AUTHOR("Pratyush Anand <pratyush.anand@gmail.com>");
MODULE_LICENSE("GPL v2");

View File

@ -2,8 +2,8 @@
* ST SPEAr1310-miphy driver
*
* Copyright (C) 2014 ST Microelectronics
* Pratyush Anand <pratyush.anand@st.com>
* Mohit Kumar <mohit.kumar@st.com>
* Pratyush Anand <pratyush.anand@gmail.com>
* Mohit Kumar <mohit.kumar.dhaka@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -257,5 +257,5 @@ static struct platform_driver spear1310_miphy_driver = {
module_platform_driver(spear1310_miphy_driver);
MODULE_DESCRIPTION("ST SPEAR1310-MIPHY driver");
MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>");
MODULE_AUTHOR("Pratyush Anand <pratyush.anand@gmail.com>");
MODULE_LICENSE("GPL v2");

View File

@ -2,8 +2,8 @@
* ST spear1340-miphy driver
*
* Copyright (C) 2014 ST Microelectronics
* Pratyush Anand <pratyush.anand@st.com>
* Mohit Kumar <mohit.kumar@st.com>
* Pratyush Anand <pratyush.anand@gmail.com>
* Mohit Kumar <mohit.kumar.dhaka@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -290,5 +290,5 @@ static struct platform_driver spear1340_miphy_driver = {
module_platform_driver(spear1340_miphy_driver);
MODULE_DESCRIPTION("ST SPEAR1340-MIPHY driver");
MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>");
MODULE_AUTHOR("Pratyush Anand <pratyush.anand@gmail.com>");
MODULE_LICENSE("GPL v2");

View File

@ -4,7 +4,7 @@
* Test pattern generation for Link Layer Validation System Tests
*
* Copyright (C) 2014 ST Microelectronics
* Pratyush Anand <pratyush.anand@st.com>
* Pratyush Anand <pratyush.anand@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any

View File

@ -137,8 +137,8 @@ static int
befs_bt_read_super(struct super_block *sb, befs_data_stream * ds,
befs_btree_super * sup)
{
struct buffer_head *bh = NULL;
befs_disk_btree_super *od_sup = NULL;
struct buffer_head *bh;
befs_disk_btree_super *od_sup;
befs_debug(sb, "---> %s", __func__);
@ -250,7 +250,7 @@ int
befs_btree_find(struct super_block *sb, befs_data_stream * ds,
const char *key, befs_off_t * value)
{
struct befs_btree_node *this_node = NULL;
struct befs_btree_node *this_node;
befs_btree_super bt_super;
befs_off_t node_off;
int res;

View File

@ -70,7 +70,8 @@ static int expand_corename(struct core_name *cn, int size)
return 0;
}
static int cn_vprintf(struct core_name *cn, const char *fmt, va_list arg)
static __printf(2, 0) int cn_vprintf(struct core_name *cn, const char *fmt,
va_list arg)
{
int free, need;
va_list arg_copy;
@ -93,7 +94,7 @@ static int cn_vprintf(struct core_name *cn, const char *fmt, va_list arg)
return -ENOMEM;
}
static int cn_printf(struct core_name *cn, const char *fmt, ...)
static __printf(2, 3) int cn_printf(struct core_name *cn, const char *fmt, ...)
{
va_list arg;
int ret;
@ -105,7 +106,8 @@ static int cn_printf(struct core_name *cn, const char *fmt, ...)
return ret;
}
static int cn_esc_printf(struct core_name *cn, const char *fmt, ...)
static __printf(2, 3)
int cn_esc_printf(struct core_name *cn, const char *fmt, ...)
{
int cur = cn->used;
va_list arg;
@ -209,11 +211,15 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm)
break;
/* uid */
case 'u':
err = cn_printf(cn, "%d", cred->uid);
err = cn_printf(cn, "%u",
from_kuid(&init_user_ns,
cred->uid));
break;
/* gid */
case 'g':
err = cn_printf(cn, "%d", cred->gid);
err = cn_printf(cn, "%u",
from_kgid(&init_user_ns,
cred->gid));
break;
case 'd':
err = cn_printf(cn, "%d",
@ -221,7 +227,8 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm)
break;
/* signal that caused the coredump */
case 's':
err = cn_printf(cn, "%ld", cprm->siginfo->si_signo);
err = cn_printf(cn, "%d",
cprm->siginfo->si_signo);
break;
/* UNIX time of coredump */
case 't': {

View File

@ -67,7 +67,7 @@ static struct kmem_cache * efs_inode_cachep;
static struct inode *efs_alloc_inode(struct super_block *sb)
{
struct efs_inode_info *ei;
ei = (struct efs_inode_info *)kmem_cache_alloc(efs_inode_cachep, GFP_KERNEL);
ei = kmem_cache_alloc(efs_inode_cachep, GFP_KERNEL);
if (!ei)
return NULL;
return &ei->vfs_inode;

View File

@ -3446,7 +3446,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
unsigned long journal_devnum = 0;
unsigned long def_mount_opts;
struct inode *root;
char *cp;
const char *descr;
int ret = -ENOMEM;
int blocksize, clustersize;
@ -3477,8 +3476,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
part_stat_read(sb->s_bdev->bd_part, sectors[1]);
/* Cleanup superblock name */
for (cp = sb->s_id; (cp = strchr(cp, '/'));)
*cp = '!';
strreplace(sb->s_id, '/', '!');
/* -EINVAL is default */
ret = -EINVAL;

View File

@ -1135,7 +1135,6 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev,
{
journal_t *journal = journal_init_common();
struct buffer_head *bh;
char *p;
int n;
if (!journal)
@ -1148,9 +1147,7 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev,
journal->j_blk_offset = start;
journal->j_maxlen = len;
bdevname(journal->j_dev, journal->j_devname);
p = journal->j_devname;
while ((p = strchr(p, '/')))
*p = '!';
strreplace(journal->j_devname, '/', '!');
jbd2_stats_proc_init(journal);
n = journal->j_blocksize / sizeof(journal_block_tag_t);
journal->j_wbufsize = n;
@ -1202,10 +1199,7 @@ journal_t * jbd2_journal_init_inode (struct inode *inode)
journal->j_dev = journal->j_fs_dev = inode->i_sb->s_bdev;
journal->j_inode = inode;
bdevname(journal->j_dev, journal->j_devname);
p = journal->j_devname;
while ((p = strchr(p, '/')))
*p = '!';
p = journal->j_devname + strlen(journal->j_devname);
p = strreplace(journal->j_devname, '/', '!');
sprintf(p, "-%lu", journal->j_inode->i_ino);
jbd_debug(1,
"journal %p: inode %s/%ld, size %Ld, bits %d, blksize %ld\n",

View File

@ -62,7 +62,7 @@ static struct kmem_cache * minix_inode_cachep;
static struct inode *minix_alloc_inode(struct super_block *sb)
{
struct minix_inode_info *ei;
ei = (struct minix_inode_info *)kmem_cache_alloc(minix_inode_cachep, GFP_KERNEL);
ei = kmem_cache_alloc(minix_inode_cachep, GFP_KERNEL);
if (!ei)
return NULL;
return &ei->vfs_inode;

View File

@ -496,8 +496,7 @@ static struct dentry *nilfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
{
struct nilfs_fid *fid = (struct nilfs_fid *)fh;
if ((fh_len != NILFS_FID_SIZE_NON_CONNECTABLE &&
fh_len != NILFS_FID_SIZE_CONNECTABLE) ||
if (fh_len < NILFS_FID_SIZE_NON_CONNECTABLE ||
(fh_type != FILEID_NILFS_WITH_PARENT &&
fh_type != FILEID_NILFS_WITHOUT_PARENT))
return NULL;
@ -510,7 +509,7 @@ static struct dentry *nilfs_fh_to_parent(struct super_block *sb, struct fid *fh,
{
struct nilfs_fid *fid = (struct nilfs_fid *)fh;
if (fh_len != NILFS_FID_SIZE_CONNECTABLE ||
if (fh_len < NILFS_FID_SIZE_CONNECTABLE ||
fh_type != FILEID_NILFS_WITH_PARENT)
return NULL;

View File

@ -71,3 +71,7 @@ config PROC_PAGE_MONITOR
/proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap,
/proc/kpagecount, and /proc/kpageflags. Disabling these
interfaces will reduce the size of the kernel by approximately 4kb.
config PROC_CHILDREN
bool "Include /proc/<pid>/task/<tid>/children file"
default n

View File

@ -577,7 +577,7 @@ int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
return 0;
}
#ifdef CONFIG_CHECKPOINT_RESTORE
#ifdef CONFIG_PROC_CHILDREN
static struct pid *
get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos)
{
@ -700,4 +700,4 @@ const struct file_operations proc_tid_children_operations = {
.llseek = seq_lseek,
.release = children_seq_release,
};
#endif /* CONFIG_CHECKPOINT_RESTORE */
#endif /* CONFIG_PROC_CHILDREN */

View File

@ -196,18 +196,205 @@ static int proc_root_link(struct dentry *dentry, struct path *path)
return result;
}
static int proc_pid_cmdline(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
size_t _count, loff_t *pos)
{
struct task_struct *tsk;
struct mm_struct *mm;
char *page;
unsigned long count = _count;
unsigned long arg_start, arg_end, env_start, env_end;
unsigned long len1, len2, len;
unsigned long p;
char c;
ssize_t rv;
BUG_ON(*pos < 0);
tsk = get_proc_task(file_inode(file));
if (!tsk)
return -ESRCH;
mm = get_task_mm(tsk);
put_task_struct(tsk);
if (!mm)
return 0;
/* Check if process spawned far enough to have cmdline. */
if (!mm->env_end) {
rv = 0;
goto out_mmput;
}
page = (char *)__get_free_page(GFP_TEMPORARY);
if (!page) {
rv = -ENOMEM;
goto out_mmput;
}
down_read(&mm->mmap_sem);
arg_start = mm->arg_start;
arg_end = mm->arg_end;
env_start = mm->env_start;
env_end = mm->env_end;
up_read(&mm->mmap_sem);
BUG_ON(arg_start > arg_end);
BUG_ON(env_start > env_end);
len1 = arg_end - arg_start;
len2 = env_end - env_start;
/*
* Rely on struct seq_operations::show() being called once
* per internal buffer allocation. See single_open(), traverse().
* Inherently racy -- command line shares address space
* with code and data.
*/
BUG_ON(m->size < PAGE_SIZE);
m->count += get_cmdline(task, m->buf, PAGE_SIZE);
return 0;
rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0);
if (rv <= 0)
goto out_free_page;
rv = 0;
if (c == '\0') {
/* Command line (set of strings) occupies whole ARGV. */
if (len1 <= *pos)
goto out_free_page;
p = arg_start + *pos;
len = len1 - *pos;
while (count > 0 && len > 0) {
unsigned int _count;
int nr_read;
_count = min3(count, len, PAGE_SIZE);
nr_read = access_remote_vm(mm, p, page, _count, 0);
if (nr_read < 0)
rv = nr_read;
if (nr_read <= 0)
goto out_free_page;
if (copy_to_user(buf, page, nr_read)) {
rv = -EFAULT;
goto out_free_page;
}
p += nr_read;
len -= nr_read;
buf += nr_read;
count -= nr_read;
rv += nr_read;
}
} else {
/*
* Command line (1 string) occupies ARGV and maybe
* extends into ENVP.
*/
if (len1 + len2 <= *pos)
goto skip_argv_envp;
if (len1 <= *pos)
goto skip_argv;
p = arg_start + *pos;
len = len1 - *pos;
while (count > 0 && len > 0) {
unsigned int _count, l;
int nr_read;
bool final;
_count = min3(count, len, PAGE_SIZE);
nr_read = access_remote_vm(mm, p, page, _count, 0);
if (nr_read < 0)
rv = nr_read;
if (nr_read <= 0)
goto out_free_page;
/*
* Command line can be shorter than whole ARGV
* even if last "marker" byte says it is not.
*/
final = false;
l = strnlen(page, nr_read);
if (l < nr_read) {
nr_read = l;
final = true;
}
if (copy_to_user(buf, page, nr_read)) {
rv = -EFAULT;
goto out_free_page;
}
p += nr_read;
len -= nr_read;
buf += nr_read;
count -= nr_read;
rv += nr_read;
if (final)
goto out_free_page;
}
skip_argv:
/*
* Command line (1 string) occupies ARGV and
* extends into ENVP.
*/
if (len1 <= *pos) {
p = env_start + *pos - len1;
len = len1 + len2 - *pos;
} else {
p = env_start;
len = len2;
}
while (count > 0 && len > 0) {
unsigned int _count, l;
int nr_read;
bool final;
_count = min3(count, len, PAGE_SIZE);
nr_read = access_remote_vm(mm, p, page, _count, 0);
if (nr_read < 0)
rv = nr_read;
if (nr_read <= 0)
goto out_free_page;
/* Find EOS. */
final = false;
l = strnlen(page, nr_read);
if (l < nr_read) {
nr_read = l;
final = true;
}
if (copy_to_user(buf, page, nr_read)) {
rv = -EFAULT;
goto out_free_page;
}
p += nr_read;
len -= nr_read;
buf += nr_read;
count -= nr_read;
rv += nr_read;
if (final)
goto out_free_page;
}
skip_argv_envp:
;
}
out_free_page:
free_page((unsigned long)page);
out_mmput:
mmput(mm);
if (rv > 0)
*pos += rv;
return rv;
}
static const struct file_operations proc_pid_cmdline_ops = {
.read = proc_pid_cmdline_read,
.llseek = generic_file_llseek,
};
static int proc_pid_auxv(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{
@ -2572,7 +2759,7 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
ONE("syscall", S_IRUSR, proc_pid_syscall),
#endif
ONE("cmdline", S_IRUGO, proc_pid_cmdline),
REG("cmdline", S_IRUGO, proc_pid_cmdline_ops),
ONE("stat", S_IRUGO, proc_tgid_stat),
ONE("statm", S_IRUGO, proc_pid_statm),
REG("maps", S_IRUGO, proc_pid_maps_operations),
@ -2918,11 +3105,11 @@ static const struct pid_entry tid_base_stuff[] = {
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
ONE("syscall", S_IRUSR, proc_pid_syscall),
#endif
ONE("cmdline", S_IRUGO, proc_pid_cmdline),
REG("cmdline", S_IRUGO, proc_pid_cmdline_ops),
ONE("stat", S_IRUGO, proc_tid_stat),
ONE("statm", S_IRUGO, proc_pid_statm),
REG("maps", S_IRUGO, proc_tid_maps_operations),
#ifdef CONFIG_CHECKPOINT_RESTORE
#ifdef CONFIG_PROC_CHILDREN
REG("children", S_IRUGO, proc_tid_children_operations),
#endif
#ifdef CONFIG_NUMA

View File

@ -589,8 +589,7 @@ static struct kmem_cache *reiserfs_inode_cachep;
static struct inode *reiserfs_alloc_inode(struct super_block *sb)
{
struct reiserfs_inode_info *ei;
ei = (struct reiserfs_inode_info *)
kmem_cache_alloc(reiserfs_inode_cachep, GFP_KERNEL);
ei = kmem_cache_alloc(reiserfs_inode_cachep, GFP_KERNEL);
if (!ei)
return NULL;
atomic_set(&ei->openers, 0);

View File

@ -5,9 +5,9 @@
/*
* Common definitions for all gcc versions go here.
*/
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
/* Optimization barrier */
@ -46,55 +46,63 @@
* the inline assembly constraint from =g to =r, in this particular
* case either is valid.
*/
#define RELOC_HIDE(ptr, off) \
({ unsigned long __ptr; \
__asm__ ("" : "=r"(__ptr) : "0"(ptr)); \
(typeof(ptr)) (__ptr + (off)); })
#define RELOC_HIDE(ptr, off) \
({ \
unsigned long __ptr; \
__asm__ ("" : "=r"(__ptr) : "0"(ptr)); \
(typeof(ptr)) (__ptr + (off)); \
})
/* Make the optimizer believe the variable can be manipulated arbitrarily. */
#define OPTIMIZER_HIDE_VAR(var) __asm__ ("" : "=r" (var) : "0" (var))
#define OPTIMIZER_HIDE_VAR(var) \
__asm__ ("" : "=r" (var) : "0" (var))
#ifdef __CHECKER__
#define __must_be_array(arr) 0
#define __must_be_array(a) 0
#else
/* &a[0] degrades to a pointer: a different type from an array */
#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
#endif
/*
* Force always-inline if the user requests it so via the .config,
* or if gcc is too old:
*/
#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \
#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \
!defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4)
# define inline inline __attribute__((always_inline)) notrace
# define __inline__ __inline__ __attribute__((always_inline)) notrace
# define __inline __inline __attribute__((always_inline)) notrace
#define inline inline __attribute__((always_inline)) notrace
#define __inline__ __inline__ __attribute__((always_inline)) notrace
#define __inline __inline __attribute__((always_inline)) notrace
#else
/* A lot of inline functions can cause havoc with function tracing */
# define inline inline notrace
# define __inline__ __inline__ notrace
# define __inline __inline notrace
#define inline inline notrace
#define __inline__ __inline__ notrace
#define __inline __inline notrace
#endif
#define __deprecated __attribute__((deprecated))
#define __packed __attribute__((packed))
#define __weak __attribute__((weak))
#define __alias(symbol) __attribute__((alias(#symbol)))
#define __always_inline inline __attribute__((always_inline))
#define noinline __attribute__((noinline))
#define __deprecated __attribute__((deprecated))
#define __packed __attribute__((packed))
#define __weak __attribute__((weak))
#define __alias(symbol) __attribute__((alias(#symbol)))
/*
* it doesn't make sense on ARM (currently the only user of __naked) to trace
* naked functions because then mcount is called without stack and frame pointer
* being set up and there is no chance to restore the lr register to the value
* before mcount was called.
* it doesn't make sense on ARM (currently the only user of __naked)
* to trace naked functions because then mcount is called without
* stack and frame pointer being set up and there is no chance to
* restore the lr register to the value before mcount was called.
*
* The asm() bodies of naked functions often depend on standard calling conventions,
* therefore they must be noinline and noclone. GCC 4.[56] currently fail to enforce
* this, so we must do so ourselves. See GCC PR44290.
* The asm() bodies of naked functions often depend on standard calling
* conventions, therefore they must be noinline and noclone.
*
* GCC 4.[56] currently fail to enforce this, so we must do so ourselves.
* See GCC PR44290.
*/
#define __naked __attribute__((naked)) noinline __noclone notrace
#define __naked __attribute__((naked)) noinline __noclone notrace
#define __noreturn __attribute__((noreturn))
#define __noreturn __attribute__((noreturn))
/*
* From the GCC manual:
@ -106,19 +114,130 @@
* would be.
* [...]
*/
#define __pure __attribute__((pure))
#define __aligned(x) __attribute__((aligned(x)))
#define __printf(a, b) __attribute__((format(printf, a, b)))
#define __scanf(a, b) __attribute__((format(scanf, a, b)))
#define noinline __attribute__((noinline))
#define __attribute_const__ __attribute__((__const__))
#define __maybe_unused __attribute__((unused))
#define __always_unused __attribute__((unused))
#define __pure __attribute__((pure))
#define __aligned(x) __attribute__((aligned(x)))
#define __printf(a, b) __attribute__((format(printf, a, b)))
#define __scanf(a, b) __attribute__((format(scanf, a, b)))
#define __attribute_const__ __attribute__((__const__))
#define __maybe_unused __attribute__((unused))
#define __always_unused __attribute__((unused))
#define __gcc_header(x) #x
#define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h)
#define gcc_header(x) _gcc_header(x)
#include gcc_header(__GNUC__)
/* gcc version specific checks */
#if GCC_VERSION < 30200
# error Sorry, your compiler is too old - please upgrade it.
#endif
#if GCC_VERSION < 30300
# define __used __attribute__((__unused__))
#else
# define __used __attribute__((__used__))
#endif
#ifdef CONFIG_GCOV_KERNEL
# if GCC_VERSION < 30400
# error "GCOV profiling support for gcc versions below 3.4 not included"
# endif /* __GNUC_MINOR__ */
#endif /* CONFIG_GCOV_KERNEL */
#if GCC_VERSION >= 30400
#define __must_check __attribute__((warn_unused_result))
#endif
#if GCC_VERSION >= 40000
/* GCC 4.1.[01] miscompiles __weak */
#ifdef __KERNEL__
# if GCC_VERSION >= 40100 && GCC_VERSION <= 40101
# error Your version of gcc miscompiles the __weak directive
# endif
#endif
#define __used __attribute__((__used__))
#define __compiler_offsetof(a, b) \
__builtin_offsetof(a, b)
#if GCC_VERSION >= 40100 && GCC_VERSION < 40600
# define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
#endif
#if GCC_VERSION >= 40300
/* Mark functions as cold. gcc will assume any path leading to a call
* to them will be unlikely. This means a lot of manual unlikely()s
* are unnecessary now for any paths leading to the usual suspects
* like BUG(), printk(), panic() etc. [but let's keep them for now for
* older compilers]
*
* Early snapshots of gcc 4.3 don't support this and we can't detect this
* in the preprocessor, but we can live with this because they're unreleased.
* Maketime probing would be overkill here.
*
* gcc also has a __attribute__((__hot__)) to move hot functions into
* a special section, but I don't see any sense in this right now in
* the kernel context
*/
#define __cold __attribute__((__cold__))
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
#ifndef __CHECKER__
# define __compiletime_warning(message) __attribute__((warning(message)))
# define __compiletime_error(message) __attribute__((error(message)))
#endif /* __CHECKER__ */
#endif /* GCC_VERSION >= 40300 */
#if GCC_VERSION >= 40500
/*
* Mark a position in code as unreachable. This can be used to
* suppress control flow warnings after asm blocks that transfer
* control elsewhere.
*
* Early snapshots of gcc 4.5 don't support this and we can't detect
* this in the preprocessor, but we can live with this because they're
* unreleased. Really, we need to have autoconf for the kernel.
*/
#define unreachable() __builtin_unreachable()
/* Mark a function definition as prohibited from being cloned. */
#define __noclone __attribute__((__noclone__))
#endif /* GCC_VERSION >= 40500 */
#if GCC_VERSION >= 40600
/*
* Tell the optimizer that something else uses this function or variable.
*/
#define __visible __attribute__((externally_visible))
#endif
/*
* GCC 'asm goto' miscompiles certain code sequences:
*
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
*
* Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
*
* (asm goto is automatically volatile - the naming reflects this.)
*/
#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
#if GCC_VERSION >= 40400
#define __HAVE_BUILTIN_BSWAP32__
#define __HAVE_BUILTIN_BSWAP64__
#endif
#if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600)
#define __HAVE_BUILTIN_BSWAP16__
#endif
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
#if GCC_VERSION >= 50000
#define KASAN_ABI_VERSION 4
#elif GCC_VERSION >= 40902
#define KASAN_ABI_VERSION 3
#endif
#endif /* gcc version >= 40000 specific checks */
#if !defined(__noclone)
#define __noclone /* not needed */
@ -129,5 +248,3 @@
* code
*/
#define uninitialized_var(x) x = x
#define __always_inline inline __attribute__((always_inline))

View File

@ -1,23 +0,0 @@
#ifndef __LINUX_COMPILER_H
#error "Please don't include <linux/compiler-gcc3.h> directly, include <linux/compiler.h> instead."
#endif
#if GCC_VERSION < 30200
# error Sorry, your compiler is too old - please upgrade it.
#endif
#if GCC_VERSION >= 30300
# define __used __attribute__((__used__))
#else
# define __used __attribute__((__unused__))
#endif
#if GCC_VERSION >= 30400
#define __must_check __attribute__((warn_unused_result))
#endif
#ifdef CONFIG_GCOV_KERNEL
# if GCC_VERSION < 30400
# error "GCOV profiling support for gcc versions below 3.4 not included"
# endif /* __GNUC_MINOR__ */
#endif /* CONFIG_GCOV_KERNEL */

View File

@ -1,91 +0,0 @@
#ifndef __LINUX_COMPILER_H
#error "Please don't include <linux/compiler-gcc4.h> directly, include <linux/compiler.h> instead."
#endif
/* GCC 4.1.[01] miscompiles __weak */
#ifdef __KERNEL__
# if GCC_VERSION >= 40100 && GCC_VERSION <= 40101
# error Your version of gcc miscompiles the __weak directive
# endif
#endif
#define __used __attribute__((__used__))
#define __must_check __attribute__((warn_unused_result))
#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
#if GCC_VERSION >= 40100 && GCC_VERSION < 40600
# define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
#endif
#if GCC_VERSION >= 40300
/* Mark functions as cold. gcc will assume any path leading to a call
to them will be unlikely. This means a lot of manual unlikely()s
are unnecessary now for any paths leading to the usual suspects
like BUG(), printk(), panic() etc. [but let's keep them for now for
older compilers]
Early snapshots of gcc 4.3 don't support this and we can't detect this
in the preprocessor, but we can live with this because they're unreleased.
Maketime probing would be overkill here.
gcc also has a __attribute__((__hot__)) to move hot functions into
a special section, but I don't see any sense in this right now in
the kernel context */
#define __cold __attribute__((__cold__))
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
#ifndef __CHECKER__
# define __compiletime_warning(message) __attribute__((warning(message)))
# define __compiletime_error(message) __attribute__((error(message)))
#endif /* __CHECKER__ */
#endif /* GCC_VERSION >= 40300 */
#if GCC_VERSION >= 40500
/*
* Mark a position in code as unreachable. This can be used to
* suppress control flow warnings after asm blocks that transfer
* control elsewhere.
*
* Early snapshots of gcc 4.5 don't support this and we can't detect
* this in the preprocessor, but we can live with this because they're
* unreleased. Really, we need to have autoconf for the kernel.
*/
#define unreachable() __builtin_unreachable()
/* Mark a function definition as prohibited from being cloned. */
#define __noclone __attribute__((__noclone__))
#endif /* GCC_VERSION >= 40500 */
#if GCC_VERSION >= 40600
/*
* Tell the optimizer that something else uses this function or variable.
*/
#define __visible __attribute__((externally_visible))
#endif
/*
* GCC 'asm goto' miscompiles certain code sequences:
*
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
*
* Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
*
* (asm goto is automatically volatile - the naming reflects this.)
*/
#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
#if GCC_VERSION >= 40400
#define __HAVE_BUILTIN_BSWAP32__
#define __HAVE_BUILTIN_BSWAP64__
#endif
#if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600)
#define __HAVE_BUILTIN_BSWAP16__
#endif
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
#if GCC_VERSION >= 40902
#define KASAN_ABI_VERSION 3
#endif

View File

@ -1,67 +0,0 @@
#ifndef __LINUX_COMPILER_H
#error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead."
#endif
#define __used __attribute__((__used__))
#define __must_check __attribute__((warn_unused_result))
#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
/* Mark functions as cold. gcc will assume any path leading to a call
to them will be unlikely. This means a lot of manual unlikely()s
are unnecessary now for any paths leading to the usual suspects
like BUG(), printk(), panic() etc. [but let's keep them for now for
older compilers]
Early snapshots of gcc 4.3 don't support this and we can't detect this
in the preprocessor, but we can live with this because they're unreleased.
Maketime probing would be overkill here.
gcc also has a __attribute__((__hot__)) to move hot functions into
a special section, but I don't see any sense in this right now in
the kernel context */
#define __cold __attribute__((__cold__))
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
#ifndef __CHECKER__
# define __compiletime_warning(message) __attribute__((warning(message)))
# define __compiletime_error(message) __attribute__((error(message)))
#endif /* __CHECKER__ */
/*
* Mark a position in code as unreachable. This can be used to
* suppress control flow warnings after asm blocks that transfer
* control elsewhere.
*
* Early snapshots of gcc 4.5 don't support this and we can't detect
* this in the preprocessor, but we can live with this because they're
* unreleased. Really, we need to have autoconf for the kernel.
*/
#define unreachable() __builtin_unreachable()
/* Mark a function definition as prohibited from being cloned. */
#define __noclone __attribute__((__noclone__))
/*
* Tell the optimizer that something else uses this function or variable.
*/
#define __visible __attribute__((externally_visible))
/*
* GCC 'asm goto' miscompiles certain code sequences:
*
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
*
* Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
*
* (asm goto is automatically volatile - the naming reflects this.)
*/
#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
#define __HAVE_BUILTIN_BSWAP32__
#define __HAVE_BUILTIN_BSWAP64__
#define __HAVE_BUILTIN_BSWAP16__
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
#define KASAN_ABI_VERSION 4

View File

@ -13,10 +13,12 @@
/* Intel ECC compiler doesn't support gcc specific asm stmts.
* It uses intrinsics to do the equivalent things.
*/
#undef barrier
#undef barrier_data
#undef RELOC_HIDE
#undef OPTIMIZER_HIDE_VAR
#define barrier() __memory_barrier()
#define barrier_data(ptr) barrier()
#define RELOC_HIDE(ptr, off) \

View File

@ -115,6 +115,7 @@ static inline int con_debug_leave(void)
#define CON_BOOT (8)
#define CON_ANYTIME (16) /* Safe to call when cpu is offline */
#define CON_BRL (32) /* Used for a braille device */
#define CON_EXTENDED (64) /* Use the extended output format a la /dev/kmsg */
struct console {
char name[16];

View File

@ -30,6 +30,8 @@ static inline const char *printk_skip_level(const char *buffer)
return buffer;
}
#define CONSOLE_EXT_LOG_MAX 8192
/* printk's without a loglevel use this.. */
#define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT

View File

@ -2556,8 +2556,22 @@ extern struct mm_struct *mm_access(struct task_struct *task, unsigned int mode);
/* Remove the current tasks stale references to the old mm_struct */
extern void mm_release(struct task_struct *, struct mm_struct *);
#ifdef CONFIG_HAVE_COPY_THREAD_TLS
extern int copy_thread_tls(unsigned long, unsigned long, unsigned long,
struct task_struct *, unsigned long);
#else
extern int copy_thread(unsigned long, unsigned long, unsigned long,
struct task_struct *);
/* Architectures that haven't opted into copy_thread_tls get the tls argument
* via pt_regs, so ignore the tls argument passed via C. */
static inline int copy_thread_tls(
unsigned long clone_flags, unsigned long sp, unsigned long arg,
struct task_struct *p, unsigned long tls)
{
return copy_thread(clone_flags, sp, arg, p);
}
#endif
extern void flush_thread(void);
extern void exit_thread(void);
@ -2576,6 +2590,7 @@ extern int do_execveat(int, struct filename *,
const char __user * const __user *,
const char __user * const __user *,
int);
extern long _do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *, unsigned long);
extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *);
struct task_struct *fork_idle(int);
extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);

View File

@ -3,7 +3,6 @@
#include <uapi/linux/stddef.h>
#undef NULL
#define NULL ((void *)0)
@ -14,10 +13,9 @@ enum {
#undef offsetof
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
#endif
/**
@ -28,3 +26,5 @@ enum {
*/
#define offsetofend(TYPE, MEMBER) \
(offsetof(TYPE, MEMBER) + sizeof(((TYPE *)0)->MEMBER))
#endif

View File

@ -111,6 +111,7 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
extern void * memchr(const void *,int,__kernel_size_t);
#endif
void *memchr_inv(const void *s, int c, size_t n);
char *strreplace(char *s, char old, char new);
extern void kfree_const(const void *x);

View File

@ -827,15 +827,15 @@ asmlinkage long sys_syncfs(int fd);
asmlinkage long sys_fork(void);
asmlinkage long sys_vfork(void);
#ifdef CONFIG_CLONE_BACKWARDS
asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, int,
asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, unsigned long,
int __user *);
#else
#ifdef CONFIG_CLONE_BACKWARDS3
asmlinkage long sys_clone(unsigned long, unsigned long, int, int __user *,
int __user *, int);
int __user *, unsigned long);
#else
asmlinkage long sys_clone(unsigned long, unsigned long, int __user *,
int __user *, int);
int __user *, unsigned long);
#endif
#endif

View File

@ -47,12 +47,12 @@
#define SYSLOG_FROM_READER 0
#define SYSLOG_FROM_PROC 1
int do_syslog(int type, char __user *buf, int count, bool from_file);
int do_syslog(int type, char __user *buf, int count, int source);
#ifdef CONFIG_PRINTK
int check_syslog_permissions(int type, bool from_file);
int check_syslog_permissions(int type, int source);
#else
static inline int check_syslog_permissions(int type, bool from_file)
static inline int check_syslog_permissions(int type, int source)
{
return 0;
}

View File

@ -81,7 +81,8 @@ struct zpool_driver {
atomic_t refcount;
struct list_head list;
void *(*create)(char *name, gfp_t gfp, struct zpool_ops *ops);
void *(*create)(char *name, gfp_t gfp, struct zpool_ops *ops,
struct zpool *zpool);
void (*destroy)(void *pool);
int (*malloc)(void *pool, size_t size, gfp_t gfp,
@ -102,6 +103,4 @@ void zpool_register_driver(struct zpool_driver *driver);
int zpool_unregister_driver(struct zpool_driver *driver);
int zpool_evict(void *pool, unsigned long handle);
#endif

View File

@ -1136,6 +1136,7 @@ endif # CGROUPS
config CHECKPOINT_RESTORE
bool "Checkpoint/restore support" if EXPERT
select PROC_CHILDREN
default n
help
Enables additional kernel features in a sake of checkpoint/restore.

View File

@ -533,8 +533,13 @@ void __init mount_root(void)
}
#endif
#ifdef CONFIG_BLOCK
create_dev("/dev/root", ROOT_DEV);
mount_block_root("/dev/root", root_mountflags);
{
int err = create_dev("/dev/root", ROOT_DEV);
if (err < 0)
pr_emerg("Failed to create /dev/root: %d\n", err);
mount_block_root("/dev/root", root_mountflags);
}
#endif
}

View File

@ -711,10 +711,10 @@ void do_exit(long code)
current->comm, task_pid_nr(current),
preempt_count());
acct_update_integrals(tsk);
/* sync mm's RSS info before statistics gathering */
if (tsk->mm)
sync_mm_rss(tsk->mm);
acct_update_integrals(tsk);
group_dead = atomic_dec_and_test(&tsk->signal->live);
if (group_dead) {
hrtimer_cancel(&tsk->signal->real_timer);

View File

@ -1238,7 +1238,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
unsigned long stack_size,
int __user *child_tidptr,
struct pid *pid,
int trace)
int trace,
unsigned long tls)
{
int retval;
struct task_struct *p;
@ -1447,7 +1448,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
retval = copy_io(clone_flags, p);
if (retval)
goto bad_fork_cleanup_namespaces;
retval = copy_thread(clone_flags, stack_start, stack_size, p);
retval = copy_thread_tls(clone_flags, stack_start, stack_size, p, tls);
if (retval)
goto bad_fork_cleanup_io;
@ -1659,7 +1660,7 @@ static inline void init_idle_pids(struct pid_link *links)
struct task_struct *fork_idle(int cpu)
{
struct task_struct *task;
task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0);
task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0, 0);
if (!IS_ERR(task)) {
init_idle_pids(task->pids);
init_idle(task, cpu);
@ -1674,11 +1675,12 @@ struct task_struct *fork_idle(int cpu)
* It copies the process, and if successful kick-starts
* it and waits for it to finish using the VM if required.
*/
long do_fork(unsigned long clone_flags,
long _do_fork(unsigned long clone_flags,
unsigned long stack_start,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr)
int __user *child_tidptr,
unsigned long tls)
{
struct task_struct *p;
int trace = 0;
@ -1703,7 +1705,7 @@ long do_fork(unsigned long clone_flags,
}
p = copy_process(clone_flags, stack_start, stack_size,
child_tidptr, NULL, trace);
child_tidptr, NULL, trace, tls);
/*
* Do this prior waking up the new thread - the thread pointer
* might get invalid after that point, if the thread exits quickly.
@ -1744,20 +1746,34 @@ long do_fork(unsigned long clone_flags,
return nr;
}
#ifndef CONFIG_HAVE_COPY_THREAD_TLS
/* For compatibility with architectures that call do_fork directly rather than
* using the syscall entry points below. */
long do_fork(unsigned long clone_flags,
unsigned long stack_start,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr)
{
return _do_fork(clone_flags, stack_start, stack_size,
parent_tidptr, child_tidptr, 0);
}
#endif
/*
* Create a kernel thread.
*/
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,
(unsigned long)arg, NULL, NULL);
return _do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,
(unsigned long)arg, NULL, NULL, 0);
}
#ifdef __ARCH_WANT_SYS_FORK
SYSCALL_DEFINE0(fork)
{
#ifdef CONFIG_MMU
return do_fork(SIGCHLD, 0, 0, NULL, NULL);
return _do_fork(SIGCHLD, 0, 0, NULL, NULL, 0);
#else
/* can not support in nommu mode */
return -EINVAL;
@ -1768,8 +1784,8 @@ SYSCALL_DEFINE0(fork)
#ifdef __ARCH_WANT_SYS_VFORK
SYSCALL_DEFINE0(vfork)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
0, NULL, NULL);
return _do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
0, NULL, NULL, 0);
}
#endif
@ -1777,27 +1793,27 @@ SYSCALL_DEFINE0(vfork)
#ifdef CONFIG_CLONE_BACKWARDS
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
int __user *, parent_tidptr,
int, tls_val,
unsigned long, tls,
int __user *, child_tidptr)
#elif defined(CONFIG_CLONE_BACKWARDS2)
SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags,
int __user *, parent_tidptr,
int __user *, child_tidptr,
int, tls_val)
unsigned long, tls)
#elif defined(CONFIG_CLONE_BACKWARDS3)
SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp,
int, stack_size,
int __user *, parent_tidptr,
int __user *, child_tidptr,
int, tls_val)
unsigned long, tls)
#else
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
int __user *, parent_tidptr,
int __user *, child_tidptr,
int, tls_val)
unsigned long, tls)
#endif
{
return do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);
return _do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr, tls);
}
#endif

View File

@ -84,6 +84,18 @@ static struct lockdep_map console_lock_dep_map = {
};
#endif
/*
* Number of registered extended console drivers.
*
* If extended consoles are present, in-kernel cont reassembly is disabled
* and each fragment is stored as a separate log entry with proper
* continuation flag so that every emitted message has full metadata. This
* doesn't change the result for regular consoles or /proc/kmsg. For
* /dev/kmsg, as long as the reader concatenates messages according to
* consecutive continuation flags, the end result should be the same too.
*/
static int nr_ext_console_drivers;
/*
* Helper macros to handle lockdep when locking/unlocking console_sem. We use
* macros instead of functions so that _RET_IP_ contains useful information.
@ -195,7 +207,7 @@ static int console_may_schedule;
* need to be changed in the future, when the requirements change.
*
* /dev/kmsg exports the structured data in the following line format:
* "level,sequnum,timestamp;<message text>\n"
* "<level>,<sequnum>,<timestamp>,<contflag>;<message text>\n"
*
* The optional key/value pairs are attached as continuation lines starting
* with a space character and terminated by a newline. All possible
@ -477,18 +489,18 @@ static int syslog_action_restricted(int type)
type != SYSLOG_ACTION_SIZE_BUFFER;
}
int check_syslog_permissions(int type, bool from_file)
int check_syslog_permissions(int type, int source)
{
/*
* If this is from /proc/kmsg and we've already opened it, then we've
* already done the capabilities checks at open time.
*/
if (from_file && type != SYSLOG_ACTION_OPEN)
return 0;
if (source == SYSLOG_FROM_PROC && type != SYSLOG_ACTION_OPEN)
goto ok;
if (syslog_action_restricted(type)) {
if (capable(CAP_SYSLOG))
return 0;
goto ok;
/*
* For historical reasons, accept CAP_SYS_ADMIN too, with
* a warning.
@ -498,13 +510,94 @@ int check_syslog_permissions(int type, bool from_file)
"CAP_SYS_ADMIN but no CAP_SYSLOG "
"(deprecated).\n",
current->comm, task_pid_nr(current));
return 0;
goto ok;
}
return -EPERM;
}
ok:
return security_syslog(type);
}
static void append_char(char **pp, char *e, char c)
{
if (*pp < e)
*(*pp)++ = c;
}
static ssize_t msg_print_ext_header(char *buf, size_t size,
struct printk_log *msg, u64 seq,
enum log_flags prev_flags)
{
u64 ts_usec = msg->ts_nsec;
char cont = '-';
do_div(ts_usec, 1000);
/*
* If we couldn't merge continuation line fragments during the print,
* export the stored flags to allow an optional external merge of the
* records. Merging the records isn't always neccessarily correct, like
* when we hit a race during printing. In most cases though, it produces
* better readable output. 'c' in the record flags mark the first
* fragment of a line, '+' the following.
*/
if (msg->flags & LOG_CONT && !(prev_flags & LOG_CONT))
cont = 'c';
else if ((msg->flags & LOG_CONT) ||
((prev_flags & LOG_CONT) && !(msg->flags & LOG_PREFIX)))
cont = '+';
return scnprintf(buf, size, "%u,%llu,%llu,%c;",
(msg->facility << 3) | msg->level, seq, ts_usec, cont);
}
static ssize_t msg_print_ext_body(char *buf, size_t size,
char *dict, size_t dict_len,
char *text, size_t text_len)
{
char *p = buf, *e = buf + size;
size_t i;
/* escape non-printable characters */
for (i = 0; i < text_len; i++) {
unsigned char c = text[i];
if (c < ' ' || c >= 127 || c == '\\')
p += scnprintf(p, e - p, "\\x%02x", c);
else
append_char(&p, e, c);
}
append_char(&p, e, '\n');
if (dict_len) {
bool line = true;
for (i = 0; i < dict_len; i++) {
unsigned char c = dict[i];
if (line) {
append_char(&p, e, ' ');
line = false;
}
if (c == '\0') {
append_char(&p, e, '\n');
line = true;
continue;
}
if (c < ' ' || c >= 127 || c == '\\') {
p += scnprintf(p, e - p, "\\x%02x", c);
continue;
}
append_char(&p, e, c);
}
append_char(&p, e, '\n');
}
return p - buf;
}
/* /dev/kmsg - userspace message inject/listen interface */
struct devkmsg_user {
@ -512,7 +605,7 @@ struct devkmsg_user {
u32 idx;
enum log_flags prev;
struct mutex lock;
char buf[8192];
char buf[CONSOLE_EXT_LOG_MAX];
};
static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from)
@ -570,9 +663,6 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
{
struct devkmsg_user *user = file->private_data;
struct printk_log *msg;
u64 ts_usec;
size_t i;
char cont = '-';
size_t len;
ssize_t ret;
@ -608,66 +698,13 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
}
msg = log_from_idx(user->idx);
ts_usec = msg->ts_nsec;
do_div(ts_usec, 1000);
len = msg_print_ext_header(user->buf, sizeof(user->buf),
msg, user->seq, user->prev);
len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len,
log_dict(msg), msg->dict_len,
log_text(msg), msg->text_len);
/*
* If we couldn't merge continuation line fragments during the print,
* export the stored flags to allow an optional external merge of the
* records. Merging the records isn't always neccessarily correct, like
* when we hit a race during printing. In most cases though, it produces
* better readable output. 'c' in the record flags mark the first
* fragment of a line, '+' the following.
*/
if (msg->flags & LOG_CONT && !(user->prev & LOG_CONT))
cont = 'c';
else if ((msg->flags & LOG_CONT) ||
((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX)))
cont = '+';
len = sprintf(user->buf, "%u,%llu,%llu,%c;",
(msg->facility << 3) | msg->level,
user->seq, ts_usec, cont);
user->prev = msg->flags;
/* escape non-printable characters */
for (i = 0; i < msg->text_len; i++) {
unsigned char c = log_text(msg)[i];
if (c < ' ' || c >= 127 || c == '\\')
len += sprintf(user->buf + len, "\\x%02x", c);
else
user->buf[len++] = c;
}
user->buf[len++] = '\n';
if (msg->dict_len) {
bool line = true;
for (i = 0; i < msg->dict_len; i++) {
unsigned char c = log_dict(msg)[i];
if (line) {
user->buf[len++] = ' ';
line = false;
}
if (c == '\0') {
user->buf[len++] = '\n';
line = true;
continue;
}
if (c < ' ' || c >= 127 || c == '\\') {
len += sprintf(user->buf + len, "\\x%02x", c);
continue;
}
user->buf[len++] = c;
}
user->buf[len++] = '\n';
}
user->idx = log_next(user->idx);
user->seq++;
raw_spin_unlock_irq(&logbuf_lock);
@ -1253,20 +1290,16 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
return len;
}
int do_syslog(int type, char __user *buf, int len, bool from_file)
int do_syslog(int type, char __user *buf, int len, int source)
{
bool clear = false;
static int saved_console_loglevel = LOGLEVEL_DEFAULT;
int error;
error = check_syslog_permissions(type, from_file);
error = check_syslog_permissions(type, source);
if (error)
goto out;
error = security_syslog(type);
if (error)
return error;
switch (type) {
case SYSLOG_ACTION_CLOSE: /* Close log */
break;
@ -1346,7 +1379,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
syslog_prev = 0;
syslog_partial = 0;
}
if (from_file) {
if (source == SYSLOG_FROM_PROC) {
/*
* Short-cut for poll(/"proc/kmsg") which simply checks
* for pending data, not the size; return the count of
@ -1393,7 +1426,9 @@ SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
* log_buf[start] to log_buf[end - 1].
* The console_lock must be held.
*/
static void call_console_drivers(int level, const char *text, size_t len)
static void call_console_drivers(int level,
const char *ext_text, size_t ext_len,
const char *text, size_t len)
{
struct console *con;
@ -1414,7 +1449,10 @@ static void call_console_drivers(int level, const char *text, size_t len)
if (!cpu_online(smp_processor_id()) &&
!(con->flags & CON_ANYTIME))
continue;
con->write(con, text, len);
if (con->flags & CON_EXTENDED)
con->write(con, ext_text, ext_len);
else
con->write(con, text, len);
}
}
@ -1557,8 +1595,12 @@ static bool cont_add(int facility, int level, const char *text, size_t len)
if (cont.len && cont.flushed)
return false;
if (cont.len + len > sizeof(cont.buf)) {
/* the line gets too long, split it up in separate records */
/*
* If ext consoles are present, flush and skip in-kernel
* continuation. See nr_ext_console_drivers definition. Also, if
* the line gets too long, split it up in separate records.
*/
if (nr_ext_console_drivers || cont.len + len > sizeof(cont.buf)) {
cont_flush(LOG_CONT);
return false;
}
@ -1893,9 +1935,19 @@ static struct cont {
u8 level;
bool flushed:1;
} cont;
static char *log_text(const struct printk_log *msg) { return NULL; }
static char *log_dict(const struct printk_log *msg) { return NULL; }
static struct printk_log *log_from_idx(u32 idx) { return NULL; }
static u32 log_next(u32 idx) { return 0; }
static void call_console_drivers(int level, const char *text, size_t len) {}
static ssize_t msg_print_ext_header(char *buf, size_t size,
struct printk_log *msg, u64 seq,
enum log_flags prev_flags) { return 0; }
static ssize_t msg_print_ext_body(char *buf, size_t size,
char *dict, size_t dict_len,
char *text, size_t text_len) { return 0; }
static void call_console_drivers(int level,
const char *ext_text, size_t ext_len,
const char *text, size_t len) {}
static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
bool syslog, char *buf, size_t size) { return 0; }
static size_t cont_print_text(char *text, size_t size) { return 0; }
@ -2148,7 +2200,7 @@ static void console_cont_flush(char *text, size_t size)
len = cont_print_text(text, size);
raw_spin_unlock(&logbuf_lock);
stop_critical_timings();
call_console_drivers(cont.level, text, len);
call_console_drivers(cont.level, NULL, 0, text, len);
start_critical_timings();
local_irq_restore(flags);
return;
@ -2172,6 +2224,7 @@ static void console_cont_flush(char *text, size_t size)
*/
void console_unlock(void)
{
static char ext_text[CONSOLE_EXT_LOG_MAX];
static char text[LOG_LINE_MAX + PREFIX_MAX];
static u64 seen_seq;
unsigned long flags;
@ -2190,6 +2243,7 @@ void console_unlock(void)
again:
for (;;) {
struct printk_log *msg;
size_t ext_len = 0;
size_t len;
int level;
@ -2235,13 +2289,22 @@ void console_unlock(void)
level = msg->level;
len += msg_print_text(msg, console_prev, false,
text + len, sizeof(text) - len);
if (nr_ext_console_drivers) {
ext_len = msg_print_ext_header(ext_text,
sizeof(ext_text),
msg, console_seq, console_prev);
ext_len += msg_print_ext_body(ext_text + ext_len,
sizeof(ext_text) - ext_len,
log_dict(msg), msg->dict_len,
log_text(msg), msg->text_len);
}
console_idx = log_next(console_idx);
console_seq++;
console_prev = msg->flags;
raw_spin_unlock(&logbuf_lock);
stop_critical_timings(); /* don't trace print latency */
call_console_drivers(level, text, len);
call_console_drivers(level, ext_text, ext_len, text, len);
start_critical_timings();
local_irq_restore(flags);
}
@ -2497,6 +2560,11 @@ void register_console(struct console *newcon)
newcon->next = console_drivers->next;
console_drivers->next = newcon;
}
if (newcon->flags & CON_EXTENDED)
if (!nr_ext_console_drivers++)
pr_info("printk: continuation disabled due to ext consoles, expect more fragments in /dev/kmsg\n");
if (newcon->flags & CON_PRINTBUFFER) {
/*
* console_unlock(); will print out the buffered messages
@ -2569,6 +2637,9 @@ int unregister_console(struct console *console)
}
}
if (!res && (console->flags & CON_EXTENDED))
nr_ext_console_drivers--;
/*
* If this isn't the last console and it has CON_CONSDEV set, we
* need to set it on the next preferred console.

View File

@ -1722,7 +1722,6 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
goto exit;
}
#ifdef CONFIG_CHECKPOINT_RESTORE
/*
* WARNING: we don't require any capability here so be very careful
* in what is allowed for modification from userspace.
@ -1818,6 +1817,7 @@ static int validate_prctl_map(struct prctl_mm_map *prctl_map)
return error;
}
#ifdef CONFIG_CHECKPOINT_RESTORE
static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data_size)
{
struct prctl_mm_map prctl_map = { .exe_fd = (u32)-1, };
@ -1902,10 +1902,41 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data
}
#endif /* CONFIG_CHECKPOINT_RESTORE */
static int prctl_set_auxv(struct mm_struct *mm, unsigned long addr,
unsigned long len)
{
/*
* This doesn't move the auxiliary vector itself since it's pinned to
* mm_struct, but it permits filling the vector with new values. It's
* up to the caller to provide sane values here, otherwise userspace
* tools which use this vector might be unhappy.
*/
unsigned long user_auxv[AT_VECTOR_SIZE];
if (len > sizeof(user_auxv))
return -EINVAL;
if (copy_from_user(user_auxv, (const void __user *)addr, len))
return -EFAULT;
/* Make sure the last entry is always AT_NULL */
user_auxv[AT_VECTOR_SIZE - 2] = 0;
user_auxv[AT_VECTOR_SIZE - 1] = 0;
BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
task_lock(current);
memcpy(mm->saved_auxv, user_auxv, len);
task_unlock(current);
return 0;
}
static int prctl_set_mm(int opt, unsigned long addr,
unsigned long arg4, unsigned long arg5)
{
struct mm_struct *mm = current->mm;
struct prctl_mm_map prctl_map;
struct vm_area_struct *vma;
int error;
@ -1925,6 +1956,9 @@ static int prctl_set_mm(int opt, unsigned long addr,
if (opt == PR_SET_MM_EXE_FILE)
return prctl_set_mm_exe_file(mm, (unsigned int)addr);
if (opt == PR_SET_MM_AUXV)
return prctl_set_auxv(mm, addr, arg4);
if (addr >= TASK_SIZE || addr < mmap_min_addr)
return -EINVAL;
@ -1933,42 +1967,64 @@ static int prctl_set_mm(int opt, unsigned long addr,
down_read(&mm->mmap_sem);
vma = find_vma(mm, addr);
prctl_map.start_code = mm->start_code;
prctl_map.end_code = mm->end_code;
prctl_map.start_data = mm->start_data;
prctl_map.end_data = mm->end_data;
prctl_map.start_brk = mm->start_brk;
prctl_map.brk = mm->brk;
prctl_map.start_stack = mm->start_stack;
prctl_map.arg_start = mm->arg_start;
prctl_map.arg_end = mm->arg_end;
prctl_map.env_start = mm->env_start;
prctl_map.env_end = mm->env_end;
prctl_map.auxv = NULL;
prctl_map.auxv_size = 0;
prctl_map.exe_fd = -1;
switch (opt) {
case PR_SET_MM_START_CODE:
mm->start_code = addr;
prctl_map.start_code = addr;
break;
case PR_SET_MM_END_CODE:
mm->end_code = addr;
prctl_map.end_code = addr;
break;
case PR_SET_MM_START_DATA:
mm->start_data = addr;
prctl_map.start_data = addr;
break;
case PR_SET_MM_END_DATA:
mm->end_data = addr;
prctl_map.end_data = addr;
break;
case PR_SET_MM_START_STACK:
prctl_map.start_stack = addr;
break;
case PR_SET_MM_START_BRK:
if (addr <= mm->end_data)
goto out;
if (check_data_rlimit(rlimit(RLIMIT_DATA), mm->brk, addr,
mm->end_data, mm->start_data))
goto out;
mm->start_brk = addr;
prctl_map.start_brk = addr;
break;
case PR_SET_MM_BRK:
if (addr <= mm->end_data)
goto out;
if (check_data_rlimit(rlimit(RLIMIT_DATA), addr, mm->start_brk,
mm->end_data, mm->start_data))
goto out;
mm->brk = addr;
prctl_map.brk = addr;
break;
case PR_SET_MM_ARG_START:
prctl_map.arg_start = addr;
break;
case PR_SET_MM_ARG_END:
prctl_map.arg_end = addr;
break;
case PR_SET_MM_ENV_START:
prctl_map.env_start = addr;
break;
case PR_SET_MM_ENV_END:
prctl_map.env_end = addr;
break;
default:
goto out;
}
error = validate_prctl_map(&prctl_map);
if (error)
goto out;
switch (opt) {
/*
* If command line arguments and environment
* are placed somewhere else on stack, we can
@ -1985,52 +2041,20 @@ static int prctl_set_mm(int opt, unsigned long addr,
error = -EFAULT;
goto out;
}
if (opt == PR_SET_MM_START_STACK)
mm->start_stack = addr;
else if (opt == PR_SET_MM_ARG_START)
mm->arg_start = addr;
else if (opt == PR_SET_MM_ARG_END)
mm->arg_end = addr;
else if (opt == PR_SET_MM_ENV_START)
mm->env_start = addr;
else if (opt == PR_SET_MM_ENV_END)
mm->env_end = addr;
break;
/*
* This doesn't move auxiliary vector itself
* since it's pinned to mm_struct, but allow
* to fill vector with new values. It's up
* to a caller to provide sane values here
* otherwise user space tools which use this
* vector might be unhappy.
*/
case PR_SET_MM_AUXV: {
unsigned long user_auxv[AT_VECTOR_SIZE];
if (arg4 > sizeof(user_auxv))
goto out;
up_read(&mm->mmap_sem);
if (copy_from_user(user_auxv, (const void __user *)addr, arg4))
return -EFAULT;
/* Make sure the last entry is always AT_NULL */
user_auxv[AT_VECTOR_SIZE - 2] = 0;
user_auxv[AT_VECTOR_SIZE - 1] = 0;
BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
task_lock(current);
memcpy(mm->saved_auxv, user_auxv, arg4);
task_unlock(current);
return 0;
}
default:
goto out;
}
mm->start_code = prctl_map.start_code;
mm->end_code = prctl_map.end_code;
mm->start_data = prctl_map.start_data;
mm->end_data = prctl_map.end_data;
mm->start_brk = prctl_map.start_brk;
mm->brk = prctl_map.brk;
mm->start_stack = prctl_map.start_stack;
mm->arg_start = prctl_map.arg_start;
mm->arg_end = prctl_map.arg_end;
mm->env_start = prctl_map.env_start;
mm->env_end = prctl_map.env_end;
error = 0;
out:
up_read(&mm->mmap_sem);

View File

@ -439,7 +439,7 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
{
struct blk_trace *old_bt, *bt = NULL;
struct dentry *dir = NULL;
int ret, i;
int ret;
if (!buts->buf_size || !buts->buf_nr)
return -EINVAL;
@ -451,9 +451,7 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
* some device names have larger paths - convert the slashes
* to underscores for this to work as expected
*/
for (i = 0; i < strlen(buts->name); i++)
if (buts->name[i] == '/')
buts->name[i] = '_';
strreplace(buts->name, '/', '_');
bt = kzalloc(sizeof(*bt), GFP_KERNEL);
if (!bt)

View File

@ -2082,7 +2082,7 @@ struct function_filter_data {
static char **
ftrace_function_filter_re(char *buf, int len, int *count)
{
char *str, *sep, **re;
char *str, **re;
str = kstrndup(buf, len, GFP_KERNEL);
if (!str)
@ -2092,8 +2092,7 @@ ftrace_function_filter_re(char *buf, int len, int *count)
* The argv_split function takes white space
* as a separator, so convert ',' into spaces.
*/
while ((sep = strchr(str, ',')))
*sep = ' ';
strreplace(str, ',', ' ');
re = argv_split(GFP_KERNEL, str, count);
kfree(str);

View File

@ -462,19 +462,20 @@ EXPORT_SYMBOL(bitmap_parse_user);
* Output format is a comma-separated list of decimal numbers and
* ranges if list is specified or hex digits grouped into comma-separated
* sets of 8 digits/set. Returns the number of characters written to buf.
*
* It is assumed that @buf is a pointer into a PAGE_SIZE area and that
* sufficient storage remains at @buf to accommodate the
* bitmap_print_to_pagebuf() output.
*/
int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp,
int nmaskbits)
{
ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf - 2;
ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
int n = 0;
if (len > 1) {
n = list ? scnprintf(buf, len, "%*pbl", nmaskbits, maskp) :
scnprintf(buf, len, "%*pb", nmaskbits, maskp);
buf[n++] = '\n';
buf[n] = '\0';
}
if (len > 1)
n = list ? scnprintf(buf, len, "%*pbl\n", nmaskbits, maskp) :
scnprintf(buf, len, "%*pb\n", nmaskbits, maskp);
return n;
}
EXPORT_SYMBOL(bitmap_print_to_pagebuf);
@ -506,12 +507,12 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
unsigned a, b;
int c, old_c, totaldigits;
const char __user __force *ubuf = (const char __user __force *)buf;
int exp_digit, in_range;
int at_start, in_range;
totaldigits = c = 0;
bitmap_zero(maskp, nmaskbits);
do {
exp_digit = 1;
at_start = 1;
in_range = 0;
a = b = 0;
@ -540,11 +541,10 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
break;
if (c == '-') {
if (exp_digit || in_range)
if (at_start || in_range)
return -EINVAL;
b = 0;
in_range = 1;
exp_digit = 1;
continue;
}
@ -554,16 +554,18 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
b = b * 10 + (c - '0');
if (!in_range)
a = b;
exp_digit = 0;
at_start = 0;
totaldigits++;
}
if (!(a <= b))
return -EINVAL;
if (b >= nmaskbits)
return -ERANGE;
while (a <= b) {
set_bit(a, maskp);
a++;
if (!at_start) {
while (a <= b) {
set_bit(a, maskp);
a++;
}
}
} while (buflen && c == ',');
return 0;

View File

@ -257,23 +257,20 @@ static int kobject_add_internal(struct kobject *kobj)
int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
va_list vargs)
{
const char *old_name = kobj->name;
char *s;
if (kobj->name && !fmt)
return 0;
kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs);
if (!kobj->name) {
kobj->name = old_name;
s = kvasprintf(GFP_KERNEL, fmt, vargs);
if (!s)
return -ENOMEM;
}
/* ewww... some of these buggers have '/' in the name ... */
while ((s = strchr(kobj->name, '/')))
s[0] = '!';
strreplace(s, '/', '!');
kfree(kobj->name);
kobj->name = s;
kfree(old_name);
return 0;
}

View File

@ -65,7 +65,8 @@ static struct kmem_cache *radix_tree_node_cachep;
*/
struct radix_tree_preload {
int nr;
struct radix_tree_node *nodes[RADIX_TREE_PRELOAD_SIZE];
/* nodes->private_data points to next preallocated node */
struct radix_tree_node *nodes;
};
static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
@ -197,8 +198,9 @@ radix_tree_node_alloc(struct radix_tree_root *root)
*/
rtp = this_cpu_ptr(&radix_tree_preloads);
if (rtp->nr) {
ret = rtp->nodes[rtp->nr - 1];
rtp->nodes[rtp->nr - 1] = NULL;
ret = rtp->nodes;
rtp->nodes = ret->private_data;
ret->private_data = NULL;
rtp->nr--;
}
/*
@ -257,17 +259,20 @@ static int __radix_tree_preload(gfp_t gfp_mask)
preempt_disable();
rtp = this_cpu_ptr(&radix_tree_preloads);
while (rtp->nr < ARRAY_SIZE(rtp->nodes)) {
while (rtp->nr < RADIX_TREE_PRELOAD_SIZE) {
preempt_enable();
node = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
if (node == NULL)
goto out;
preempt_disable();
rtp = this_cpu_ptr(&radix_tree_preloads);
if (rtp->nr < ARRAY_SIZE(rtp->nodes))
rtp->nodes[rtp->nr++] = node;
else
if (rtp->nr < RADIX_TREE_PRELOAD_SIZE) {
node->private_data = rtp->nodes;
rtp->nodes = node;
rtp->nr++;
} else {
kmem_cache_free(radix_tree_node_cachep, node);
}
}
ret = 0;
out:
@ -1463,15 +1468,16 @@ static int radix_tree_callback(struct notifier_block *nfb,
{
int cpu = (long)hcpu;
struct radix_tree_preload *rtp;
struct radix_tree_node *node;
/* Free per-cpu pool of perloaded nodes */
if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
rtp = &per_cpu(radix_tree_preloads, cpu);
while (rtp->nr) {
kmem_cache_free(radix_tree_node_cachep,
rtp->nodes[rtp->nr-1]);
rtp->nodes[rtp->nr-1] = NULL;
rtp->nr--;
node = rtp->nodes;
rtp->nodes = node->private_data;
kmem_cache_free(radix_tree_node_cachep, node);
rtp->nr--;
}
}
return NOTIFY_OK;

View File

@ -8,6 +8,12 @@
#include <linux/export.h>
#include <linux/sort.h>
static int alignment_ok(const void *base, int align)
{
return IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
((unsigned long)base & (align - 1)) == 0;
}
static void u32_swap(void *a, void *b, int size)
{
u32 t = *(u32 *)a;
@ -15,6 +21,13 @@ static void u32_swap(void *a, void *b, int size)
*(u32 *)b = t;
}
static void u64_swap(void *a, void *b, int size)
{
u64 t = *(u64 *)a;
*(u64 *)a = *(u64 *)b;
*(u64 *)b = t;
}
static void generic_swap(void *a, void *b, int size)
{
char t;
@ -50,8 +63,14 @@ void sort(void *base, size_t num, size_t size,
/* pre-scale counters for performance */
int i = (num/2 - 1) * size, n = num * size, c, r;
if (!swap_func)
swap_func = (size == 4 ? u32_swap : generic_swap);
if (!swap_func) {
if (size == 4 && alignment_ok(base, 4))
swap_func = u32_swap;
else if (size == 8 && alignment_ok(base, 8))
swap_func = u64_swap;
else
swap_func = generic_swap;
}
/* heapify */
for ( ; i >= 0; i -= size) {

View File

@ -849,3 +849,20 @@ void *memchr_inv(const void *start, int c, size_t bytes)
return check_bytes8(start, value, bytes % 8);
}
EXPORT_SYMBOL(memchr_inv);
/**
* strreplace - Replace all occurrences of character in string.
* @s: The string to operate on.
* @old: The character being replaced.
* @new: The character @old is replaced with.
*
* Returns pointer to the nul byte at the end of @s.
*/
char *strreplace(char *s, char old, char new)
{
for (; *s; ++s)
if (*s == old)
*s = new;
return s;
}
EXPORT_SYMBOL(strreplace);

View File

@ -25,19 +25,19 @@ static const char * const test_data_1_le[] __initconst = {
"4c", "d1", "19", "99", "43", "b1", "af", "0c",
};
static const char *test_data_2_le[] __initdata = {
static const char * const test_data_2_le[] __initconst = {
"32be", "7bdb", "180a", "b293",
"ba70", "24c4", "837d", "9b34",
"9ca6", "ad31", "0f9c", "e9ac",
"d14c", "9919", "b143", "0caf",
};
static const char *test_data_4_le[] __initdata = {
static const char * const test_data_4_le[] __initconst = {
"7bdb32be", "b293180a", "24c4ba70", "9b34837d",
"ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143",
};
static const char *test_data_8_le[] __initdata = {
static const char * const test_data_8_le[] __initconst = {
"b293180a7bdb32be", "9b34837d24c4ba70",
"e9ac0f9cad319ca6", "0cafb1439919d14c",
};

View File

@ -975,7 +975,6 @@ static void update_and_free_page(struct hstate *h, struct page *page)
destroy_compound_gigantic_page(page, huge_page_order(h));
free_gigantic_page(page, huge_page_order(h));
} else {
arch_release_hugepage(page);
__free_pages(page, huge_page_order(h));
}
}
@ -1160,10 +1159,6 @@ static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid)
__GFP_REPEAT|__GFP_NOWARN,
huge_page_order(h));
if (page) {
if (arch_prepare_hugepage(page)) {
__free_pages(page, huge_page_order(h));
return NULL;
}
prep_new_huge_page(h, page, nid);
}
@ -1315,11 +1310,6 @@ static struct page *alloc_buddy_huge_page(struct hstate *h, int nid)
htlb_alloc_mask(h)|__GFP_COMP|__GFP_THISNODE|
__GFP_REPEAT|__GFP_NOWARN, huge_page_order(h));
if (page && arch_prepare_hugepage(page)) {
__free_pages(page, huge_page_order(h));
page = NULL;
}
spin_lock(&hugetlb_lock);
if (page) {
INIT_LIST_HEAD(&page->lru);

View File

@ -6,7 +6,6 @@
#define KASAN_SHADOW_SCALE_SIZE (1UL << KASAN_SHADOW_SCALE_SHIFT)
#define KASAN_SHADOW_MASK (KASAN_SHADOW_SCALE_SIZE - 1)
#define KASAN_FREE_PAGE 0xFF /* page was freed */
#define KASAN_FREE_PAGE 0xFF /* page was freed */
#define KASAN_PAGE_REDZONE 0xFE /* redzone for kmalloc_large allocations */
#define KASAN_KMALLOC_REDZONE 0xFC /* redzone inside slub object */

View File

@ -97,6 +97,10 @@ struct zbud_pool {
struct list_head lru;
u64 pages_nr;
struct zbud_ops *ops;
#ifdef CONFIG_ZPOOL
struct zpool *zpool;
struct zpool_ops *zpool_ops;
#endif
};
/*
@ -123,7 +127,10 @@ struct zbud_header {
static int zbud_zpool_evict(struct zbud_pool *pool, unsigned long handle)
{
return zpool_evict(pool, handle);
if (pool->zpool && pool->zpool_ops && pool->zpool_ops->evict)
return pool->zpool_ops->evict(pool->zpool, handle);
else
return -ENOENT;
}
static struct zbud_ops zbud_zpool_ops = {
@ -131,9 +138,17 @@ static struct zbud_ops zbud_zpool_ops = {
};
static void *zbud_zpool_create(char *name, gfp_t gfp,
struct zpool_ops *zpool_ops)
struct zpool_ops *zpool_ops,
struct zpool *zpool)
{
return zbud_create_pool(gfp, zpool_ops ? &zbud_zpool_ops : NULL);
struct zbud_pool *pool;
pool = zbud_create_pool(gfp, zpool_ops ? &zbud_zpool_ops : NULL);
if (pool) {
pool->zpool = zpool;
pool->zpool_ops = zpool_ops;
}
return pool;
}
static void zbud_zpool_destroy(void *pool)
@ -292,7 +307,7 @@ struct zbud_pool *zbud_create_pool(gfp_t gfp, struct zbud_ops *ops)
struct zbud_pool *pool;
int i;
pool = kmalloc(sizeof(struct zbud_pool), gfp);
pool = kzalloc(sizeof(struct zbud_pool), gfp);
if (!pool)
return NULL;
spin_lock_init(&pool->lock);

View File

@ -73,33 +73,6 @@ int zpool_unregister_driver(struct zpool_driver *driver)
}
EXPORT_SYMBOL(zpool_unregister_driver);
/**
* zpool_evict() - evict callback from a zpool implementation.
* @pool: pool to evict from.
* @handle: handle to evict.
*
* This can be used by zpool implementations to call the
* user's evict zpool_ops struct evict callback.
*/
int zpool_evict(void *pool, unsigned long handle)
{
struct zpool *zpool;
spin_lock(&pools_lock);
list_for_each_entry(zpool, &pools_head, list) {
if (zpool->pool == pool) {
spin_unlock(&pools_lock);
if (!zpool->ops || !zpool->ops->evict)
return -EINVAL;
return zpool->ops->evict(zpool, handle);
}
}
spin_unlock(&pools_lock);
return -ENOENT;
}
EXPORT_SYMBOL(zpool_evict);
static struct zpool_driver *zpool_get_driver(char *type)
{
struct zpool_driver *driver;
@ -147,7 +120,7 @@ struct zpool *zpool_create_pool(char *type, char *name, gfp_t gfp,
struct zpool_driver *driver;
struct zpool *zpool;
pr_info("creating pool type %s\n", type);
pr_debug("creating pool type %s\n", type);
driver = zpool_get_driver(type);
@ -170,7 +143,7 @@ struct zpool *zpool_create_pool(char *type, char *name, gfp_t gfp,
zpool->type = driver->type;
zpool->driver = driver;
zpool->pool = driver->create(name, gfp, ops);
zpool->pool = driver->create(name, gfp, ops, zpool);
zpool->ops = ops;
if (!zpool->pool) {
@ -180,7 +153,7 @@ struct zpool *zpool_create_pool(char *type, char *name, gfp_t gfp,
return NULL;
}
pr_info("created %s pool\n", type);
pr_debug("created pool type %s\n", type);
spin_lock(&pools_lock);
list_add(&zpool->list, &pools_head);
@ -202,7 +175,7 @@ struct zpool *zpool_create_pool(char *type, char *name, gfp_t gfp,
*/
void zpool_destroy_pool(struct zpool *zpool)
{
pr_info("destroying pool type %s\n", zpool->type);
pr_debug("destroying pool type %s\n", zpool->type);
spin_lock(&pools_lock);
list_del(&zpool->list);

View File

@ -45,10 +45,6 @@
*
*/
#ifdef CONFIG_ZSMALLOC_DEBUG
#define DEBUG
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@ -313,7 +309,8 @@ static void record_obj(unsigned long handle, unsigned long obj)
#ifdef CONFIG_ZPOOL
static void *zs_zpool_create(char *name, gfp_t gfp, struct zpool_ops *zpool_ops)
static void *zs_zpool_create(char *name, gfp_t gfp, struct zpool_ops *zpool_ops,
struct zpool *zpool)
{
return zs_create_pool(name, gfp);
}

View File

@ -75,9 +75,10 @@ static u64 zswap_duplicate_entry;
/*********************************
* tunables
**********************************/
/* Enable/disable zswap (disabled by default, fixed at boot for now) */
static bool zswap_enabled __read_mostly;
module_param_named(enabled, zswap_enabled, bool, 0444);
/* Enable/disable zswap (disabled by default) */
static bool zswap_enabled;
module_param_named(enabled, zswap_enabled, bool, 0644);
/* Compressor to be used by zswap (fixed at boot for now) */
#define ZSWAP_COMPRESSOR_DEFAULT "lzo"
@ -648,7 +649,7 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
u8 *src, *dst;
struct zswap_header *zhdr;
if (!tree) {
if (!zswap_enabled || !tree) {
ret = -ENODEV;
goto reject;
}
@ -901,9 +902,6 @@ static int __init init_zswap(void)
{
gfp_t gfp = __GFP_NORETRY | __GFP_NOWARN;
if (!zswap_enabled)
return 0;
pr_info("loading zswap\n");
zswap_pool = zpool_create_pool(zswap_zpool_type, "zswap", gfp,

View File

@ -9,6 +9,7 @@ use strict;
use POSIX;
use File::Basename;
use Cwd 'abs_path';
use Term::ANSIColor qw(:constants);
my $P = $0;
my $D = dirname(abs_path($P));
@ -24,6 +25,7 @@ my $chk_patch = 1;
my $tst_only;
my $emacs = 0;
my $terse = 0;
my $showfile = 0;
my $file = 0;
my $check = 0;
my $check_orig = 0;
@ -48,7 +50,8 @@ my $minimum_perl_version = 5.10.0;
my $min_conf_desc_length = 4;
my $spelling_file = "$D/spelling.txt";
my $codespell = 0;
my $codespellfile = "/usr/local/share/codespell/dictionary.txt";
my $codespellfile = "/usr/share/codespell/dictionary.txt";
my $color = 1;
sub help {
my ($exitcode) = @_;
@ -64,6 +67,7 @@ Options:
--patch treat FILE as patchfile (default)
--emacs emacs compile window format
--terse one line per report
--showfile emit diffed file position, not input file position
-f, --file treat FILE as regular source file
--subjective, --strict enable more subjective tests
--types TYPE(,TYPE2...) show only these comma separated message types
@ -91,8 +95,9 @@ Options:
--ignore-perl-version override checking of perl version. expect
runtime errors.
--codespell Use the codespell dictionary for spelling/typos
(default:/usr/local/share/codespell/dictionary.txt)
(default:/usr/share/codespell/dictionary.txt)
--codespellfile Use this codespell dictionary
--color Use colors when output is STDOUT (default: on)
-h, --help, --version display this help and exit
When FILE is - read standard input.
@ -134,6 +139,7 @@ GetOptions(
'patch!' => \$chk_patch,
'emacs!' => \$emacs,
'terse!' => \$terse,
'showfile!' => \$showfile,
'f|file!' => \$file,
'subjective!' => \$check,
'strict!' => \$check,
@ -153,6 +159,7 @@ GetOptions(
'test-only=s' => \$tst_only,
'codespell!' => \$codespell,
'codespellfile=s' => \$codespellfile,
'color!' => \$color,
'h|help' => \$help,
'version' => \$help
) or help(1);
@ -196,12 +203,12 @@ sub hash_save_array_words {
sub hash_show_words {
my ($hashRef, $prefix) = @_;
if ($quiet == 0 && keys %$hashRef) {
print "NOTE: $prefix message types:";
if (keys %$hashRef) {
print "\nNOTE: $prefix message types:";
foreach my $word (sort keys %$hashRef) {
print " $word";
}
print "\n\n";
print "\n";
}
}
@ -347,15 +354,20 @@ our $UTF8 = qr{
| $NON_ASCII_UTF8
}x;
our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
our $typeOtherOSTypedefs = qr{(?x:
u_(?:char|short|int|long) | # bsd
u(?:nchar|short|int|long) # sysv
)};
our $typeTypedefs = qr{(?x:
our $typeKernelTypedefs = qr{(?x:
(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
atomic_t
)};
our $typeTypedefs = qr{(?x:
$typeC99Typedefs\b|
$typeOtherOSTypedefs\b|
$typeKernelTypedefs\b
)};
our $logFunctions = qr{(?x:
printk(?:_ratelimited|_once|)|
@ -418,6 +430,7 @@ our @typeList = (
qr{${Ident}_handler_fn},
@typeListMisordered,
);
our @typeListFile = ();
our @typeListWithAttr = (
@typeList,
qr{struct\s+$InitAttribute\s+$Ident},
@ -427,6 +440,7 @@ our @typeListWithAttr = (
our @modifierList = (
qr{fastcall},
);
our @modifierListFile = ();
our @mode_permission_funcs = (
["module_param", 3],
@ -510,13 +524,12 @@ if ($codespell) {
$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
sub build_types {
my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)";
my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)";
my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)";
my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)";
my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
$Modifier = qr{(?:$Attribute|$Sparse|$mods)};
$BasicType = qr{
(?:$typeOtherOSTypedefs\b)|
(?:$typeTypedefs\b)|
(?:${all}\b)
}x;
@ -524,7 +537,6 @@ sub build_types {
(?:$Modifier\s+|const\s+)*
(?:
(?:typeof|__typeof__)\s*\([^\)]*\)|
(?:$typeOtherOSTypedefs\b)|
(?:$typeTypedefs\b)|
(?:${all}\b)
)
@ -542,7 +554,6 @@ sub build_types {
(?:
(?:typeof|__typeof__)\s*\([^\)]*\)|
(?:$typeTypedefs\b)|
(?:$typeOtherOSTypedefs\b)|
(?:${allWithAttr}\b)
)
(?:\s+$Modifier|\s+const)*
@ -737,6 +748,13 @@ for my $filename (@ARGV) {
push(@rawlines, $_);
}
close($FILE);
if ($#ARGV > 0 && $quiet == 0) {
print '-' x length($vname) . "\n";
print "$vname\n";
print '-' x length($vname) . "\n";
}
if (!process($filename)) {
$exit = 1;
}
@ -746,6 +764,29 @@ for my $filename (@ARGV) {
@fixed_inserted = ();
@fixed_deleted = ();
$fixlinenr = -1;
@modifierListFile = ();
@typeListFile = ();
build_types();
}
if (!$quiet) {
hash_show_words(\%use_type, "Used");
hash_show_words(\%ignore_type, "Ignored");
if ($^V lt 5.10.0) {
print << "EOM"
NOTE: perl $^V is not modern enough to detect all possible issues.
An upgrade to at least perl v5.10.0 is suggested.
EOM
}
if ($exit) {
print << "EOM"
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
EOM
}
}
exit($exit);
@ -1001,7 +1042,7 @@ sub sanitise_line {
sub get_quoted_string {
my ($line, $rawline) = @_;
return "" if ($line !~ m/(\"[X\t]+\")/g);
return "" if ($line !~ m/($String)/g);
return substr($rawline, $-[0], $+[0] - $-[0]);
}
@ -1610,13 +1651,13 @@ sub possible {
for my $modifier (split(' ', $possible)) {
if ($modifier !~ $notPermitted) {
warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
push(@modifierList, $modifier);
push(@modifierListFile, $modifier);
}
}
} else {
warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
push(@typeList, $possible);
push(@typeListFile, $possible);
}
build_types();
} else {
@ -1641,15 +1682,32 @@ sub report {
(defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
return 0;
}
my $line;
if ($show_types) {
$line = "$prefix$level:$type: $msg\n";
} else {
$line = "$prefix$level: $msg\n";
my $output = '';
if (-t STDOUT && $color) {
if ($level eq 'ERROR') {
$output .= RED;
} elsif ($level eq 'WARNING') {
$output .= YELLOW;
} else {
$output .= GREEN;
}
}
$line = (split('\n', $line))[0] . "\n" if ($terse);
$output .= $prefix . $level . ':';
if ($show_types) {
$output .= BLUE if (-t STDOUT && $color);
$output .= "$type:";
}
$output .= RESET if (-t STDOUT && $color);
$output .= ' ' . $msg . "\n";
push(our @report, $line);
if ($showfile) {
my @lines = split("\n", $output, -1);
splice(@lines, 1, 1);
$output = join("\n", @lines);
}
$output = (split('\n', $output))[0] . "\n" if ($terse);
push(our @report, $output);
return 1;
}
@ -1899,6 +1957,7 @@ sub process {
my $in_header_lines = $file ? 0 : 1;
my $in_commit_log = 0; #Scanning lines before patch
my $commit_log_long_line = 0;
my $commit_log_has_diff = 0;
my $reported_maintainer_file = 0;
my $non_utf8_charset = 0;
@ -2032,7 +2091,8 @@ sub process {
my $rawline = $rawlines[$linenr - 1];
#extract the line range in the file after the patch is applied
if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
if (!$in_commit_log &&
$line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
$is_patch = 1;
$first_line = $linenr + 1;
$realline=$1-1;
@ -2073,10 +2133,6 @@ sub process {
my $hunk_line = ($realcnt != 0);
#make up the handle for any error we report on this line
$prefix = "$filename:$realline: " if ($emacs && $file);
$prefix = "$filename:$linenr: " if ($emacs && !$file);
$here = "#$linenr: " if (!$file);
$here = "#$realline: " if ($file);
@ -2106,6 +2162,13 @@ sub process {
$found_file = 1;
}
#make up the handle for any error we report on this line
if ($showfile) {
$prefix = "$realfile:$realline: "
} elsif ($emacs) {
$prefix = "$filename:$linenr: ";
}
if ($found_file) {
if ($realfile =~ m@^(drivers/net/|net/)@) {
$check = 1;
@ -2123,6 +2186,17 @@ sub process {
$cnt_lines++ if ($realcnt != 0);
# Check if the commit log has what seems like a diff which can confuse patch
if ($in_commit_log && !$commit_log_has_diff &&
(($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
$line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
$line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
$line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
ERROR("DIFF_IN_COMMIT_MSG",
"Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
$commit_log_has_diff = 1;
}
# Check for incorrect file permissions
if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
my $permhere = $here . "FILE: $realfile\n";
@ -2510,16 +2584,56 @@ sub process {
# check we are in a valid source file if not then ignore this hunk
next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/);
#line length limit
if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
$rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
!($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ ||
$line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
$line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) &&
$length > $max_line_length)
{
WARN("LONG_LINE",
"line over $max_line_length characters\n" . $herecurr);
# line length limit (with some exclusions)
#
# There are a few types of lines that may extend beyond $max_line_length:
# logging functions like pr_info that end in a string
# lines with a single string
# #defines that are a single string
#
# There are 3 different line length message types:
# LONG_LINE_COMMENT a comment starts before but extends beyond $max_linelength
# LONG_LINE_STRING a string starts before but extends beyond $max_line_length
# LONG_LINE all other lines longer than $max_line_length
#
# if LONG_LINE is ignored, the other 2 types are also ignored
#
if ($length > $max_line_length) {
my $msg_type = "LONG_LINE";
# Check the allowed long line types first
# logging functions that end in a string that starts
# before $max_line_length
if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
$msg_type = "";
# lines with only strings (w/ possible termination)
# #defines with only strings
} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
$line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
$msg_type = "";
# Otherwise set the alternate message types
# a comment starts before $max_line_length
} elsif ($line =~ /($;[\s$;]*)$/ &&
length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
$msg_type = "LONG_LINE_COMMENT"
# a quoted string starts before $max_line_length
} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
$msg_type = "LONG_LINE_STRING"
}
if ($msg_type ne "" &&
(show_type("LONG_LINE") || show_type($msg_type))) {
WARN($msg_type,
"line over $max_line_length characters\n" . $herecurr);
}
}
# check for adding lines without a newline.
@ -3264,7 +3378,6 @@ sub process {
$line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
$line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
$line !~ /\b$typeTypedefs\b/ &&
$line !~ /\b$typeOtherOSTypedefs\b/ &&
$line !~ /\b__bitwise(?:__|)\b/) {
WARN("NEW_TYPEDEFS",
"do not add new typedefs\n" . $herecurr);
@ -4337,8 +4450,8 @@ sub process {
}
# Flatten any obvious string concatentation.
while ($dstat =~ s/("X*")\s*$Ident/$1/ ||
$dstat =~ s/$Ident\s*("X*")/$1/)
while ($dstat =~ s/($String)\s*$Ident/$1/ ||
$dstat =~ s/$Ident\s*($String)/$1/)
{
}
@ -4619,7 +4732,7 @@ sub process {
# to grep for the string. Make exceptions when the previous string ends in a
# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
if ($line =~ /^\+\s*"[X\t]*"/ &&
if ($line =~ /^\+\s*$String/ &&
$prevline =~ /"\s*$/ &&
$prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
if (WARN("SPLIT_STRING",
@ -4665,13 +4778,13 @@ sub process {
}
# concatenated string without spaces between elements
if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) {
if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) {
CHK("CONCATENATED_STRING",
"Concatenated strings should use spaces between elements\n" . $herecurr);
}
# uncoalesced string fragments
if ($line =~ /"X*"\s*"/) {
if ($line =~ /$String\s*"/) {
WARN("STRING_FRAGMENTS",
"Consecutive strings are generally better as a single string\n" . $herecurr);
}
@ -4898,6 +5011,13 @@ sub process {
"memory barrier without comment\n" . $herecurr);
}
}
# check for waitqueue_active without a comment.
if ($line =~ /\bwaitqueue_active\s*\(/) {
if (!ctx_has_comment($first_line, $linenr)) {
WARN("WAITQUEUE_ACTIVE",
"waitqueue_active without comment\n" . $herecurr);
}
}
# check of hardware specific defines
if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
CHK("ARCH_DEFINES",
@ -4973,6 +5093,24 @@ sub process {
"Using weak declarations can have unintended link defects\n" . $herecurr);
}
# check for c99 types like uint8_t used outside of uapi/
if ($realfile !~ m@\binclude/uapi/@ &&
$line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
my $type = $1;
if ($type =~ /\b($typeC99Typedefs)\b/) {
$type = $1;
my $kernel_type = 'u';
$kernel_type = 's' if ($type =~ /^_*[si]/);
$type =~ /(\d+)/;
$kernel_type .= $1;
if (CHK("PREFER_KERNEL_TYPES",
"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
}
}
}
# check for sizeof(&)
if ($line =~ /\bsizeof\s*\(\s*\&/) {
WARN("SIZEOF_ADDRESS",
@ -5010,7 +5148,7 @@ sub process {
# Check for misused memsets
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
$stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) {
$stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
my $ms_addr = $2;
my $ms_val = $7;
@ -5027,14 +5165,46 @@ sub process {
# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
if ($^V && $^V ge 5.10.0 &&
$line =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/s) {
defined $stat &&
$stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
if (WARN("PREFER_ETHER_ADDR_COPY",
"Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . $herecurr) &&
"Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
$fix) {
$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
}
}
# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
$stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
WARN("PREFER_ETHER_ADDR_EQUAL",
"Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
}
# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
$stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
my $ms_val = $7;
if ($ms_val =~ /^(?:0x|)0+$/i) {
if (WARN("PREFER_ETH_ZERO_ADDR",
"Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
$fix) {
$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
}
} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
if (WARN("PREFER_ETH_BROADCAST_ADDR",
"Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
$fix) {
$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
}
}
}
# typecasts on min/max could be min_t/max_t
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
@ -5472,6 +5642,24 @@ sub process {
}
}
}
# validate content of MODULE_LICENSE against list from include/linux/module.h
if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
my $extracted_string = get_quoted_string($line, $rawline);
my $valid_licenses = qr{
GPL|
GPL\ v2|
GPL\ and\ additional\ rights|
Dual\ BSD/GPL|
Dual\ MIT/GPL|
Dual\ MPL/GPL|
Proprietary
}x;
if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
WARN("MODULE_LICENSE",
"unknown module license " . $extracted_string . "\n" . $herecurr);
}
}
}
# If we have no input at all, then there is nothing to report on
@ -5492,11 +5680,11 @@ sub process {
exit(0);
}
if (!$is_patch) {
if (!$is_patch && $file !~ /cover-letter\.patch$/) {
ERROR("NOT_UNIFIED_DIFF",
"Does not appear to be a unified-diff format patch\n");
}
if ($is_patch && $chk_signoff && $signoff == 0) {
if ($is_patch && $filename ne '-' && $chk_signoff && $signoff == 0) {
ERROR("MISSING_SIGN_OFF",
"Missing Signed-off-by: line(s)\n");
}
@ -5507,28 +5695,21 @@ sub process {
print "total: $cnt_error errors, $cnt_warn warnings, " .
(($check)? "$cnt_chk checks, " : "") .
"$cnt_lines lines checked\n";
print "\n" if ($quiet == 0);
}
if ($quiet == 0) {
if ($^V lt 5.10.0) {
print("NOTE: perl $^V is not modern enough to detect all possible issues.\n");
print("An upgrade to at least perl v5.10.0 is suggested.\n\n");
}
# If there were whitespace errors which cleanpatch can fix
# then suggest that.
if ($rpt_cleaners) {
print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
print " scripts/cleanfile\n\n";
$rpt_cleaners = 0;
print << "EOM"
NOTE: Whitespace errors detected.
You may wish to use scripts/cleanpatch or scripts/cleanfile
EOM
}
}
hash_show_words(\%use_type, "Used");
hash_show_words(\%ignore_type, "Ignored");
if ($clean == 0 && $fix &&
("@rawlines" ne "@fixed" ||
$#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
@ -5556,6 +5737,7 @@ sub process {
if (!$quiet) {
print << "EOM";
Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
Do _NOT_ trust the results written to this file.
@ -5563,22 +5745,17 @@ Do _NOT_ submit these changes without inspecting them for correctness.
This EXPERIMENTAL file is simply a convenience to help rewrite patches.
No warranties, expressed or implied...
EOM
}
}
if ($clean == 1 && $quiet == 0) {
print "$vname has no obvious style problems and is ready for submission.\n"
if ($quiet == 0) {
print "\n";
if ($clean == 1) {
print "$vname has no obvious style problems and is ready for submission.\n";
} else {
print "$vname has style problems, please review.\n";
}
}
if ($clean == 0 && $quiet == 0) {
print << "EOM";
$vname has style problems, please review.
If any of these errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
EOM
}
return $clean;
}

View File

@ -42,6 +42,7 @@ my $output_multiline = 1;
my $output_separator = ", ";
my $output_roles = 0;
my $output_rolestats = 1;
my $output_section_maxlen = 50;
my $scm = 0;
my $web = 0;
my $subsystem = 0;
@ -186,6 +187,27 @@ if (-f $conf) {
unshift(@ARGV, @conf_args) if @conf_args;
}
my @ignore_emails = ();
my $ignore_file = which_conf(".get_maintainer.ignore");
if (-f $ignore_file) {
open(my $ignore, '<', "$ignore_file")
or warn "$P: Can't find a readable .get_maintainer.ignore file $!\n";
while (<$ignore>) {
my $line = $_;
$line =~ s/\s*\n?$//;
$line =~ s/^\s*//;
$line =~ s/\s+$//;
$line =~ s/#.*$//;
next if ($line =~ m/^\s*$/);
if (rfc822_valid($line)) {
push(@ignore_emails, $line);
}
}
close($ignore);
}
if (!GetOptions(
'email!' => \$email,
'git!' => \$email_git,
@ -283,7 +305,7 @@ open (my $maint, '<', "${lk_path}MAINTAINERS")
while (<$maint>) {
my $line = $_;
if ($line =~ m/^(\C):\s*(.*)/) {
if ($line =~ m/^([A-Z]):\s*(.*)/) {
my $type = $1;
my $value = $2;
@ -513,12 +535,22 @@ if ($web) {
exit($exit);
sub ignore_email_address {
my ($address) = @_;
foreach my $ignore (@ignore_emails) {
return 1 if ($ignore eq $address);
}
return 0;
}
sub range_is_maintained {
my ($start, $end) = @_;
for (my $i = $start; $i < $end; $i++) {
my $line = $typevalue[$i];
if ($line =~ m/^(\C):\s*(.*)/) {
if ($line =~ m/^([A-Z]):\s*(.*)/) {
my $type = $1;
my $value = $2;
if ($type eq 'S') {
@ -536,7 +568,7 @@ sub range_has_maintainer {
for (my $i = $start; $i < $end; $i++) {
my $line = $typevalue[$i];
if ($line =~ m/^(\C):\s*(.*)/) {
if ($line =~ m/^([A-Z]):\s*(.*)/) {
my $type = $1;
my $value = $2;
if ($type eq 'M') {
@ -585,7 +617,7 @@ sub get_maintainers {
for ($i = $start; $i < $end; $i++) {
my $line = $typevalue[$i];
if ($line =~ m/^(\C):\s*(.*)/) {
if ($line =~ m/^([A-Z]):\s*(.*)/) {
my $type = $1;
my $value = $2;
if ($type eq 'X') {
@ -600,7 +632,7 @@ sub get_maintainers {
if (!$exclude) {
for ($i = $start; $i < $end; $i++) {
my $line = $typevalue[$i];
if ($line =~ m/^(\C):\s*(.*)/) {
if ($line =~ m/^([A-Z]):\s*(.*)/) {
my $type = $1;
my $value = $2;
if ($type eq 'F') {
@ -901,7 +933,7 @@ sub find_first_section {
while ($index < @typevalue) {
my $tv = $typevalue[$index];
if (($tv =~ m/^(\C):\s*(.*)/)) {
if (($tv =~ m/^([A-Z]):\s*(.*)/)) {
last;
}
$index++;
@ -915,7 +947,7 @@ sub find_starting_index {
while ($index > 0) {
my $tv = $typevalue[$index];
if (!($tv =~ m/^(\C):\s*(.*)/)) {
if (!($tv =~ m/^([A-Z]):\s*(.*)/)) {
last;
}
$index--;
@ -929,7 +961,7 @@ sub find_ending_index {
while ($index < @typevalue) {
my $tv = $typevalue[$index];
if (!($tv =~ m/^(\C):\s*(.*)/)) {
if (!($tv =~ m/^([A-Z]):\s*(.*)/)) {
last;
}
$index++;
@ -947,15 +979,15 @@ sub get_maintainer_role {
my $role = "unknown";
my $subsystem = $typevalue[$start];
if (length($subsystem) > 20) {
$subsystem = substr($subsystem, 0, 17);
if ($output_section_maxlen && length($subsystem) > $output_section_maxlen) {
$subsystem = substr($subsystem, 0, $output_section_maxlen - 3);
$subsystem =~ s/\s*$//;
$subsystem = $subsystem . "...";
}
for ($i = $start + 1; $i < $end; $i++) {
my $tv = $typevalue[$i];
if ($tv =~ m/^(\C):\s*(.*)/) {
if ($tv =~ m/^([A-Z]):\s*(.*)/) {
my $ptype = $1;
my $pvalue = $2;
if ($ptype eq "S") {
@ -990,8 +1022,8 @@ sub get_list_role {
my $end = find_ending_index($index);
my $subsystem = $typevalue[$start];
if (length($subsystem) > 20) {
$subsystem = substr($subsystem, 0, 17);
if ($output_section_maxlen && length($subsystem) > $output_section_maxlen) {
$subsystem = substr($subsystem, 0, $output_section_maxlen - 3);
$subsystem =~ s/\s*$//;
$subsystem = $subsystem . "...";
}
@ -1014,7 +1046,7 @@ sub add_categories {
for ($i = $start + 1; $i < $end; $i++) {
my $tv = $typevalue[$i];
if ($tv =~ m/^(\C):\s*(.*)/) {
if ($tv =~ m/^([A-Z]):\s*(.*)/) {
my $ptype = $1;
my $pvalue = $2;
if ($ptype eq "L") {
@ -1056,7 +1088,7 @@ sub add_categories {
if ($name eq "") {
if ($i > 0) {
my $tv = $typevalue[$i - 1];
if ($tv =~ m/^(\C):\s*(.*)/) {
if ($tv =~ m/^([A-Z]):\s*(.*)/) {
if ($1 eq "P") {
$name = $2;
$pvalue = format_email($name, $address, $email_usename);
@ -1073,7 +1105,7 @@ sub add_categories {
if ($name eq "") {
if ($i > 0) {
my $tv = $typevalue[$i - 1];
if ($tv =~ m/^(\C):\s*(.*)/) {
if ($tv =~ m/^([A-Z]):\s*(.*)/) {
if ($1 eq "P") {
$name = $2;
$pvalue = format_email($name, $address, $email_usename);
@ -1868,6 +1900,7 @@ sub vcs_assign {
my $percent = $sign_offs * 100 / $divisor;
$percent = 100 if ($percent > 100);
next if (ignore_email_address($line));
$count++;
last if ($sign_offs < $email_git_min_signatures ||
$count > $email_git_max_maintainers ||