提交 cb5629b1 编写于 作者: J James Morris

Merge branch 'master' into next

Conflicts:
	fs/namei.c

Manually merged per:

diff --cc fs/namei.c
index 734f2b5,bbc15c2..0000000
--- a/fs/namei.c
+++ b/fs/namei.c
@@@ -860,9 -848,8 +849,10 @@@ static int __link_path_walk(const char
  		nd->flags |= LOOKUP_CONTINUE;
  		err = exec_permission_lite(inode);
  		if (err == -EAGAIN)
- 			err = vfs_permission(nd, MAY_EXEC);
+ 			err = inode_permission(nd->path.dentry->d_inode,
+ 					       MAY_EXEC);
 +		if (!err)
 +			err = ima_path_check(&nd->path, MAY_EXEC);
   		if (err)
  			break;

@@@ -1525,14 -1506,9 +1509,14 @@@ int may_open(struct path *path, int acc
  		flag &= ~O_TRUNC;
  	}

- 	error = vfs_permission(nd, acc_mode);
+ 	error = inode_permission(inode, acc_mode);
  	if (error)
  		return error;
 +
- 	error = ima_path_check(&nd->path,
++	error = ima_path_check(path,
 +			       acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC));
 +	if (error)
 +		return error;
  	/*
  	 * An append-only file must be opened in append mode for writing.
  	 */
Signed-off-by: NJames Morris <jmorris@namei.org>

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
...@@ -32,6 +32,7 @@ Christoph Hellwig <hch@lst.de> ...@@ -32,6 +32,7 @@ Christoph Hellwig <hch@lst.de>
Corey Minyard <minyard@acm.org> Corey Minyard <minyard@acm.org>
David Brownell <david-b@pacbell.net> David Brownell <david-b@pacbell.net>
David Woodhouse <dwmw2@shinybook.infradead.org> David Woodhouse <dwmw2@shinybook.infradead.org>
Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Domen Puncer <domen@coderock.org> Domen Puncer <domen@coderock.org>
Douglas Gilbert <dougg@torque.net> Douglas Gilbert <dougg@torque.net>
Ed L. Cashin <ecashin@coraid.com> Ed L. Cashin <ecashin@coraid.com>
......
...@@ -369,10 +369,10 @@ P: 1024/8462A731 4C 55 86 34 44 59 A7 99 2B 97 88 4A 88 9A 0D 97 ...@@ -369,10 +369,10 @@ P: 1024/8462A731 4C 55 86 34 44 59 A7 99 2B 97 88 4A 88 9A 0D 97
D: sun4 port, Sparc hacker D: sun4 port, Sparc hacker
N: Hugh Blemings N: Hugh Blemings
E: hugh@misc.nu E: hugh@blemings.org
W: http://misc.nu/hugh/ W: http://blemings.org/hugh
D: Author and maintainer of the Keyspan USB to Serial drivers D: Original author of the Keyspan USB to serial drivers, random PowerPC hacker
S: Po Box 234 S: PO Box 234
S: Belconnen ACT 2616 S: Belconnen ACT 2616
S: Australia S: Australia
...@@ -464,6 +464,11 @@ S: 1200 Goldenrod Dr. ...@@ -464,6 +464,11 @@ S: 1200 Goldenrod Dr.
S: Nampa, Idaho 83686 S: Nampa, Idaho 83686
S: USA S: USA
N: Dirk J. Brandewie
E: dirk.j.brandewie@intel.com
E: linux-wimax@intel.com
D: Intel Wireless WiMAX Connection 2400 SDIO driver
N: Derrick J. Brashear N: Derrick J. Brashear
E: shadow@dementia.org E: shadow@dementia.org
W: http://www.dementia.org/~shadow W: http://www.dementia.org/~shadow
...@@ -1681,7 +1686,7 @@ E: ajoshi@shell.unixbox.com ...@@ -1681,7 +1686,7 @@ E: ajoshi@shell.unixbox.com
D: fbdev hacking D: fbdev hacking
N: Jesper Juhl N: Jesper Juhl
E: jesper.juhl@gmail.com E: jj@chaosbits.net
D: Various fixes, cleanups and minor features all over the tree. D: Various fixes, cleanups and minor features all over the tree.
D: Wrote initial version of the hdaps driver (since passed on to others). D: Wrote initial version of the hdaps driver (since passed on to others).
S: Lemnosvej 1, 3.tv S: Lemnosvej 1, 3.tv
...@@ -2119,6 +2124,11 @@ N: H.J. Lu ...@@ -2119,6 +2124,11 @@ N: H.J. Lu
E: hjl@gnu.ai.mit.edu E: hjl@gnu.ai.mit.edu
D: GCC + libraries hacker D: GCC + libraries hacker
N: Yanir Lubetkin
E: yanirx.lubatkin@intel.com
E: linux-wimax@intel.com
D: Intel Wireless WiMAX Connection 2400 driver
N: Michal Ludvig N: Michal Ludvig
E: michal@logix.cz E: michal@logix.cz
E: michal.ludvig@asterisk.co.nz E: michal.ludvig@asterisk.co.nz
...@@ -2693,6 +2703,13 @@ S: RR #5, 497 Pole Line Road ...@@ -2693,6 +2703,13 @@ S: RR #5, 497 Pole Line Road
S: Thunder Bay, Ontario S: Thunder Bay, Ontario
S: CANADA P7C 5M9 S: CANADA P7C 5M9
N: Inaky Perez-Gonzalez
E: inaky.perez-gonzalez@intel.com
E: linux-wimax@intel.com
E: inakypg@yahoo.com
D: WiMAX stack
D: Intel Wireless WiMAX Connection 2400 driver
N: Yuri Per N: Yuri Per
E: yuri@pts.mipt.ru E: yuri@pts.mipt.ru
D: Some smbfs fixes D: Some smbfs fixes
...@@ -3769,14 +3786,11 @@ S: The Netherlands ...@@ -3769,14 +3786,11 @@ S: The Netherlands
N: David Woodhouse N: David Woodhouse
E: dwmw2@infradead.org E: dwmw2@infradead.org
D: ARCnet stuff, Applicom board driver, SO_BINDTODEVICE, D: JFFS2 file system, Memory Technology Device subsystem,
D: some Alpha platform porting from 2.0, Memory Technology Devices,
D: Acquire watchdog timer, PC speaker driver maintenance,
D: various other stuff that annoyed me by not working. D: various other stuff that annoyed me by not working.
S: c/o Red Hat Engineering S: c/o Intel Corporation
S: Rustat House S: Pipers Way
S: 60 Clifton Road S: Swindon. SN3 1RJ
S: Cambridge. CB1 7EG
S: England S: England
N: Chris Wright N: Chris Wright
......
...@@ -3,8 +3,9 @@ Date: April 2008 ...@@ -3,8 +3,9 @@ Date: April 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
state. This holds the regulator output state. state. This reports the regulator enable status, for
regulators which can report that value.
This will be one of the following strings: This will be one of the following strings:
...@@ -18,7 +19,8 @@ Description: ...@@ -18,7 +19,8 @@ Description:
'disabled' means the regulator output is OFF and is not 'disabled' means the regulator output is OFF and is not
supplying power to the system.. supplying power to the system..
'unknown' means software cannot determine the state. 'unknown' means software cannot determine the state, or
the reported state is invalid.
NOTE: this field can be used in conjunction with microvolts NOTE: this field can be used in conjunction with microvolts
and microamps to determine regulator output levels. and microamps to determine regulator output levels.
...@@ -53,9 +55,10 @@ Date: April 2008 ...@@ -53,9 +55,10 @@ Date: April 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
microvolts. This holds the regulator output voltage setting microvolts. This holds the regulator output voltage setting
measured in microvolts (i.e. E-6 Volts). measured in microvolts (i.e. E-6 Volts), for regulators
which can report that voltage.
NOTE: This value should not be used to determine the regulator NOTE: This value should not be used to determine the regulator
output voltage level as this value is the same regardless of output voltage level as this value is the same regardless of
...@@ -67,9 +70,10 @@ Date: April 2008 ...@@ -67,9 +70,10 @@ Date: April 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
microamps. This holds the regulator output current limit microamps. This holds the regulator output current limit
setting measured in microamps (i.e. E-6 Amps). setting measured in microamps (i.e. E-6 Amps), for regulators
which can report that current.
NOTE: This value should not be used to determine the regulator NOTE: This value should not be used to determine the regulator
output current level as this value is the same regardless of output current level as this value is the same regardless of
...@@ -81,8 +85,9 @@ Date: April 2008 ...@@ -81,8 +85,9 @@ Date: April 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
opmode. This holds the regulator operating mode setting. opmode. This holds the current regulator operating mode,
for regulators which can report it.
The opmode value can be one of the following strings: The opmode value can be one of the following strings:
...@@ -92,7 +97,7 @@ Description: ...@@ -92,7 +97,7 @@ Description:
'standby' 'standby'
'unknown' 'unknown'
The modes are described in include/linux/regulator/regulator.h The modes are described in include/linux/regulator/consumer.h
NOTE: This value should not be used to determine the regulator NOTE: This value should not be used to determine the regulator
output operating mode as this value is the same regardless of output operating mode as this value is the same regardless of
...@@ -104,9 +109,10 @@ Date: April 2008 ...@@ -104,9 +109,10 @@ Date: April 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
min_microvolts. This holds the minimum safe working regulator min_microvolts. This holds the minimum safe working regulator
output voltage setting for this domain measured in microvolts. output voltage setting for this domain measured in microvolts,
for regulators which support voltage constraints.
NOTE: this will return the string 'constraint not defined' if NOTE: this will return the string 'constraint not defined' if
the power domain has no min microvolts constraint defined by the power domain has no min microvolts constraint defined by
...@@ -118,9 +124,10 @@ Date: April 2008 ...@@ -118,9 +124,10 @@ Date: April 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
max_microvolts. This holds the maximum safe working regulator max_microvolts. This holds the maximum safe working regulator
output voltage setting for this domain measured in microvolts. output voltage setting for this domain measured in microvolts,
for regulators which support voltage constraints.
NOTE: this will return the string 'constraint not defined' if NOTE: this will return the string 'constraint not defined' if
the power domain has no max microvolts constraint defined by the power domain has no max microvolts constraint defined by
...@@ -132,10 +139,10 @@ Date: April 2008 ...@@ -132,10 +139,10 @@ Date: April 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
min_microamps. This holds the minimum safe working regulator min_microamps. This holds the minimum safe working regulator
output current limit setting for this domain measured in output current limit setting for this domain measured in
microamps. microamps, for regulators which support current constraints.
NOTE: this will return the string 'constraint not defined' if NOTE: this will return the string 'constraint not defined' if
the power domain has no min microamps constraint defined by the power domain has no min microamps constraint defined by
...@@ -147,10 +154,10 @@ Date: April 2008 ...@@ -147,10 +154,10 @@ Date: April 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
max_microamps. This holds the maximum safe working regulator max_microamps. This holds the maximum safe working regulator
output current limit setting for this domain measured in output current limit setting for this domain measured in
microamps. microamps, for regulators which support current constraints.
NOTE: this will return the string 'constraint not defined' if NOTE: this will return the string 'constraint not defined' if
the power domain has no max microamps constraint defined by the power domain has no max microamps constraint defined by
...@@ -185,7 +192,7 @@ Date: April 2008 ...@@ -185,7 +192,7 @@ Date: April 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
requested_microamps. This holds the total requested load requested_microamps. This holds the total requested load
current in microamps for this regulator from all its consumer current in microamps for this regulator from all its consumer
devices. devices.
...@@ -204,125 +211,102 @@ Date: May 2008 ...@@ -204,125 +211,102 @@ Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
suspend_mem_microvolts. This holds the regulator output suspend_mem_microvolts. This holds the regulator output
voltage setting for this domain measured in microvolts when voltage setting for this domain measured in microvolts when
the system is suspended to memory. the system is suspended to memory, for voltage regulators
implementing suspend voltage configuration constraints.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to memory voltage defined by
platform code.
What: /sys/class/regulator/.../suspend_disk_microvolts What: /sys/class/regulator/.../suspend_disk_microvolts
Date: May 2008 Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
suspend_disk_microvolts. This holds the regulator output suspend_disk_microvolts. This holds the regulator output
voltage setting for this domain measured in microvolts when voltage setting for this domain measured in microvolts when
the system is suspended to disk. the system is suspended to disk, for voltage regulators
implementing suspend voltage configuration constraints.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to disk voltage defined by
platform code.
What: /sys/class/regulator/.../suspend_standby_microvolts What: /sys/class/regulator/.../suspend_standby_microvolts
Date: May 2008 Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
suspend_standby_microvolts. This holds the regulator output suspend_standby_microvolts. This holds the regulator output
voltage setting for this domain measured in microvolts when voltage setting for this domain measured in microvolts when
the system is suspended to standby. the system is suspended to standby, for voltage regulators
implementing suspend voltage configuration constraints.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to standby voltage defined by
platform code.
What: /sys/class/regulator/.../suspend_mem_mode What: /sys/class/regulator/.../suspend_mem_mode
Date: May 2008 Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
suspend_mem_mode. This holds the regulator operating mode suspend_mem_mode. This holds the regulator operating mode
setting for this domain when the system is suspended to setting for this domain when the system is suspended to
memory. memory, for regulators implementing suspend mode
configuration constraints.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to memory mode defined by
platform code.
What: /sys/class/regulator/.../suspend_disk_mode What: /sys/class/regulator/.../suspend_disk_mode
Date: May 2008 Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
suspend_disk_mode. This holds the regulator operating mode suspend_disk_mode. This holds the regulator operating mode
setting for this domain when the system is suspended to disk. setting for this domain when the system is suspended to disk,
for regulators implementing suspend mode configuration
NOTE: this will return the string 'not defined' if constraints.
the power domain has no suspend to disk mode defined by
platform code.
What: /sys/class/regulator/.../suspend_standby_mode What: /sys/class/regulator/.../suspend_standby_mode
Date: May 2008 Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
suspend_standby_mode. This holds the regulator operating mode suspend_standby_mode. This holds the regulator operating mode
setting for this domain when the system is suspended to setting for this domain when the system is suspended to
standby. standby, for regulators implementing suspend mode
configuration constraints.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to standby mode defined by
platform code.
What: /sys/class/regulator/.../suspend_mem_state What: /sys/class/regulator/.../suspend_mem_state
Date: May 2008 Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
suspend_mem_state. This holds the regulator operating state suspend_mem_state. This holds the regulator operating state
when suspended to memory. when suspended to memory, for regulators implementing suspend
configuration constraints.
This will be one of the following strings:
'enabled' This will be one of the same strings reported by
'disabled' the "state" attribute.
'not defined'
What: /sys/class/regulator/.../suspend_disk_state What: /sys/class/regulator/.../suspend_disk_state
Date: May 2008 Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
suspend_disk_state. This holds the regulator operating state suspend_disk_state. This holds the regulator operating state
when suspended to disk. when suspended to disk, for regulators implementing
suspend configuration constraints.
This will be one of the following strings:
'enabled' This will be one of the same strings reported by
'disabled' the "state" attribute.
'not defined'
What: /sys/class/regulator/.../suspend_standby_state What: /sys/class/regulator/.../suspend_standby_state
Date: May 2008 Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Each regulator directory will contain a field called Some regulator directories will contain a field called
suspend_standby_state. This holds the regulator operating suspend_standby_state. This holds the regulator operating
state when suspended to standby. state when suspended to standby, for regulators implementing
suspend configuration constraints.
This will be one of the following strings:
'enabled' This will be one of the same strings reported by
'disabled' the "state" attribute.
'not defined'
...@@ -32,14 +32,16 @@ Contact: linux-usb@vger.kernel.org ...@@ -32,14 +32,16 @@ Contact: linux-usb@vger.kernel.org
Description: Description:
Write: Write:
<channel> [<bpst offset>] <channel>
to start beaconing on a specific channel, or stop to force a specific channel to be used when beaconing,
beaconing if <channel> is -1. Valid channels depends or, if <channel> is -1, to prohibit beaconing. If
on the radio controller's supported band groups. <channel> is 0, then the default channel selection
algorithm will be used. Valid channels depends on the
radio controller's supported band groups.
<bpst offset> may be used to try and join a specific Reading returns the currently active channel, or -1 if
beacon group if more than one was found during a scan. the radio controller is not beaconing.
What: /sys/class/uwb_rc/uwbN/scan What: /sys/class/uwb_rc/uwbN/scan
Date: July 2008 Date: July 2008
......
...@@ -6,7 +6,6 @@ Description: ...@@ -6,7 +6,6 @@ Description:
internal state of the kernel memory blocks. Files could be internal state of the kernel memory blocks. Files could be
added or removed dynamically to represent hot-add/remove added or removed dynamically to represent hot-add/remove
operations. operations.
Users: hotplug memory add/remove tools Users: hotplug memory add/remove tools
https://w3.opensource.ibm.com/projects/powerpc-utils/ https://w3.opensource.ibm.com/projects/powerpc-utils/
...@@ -19,6 +18,56 @@ Description: ...@@ -19,6 +18,56 @@ Description:
This is useful for a user-level agent to determine This is useful for a user-level agent to determine
identify removable sections of the memory before attempting identify removable sections of the memory before attempting
potentially expensive hot-remove memory operation potentially expensive hot-remove memory operation
Users: hotplug memory remove tools
https://w3.opensource.ibm.com/projects/powerpc-utils/
What: /sys/devices/system/memory/memoryX/phys_device
Date: September 2008
Contact: Badari Pulavarty <pbadari@us.ibm.com>
Description:
The file /sys/devices/system/memory/memoryX/phys_device
is read-only and is designed to show the name of physical
memory device. Implementation is currently incomplete.
What: /sys/devices/system/memory/memoryX/phys_index
Date: September 2008
Contact: Badari Pulavarty <pbadari@us.ibm.com>
Description:
The file /sys/devices/system/memory/memoryX/phys_index
is read-only and contains the section ID in hexadecimal
which is equivalent to decimal X contained in the
memory section directory name.
What: /sys/devices/system/memory/memoryX/state
Date: September 2008
Contact: Badari Pulavarty <pbadari@us.ibm.com>
Description:
The file /sys/devices/system/memory/memoryX/state
is read-write. When read, it's contents show the
online/offline state of the memory section. When written,
root can toggle the the online/offline state of a removable
memory section (see removable file description above)
using the following commands.
# echo online > /sys/devices/system/memory/memoryX/state
# echo offline > /sys/devices/system/memory/memoryX/state
For example, if /sys/devices/system/memory/memory22/removable
contains a value of 1 and
/sys/devices/system/memory/memory22/state contains the
string "online" the following command can be executed by
by root to offline that section.
# echo offline > /sys/devices/system/memory/memory22/state
Users: hotplug memory remove tools Users: hotplug memory remove tools
https://w3.opensource.ibm.com/projects/powerpc-utils/ https://w3.opensource.ibm.com/projects/powerpc-utils/
What: /sys/devices/system/node/nodeX/memoryY
Date: September 2008
Contact: Gary Hade <garyhade@us.ibm.com>
Description:
When CONFIG_NUMA is enabled
/sys/devices/system/node/nodeX/memoryY is a symbolic link that
points to the corresponding /sys/devices/system/memory/memoryY
memory section directory. For example, the following symbolic
link is created for memory section 9 on node0.
/sys/devices/system/node/node0/memory9 -> ../../memory/memory9
...@@ -33,10 +33,12 @@ o Gnu make 3.79.1 # make --version ...@@ -33,10 +33,12 @@ o Gnu make 3.79.1 # make --version
o binutils 2.12 # ld -v o binutils 2.12 # ld -v
o util-linux 2.10o # fdformat --version o util-linux 2.10o # fdformat --version
o module-init-tools 0.9.10 # depmod -V o module-init-tools 0.9.10 # depmod -V
o e2fsprogs 1.29 # tune2fs o e2fsprogs 1.41.4 # e2fsck -V
o jfsutils 1.1.3 # fsck.jfs -V o jfsutils 1.1.3 # fsck.jfs -V
o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs
o xfsprogs 2.6.0 # xfs_db -V o xfsprogs 2.6.0 # xfs_db -V
o squashfs-tools 4.0 # mksquashfs -version
o btrfs-progs 0.18 # btrfsck
o pcmciautils 004 # pccardctl -V o pcmciautils 004 # pccardctl -V
o quota-tools 3.09 # quota -V o quota-tools 3.09 # quota -V
o PPP 2.4.0 # pppd --version o PPP 2.4.0 # pppd --version
......
...@@ -483,17 +483,25 @@ values. To do the latter, you can stick the following in your .emacs file: ...@@ -483,17 +483,25 @@ values. To do the latter, you can stick the following in your .emacs file:
(* (max steps 1) (* (max steps 1)
c-basic-offset))) c-basic-offset)))
(add-hook 'c-mode-common-hook
(lambda ()
;; Add kernel style
(c-add-style
"linux-tabs-only"
'("linux" (c-offsets-alist
(arglist-cont-nonempty
c-lineup-gcc-asm-reg
c-lineup-arglist-tabs-only))))))
(add-hook 'c-mode-hook (add-hook 'c-mode-hook
(lambda () (lambda ()
(let ((filename (buffer-file-name))) (let ((filename (buffer-file-name)))
;; Enable kernel mode for the appropriate files ;; Enable kernel mode for the appropriate files
(when (and filename (when (and filename
(string-match "~/src/linux-trees" filename)) (string-match (expand-file-name "~/src/linux-trees")
filename))
(setq indent-tabs-mode t) (setq indent-tabs-mode t)
(c-set-style "linux") (c-set-style "linux-tabs-only")))))
(c-set-offset 'arglist-cont-nonempty
'(c-lineup-gcc-asm-reg
c-lineup-arglist-tabs-only))))))
This will make emacs go better with the kernel coding style for C This will make emacs go better with the kernel coding style for C
files below ~/src/linux-trees. files below ~/src/linux-trees.
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
This document describes the DMA API. For a more gentle introduction This document describes the DMA API. For a more gentle introduction
phrased in terms of the pci_ equivalents (and actual examples) see phrased in terms of the pci_ equivalents (and actual examples) see
DMA-mapping.txt Documentation/PCI/PCI-DMA-mapping.txt.
This API is split into two pieces. Part I describes the API and the This API is split into two pieces. Part I describes the API and the
corresponding pci_ API. Part II describes the extensions to the API corresponding pci_ API. Part II describes the extensions to the API
...@@ -170,16 +170,15 @@ Returns: 0 if successful and a negative error if not. ...@@ -170,16 +170,15 @@ Returns: 0 if successful and a negative error if not.
u64 u64
dma_get_required_mask(struct device *dev) dma_get_required_mask(struct device *dev)
After setting the mask with dma_set_mask(), this API returns the This API returns the mask that the platform requires to
actual mask (within that already set) that the platform actually operate efficiently. Usually this means the returned mask
requires to operate efficiently. Usually this means the returned mask
is the minimum required to cover all of memory. Examining the is the minimum required to cover all of memory. Examining the
required mask gives drivers with variable descriptor sizes the required mask gives drivers with variable descriptor sizes the
opportunity to use smaller descriptors as necessary. opportunity to use smaller descriptors as necessary.
Requesting the required mask does not alter the current mask. If you Requesting the required mask does not alter the current mask. If you
wish to take advantage of it, you should issue another dma_set_mask() wish to take advantage of it, you should issue a dma_set_mask()
call to lower the mask again. call to set the mask to the value returned.
Part Id - Streaming DMA mappings Part Id - Streaming DMA mappings
......
...@@ -26,7 +26,7 @@ mapped only for the time they are actually used and unmapped after the DMA ...@@ -26,7 +26,7 @@ mapped only for the time they are actually used and unmapped after the DMA
transfer. transfer.
The following API will work of course even on platforms where no such The following API will work of course even on platforms where no such
hardware exists, see e.g. include/asm-i386/pci.h for how it is implemented on hardware exists, see e.g. arch/x86/include/asm/pci.h for how it is implemented on
top of the virt_to_bus interface. top of the virt_to_bus interface.
First of all, you should make sure First of all, you should make sure
......
...@@ -12,7 +12,7 @@ DOCBOOKS := z8530book.xml mcabook.xml \ ...@@ -12,7 +12,7 @@ DOCBOOKS := z8530book.xml mcabook.xml \
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
mac80211.xml debugobjects.xml sh.xml mac80211.xml debugobjects.xml sh.xml regulator.xml
### ###
# The build process is as follows (targets): # The build process is as follows (targets):
......
...@@ -74,6 +74,14 @@ ...@@ -74,6 +74,14 @@
!Enet/sunrpc/rpcb_clnt.c !Enet/sunrpc/rpcb_clnt.c
!Enet/sunrpc/clnt.c !Enet/sunrpc/clnt.c
</sect1> </sect1>
<sect1><title>WiMAX</title>
!Enet/wimax/op-msg.c
!Enet/wimax/op-reset.c
!Enet/wimax/op-rfkill.c
!Enet/wimax/stack.c
!Iinclude/net/wimax.h
!Iinclude/linux/wimax.h
</sect1>
</chapter> </chapter>
<chapter id="netdev"> <chapter id="netdev">
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<book id="regulator-api">
<bookinfo>
<title>Voltage and current regulator API</title>
<authorgroup>
<author>
<firstname>Liam</firstname>
<surname>Girdwood</surname>
<affiliation>
<address>
<email>lrg@slimlogic.co.uk</email>
</address>
</affiliation>
</author>
<author>
<firstname>Mark</firstname>
<surname>Brown</surname>
<affiliation>
<orgname>Wolfson Microelectronics</orgname>
<address>
<email>broonie@opensource.wolfsonmicro.com</email>
</address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2007-2008</year>
<holder>Wolfson Microelectronics</holder>
</copyright>
<copyright>
<year>2008</year>
<holder>Liam Girdwood</holder>
</copyright>
<legalnotice>
<para>
This documentation is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License version 2 as published by the Free Software Foundation.
</para>
<para>
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
</bookinfo>
<toc></toc>
<chapter id="intro">
<title>Introduction</title>
<para>
This framework is designed to provide a standard kernel
interface to control voltage and current regulators.
</para>
<para>
The intention is to allow systems to dynamically control
regulator power output in order to save power and prolong
battery life. This applies to both voltage regulators (where
voltage output is controllable) and current sinks (where current
limit is controllable).
</para>
<para>
Note that additional (and currently more complete) documentation
is available in the Linux kernel source under
<filename>Documentation/power/regulator</filename>.
</para>
<sect1 id="glossary">
<title>Glossary</title>
<para>
The regulator API uses a number of terms which may not be
familiar:
</para>
<glossary>
<glossentry>
<glossterm>Regulator</glossterm>
<glossdef>
<para>
Electronic device that supplies power to other devices. Most
regulators can enable and disable their output and some can also
control their output voltage or current.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Consumer</glossterm>
<glossdef>
<para>
Electronic device which consumes power provided by a regulator.
These may either be static, requiring only a fixed supply, or
dynamic, requiring active management of the regulator at
runtime.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Power Domain</glossterm>
<glossdef>
<para>
The electronic circuit supplied by a given regulator, including
the regulator and all consumer devices. The configuration of
the regulator is shared between all the components in the
circuit.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Power Management Integrated Circuit</glossterm>
<acronym>PMIC</acronym>
<glossdef>
<para>
An IC which contains numerous regulators and often also other
subsystems. In an embedded system the primary PMIC is often
equivalent to a combination of the PSU and southbridge in a
desktop system.
</para>
</glossdef>
</glossentry>
</glossary>
</sect1>
</chapter>
<chapter id="consumer">
<title>Consumer driver interface</title>
<para>
This offers a similar API to the kernel clock framework.
Consumer drivers use <link
linkend='API-regulator-get'>get</link> and <link
linkend='API-regulator-put'>put</link> operations to acquire and
release regulators. Functions are
provided to <link linkend='API-regulator-enable'>enable</link>
and <link linkend='API-regulator-disable'>disable</link> the
reguator and to get and set the runtime parameters of the
regulator.
</para>
<para>
When requesting regulators consumers use symbolic names for their
supplies, such as "Vcc", which are mapped into actual regulator
devices by the machine interface.
</para>
<para>
A stub version of this API is provided when the regulator
framework is not in use in order to minimise the need to use
ifdefs.
</para>
<sect1 id="consumer-enable">
<title>Enabling and disabling</title>
<para>
The regulator API provides reference counted enabling and
disabling of regulators. Consumer devices use the <function><link
linkend='API-regulator-enable'>regulator_enable</link></function>
and <function><link
linkend='API-regulator-disable'>regulator_disable</link>
</function> functions to enable and disable regulators. Calls
to the two functions must be balanced.
</para>
<para>
Note that since multiple consumers may be using a regulator and
machine constraints may not allow the regulator to be disabled
there is no guarantee that calling
<function>regulator_disable</function> will actually cause the
supply provided by the regulator to be disabled. Consumer
drivers should assume that the regulator may be enabled at all
times.
</para>
</sect1>
<sect1 id="consumer-config">
<title>Configuration</title>
<para>
Some consumer devices may need to be able to dynamically
configure their supplies. For example, MMC drivers may need to
select the correct operating voltage for their cards. This may
be done while the regulator is enabled or disabled.
</para>
<para>
The <function><link
linkend='API-regulator-set-voltage'>regulator_set_voltage</link>
</function> and <function><link
linkend='API-regulator-set-current-limit'
>regulator_set_current_limit</link>
</function> functions provide the primary interface for this.
Both take ranges of voltages and currents, supporting drivers
that do not require a specific value (eg, CPU frequency scaling
normally permits the CPU to use a wider range of supply
voltages at lower frequencies but does not require that the
supply voltage be lowered). Where an exact value is required
both minimum and maximum values should be identical.
</para>
</sect1>
<sect1 id="consumer-callback">
<title>Callbacks</title>
<para>
Callbacks may also be <link
linkend='API-regulator-register-notifier'>registered</link>
for events such as regulation failures.
</para>
</sect1>
</chapter>
<chapter id="driver">
<title>Regulator driver interface</title>
<para>
Drivers for regulator chips <link
linkend='API-regulator-register'>register</link> the regulators
with the regulator core, providing operations structures to the
core. A <link
linkend='API-regulator-notifier-call-chain'>notifier</link> interface
allows error conditions to be reported to the core.
</para>
<para>
Registration should be triggered by explicit setup done by the
platform, supplying a <link
linkend='API-struct-regulator-init-data'>struct
regulator_init_data</link> for the regulator containing
<link linkend='machine-constraint'>constraint</link> and
<link linkend='machine-supply'>supply</link> information.
</para>
</chapter>
<chapter id="machine">
<title>Machine interface</title>
<para>
This interface provides a way to define how regulators are
connected to consumers on a given system and what the valid
operating parameters are for the system.
</para>
<sect1 id="machine-supply">
<title>Supplies</title>
<para>
Regulator supplies are specified using <link
linkend='API-struct-regulator-consumer-supply'>struct
regulator_consumer_supply</link>. This is done at
<link linkend='driver'>driver registration
time</link> as part of the machine constraints.
</para>
</sect1>
<sect1 id="machine-constraint">
<title>Constraints</title>
<para>
As well as definining the connections the machine interface
also provides constraints definining the operations that
clients are allowed to perform and the parameters that may be
set. This is required since generally regulator devices will
offer more flexibility than it is safe to use on a given
system, for example supporting higher supply voltages than the
consumers are rated for.
</para>
<para>
This is done at <link linkend='driver'>driver
registration time</link> by providing a <link
linkend='API-struct-regulation-constraints'>struct
regulation_constraints</link>.
</para>
<para>
The constraints may also specify an initial configuration for the
regulator in the constraints, which is particularly useful for
use with static consumers.
</para>
</sect1>
</chapter>
<chapter id="api">
<title>API reference</title>
<para>
Due to limitations of the kernel documentation framework and the
existing layout of the source code the entire regulator API is
documented here.
</para>
!Iinclude/linux/regulator/consumer.h
!Iinclude/linux/regulator/machine.h
!Iinclude/linux/regulator/driver.h
!Edrivers/regulator/core.c
</chapter>
</book>
...@@ -41,6 +41,18 @@ GPL version 2. ...@@ -41,6 +41,18 @@ GPL version 2.
</abstract> </abstract>
<revhistory> <revhistory>
<revision>
<revnumber>0.7</revnumber>
<date>2008-12-23</date>
<authorinitials>hjk</authorinitials>
<revremark>Added generic platform drivers and offset attribute.</revremark>
</revision>
<revision>
<revnumber>0.6</revnumber>
<date>2008-12-05</date>
<authorinitials>hjk</authorinitials>
<revremark>Added description of portio sysfs attributes.</revremark>
</revision>
<revision> <revision>
<revnumber>0.5</revnumber> <revnumber>0.5</revnumber>
<date>2008-05-22</date> <date>2008-05-22</date>
...@@ -306,6 +318,16 @@ interested in translating it, please email me ...@@ -306,6 +318,16 @@ interested in translating it, please email me
pointed to by addr. pointed to by addr.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<filename>offset</filename>: The offset, in bytes, that has to be
added to the pointer returned by <function>mmap()</function> to get
to the actual device memory. This is important if the device's memory
is not page aligned. Remember that pointers returned by
<function>mmap()</function> are always page aligned, so it is good
style to always add this offset.
</para>
</listitem>
</itemizedlist> </itemizedlist>
<para> <para>
...@@ -318,6 +340,54 @@ interested in translating it, please email me ...@@ -318,6 +340,54 @@ interested in translating it, please email me
offset = N * getpagesize(); offset = N * getpagesize();
</programlisting> </programlisting>
<para>
Sometimes there is hardware with memory-like regions that can not be
mapped with the technique described here, but there are still ways to
access them from userspace. The most common example are x86 ioports.
On x86 systems, userspace can access these ioports using
<function>ioperm()</function>, <function>iopl()</function>,
<function>inb()</function>, <function>outb()</function>, and similar
functions.
</para>
<para>
Since these ioport regions can not be mapped, they will not appear under
<filename>/sys/class/uio/uioX/maps/</filename> like the normal memory
described above. Without information about the port regions a hardware
has to offer, it becomes difficult for the userspace part of the
driver to find out which ports belong to which UIO device.
</para>
<para>
To address this situation, the new directory
<filename>/sys/class/uio/uioX/portio/</filename> was added. It only
exists if the driver wants to pass information about one or more port
regions to userspace. If that is the case, subdirectories named
<filename>port0</filename>, <filename>port1</filename>, and so on,
will appear underneath
<filename>/sys/class/uio/uioX/portio/</filename>.
</para>
<para>
Each <filename>portX/</filename> directory contains three read-only
files that show start, size, and type of the port region:
</para>
<itemizedlist>
<listitem>
<para>
<filename>start</filename>: The first port of this region.
</para>
</listitem>
<listitem>
<para>
<filename>size</filename>: The number of ports in this region.
</para>
</listitem>
<listitem>
<para>
<filename>porttype</filename>: A string describing the type of port.
</para>
</listitem>
</itemizedlist>
</sect1> </sect1>
</chapter> </chapter>
...@@ -339,12 +409,12 @@ offset = N * getpagesize(); ...@@ -339,12 +409,12 @@ offset = N * getpagesize();
<itemizedlist> <itemizedlist>
<listitem><para> <listitem><para>
<varname>char *name</varname>: Required. The name of your driver as <varname>const char *name</varname>: Required. The name of your driver as
it will appear in sysfs. I recommend using the name of your module for this. it will appear in sysfs. I recommend using the name of your module for this.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
<varname>char *version</varname>: Required. This string appears in <varname>const char *version</varname>: Required. This string appears in
<filename>/sys/class/uio/uioX/version</filename>. <filename>/sys/class/uio/uioX/version</filename>.
</para></listitem> </para></listitem>
...@@ -355,6 +425,13 @@ mapping you need to fill one of the <varname>uio_mem</varname> structures. ...@@ -355,6 +425,13 @@ mapping you need to fill one of the <varname>uio_mem</varname> structures.
See the description below for details. See the description below for details.
</para></listitem> </para></listitem>
<listitem><para>
<varname>struct uio_port port[ MAX_UIO_PORTS_REGIONS ]</varname>: Required
if you want to pass information about ioports to userspace. For each port
region you need to fill one of the <varname>uio_port</varname> structures.
See the description below for details.
</para></listitem>
<listitem><para> <listitem><para>
<varname>long irq</varname>: Required. If your hardware generates an <varname>long irq</varname>: Required. If your hardware generates an
interrupt, it's your modules task to determine the irq number during interrupt, it's your modules task to determine the irq number during
...@@ -448,6 +525,42 @@ Please do not touch the <varname>kobj</varname> element of ...@@ -448,6 +525,42 @@ Please do not touch the <varname>kobj</varname> element of
<varname>struct uio_mem</varname>! It is used by the UIO framework <varname>struct uio_mem</varname>! It is used by the UIO framework
to set up sysfs files for this mapping. Simply leave it alone. to set up sysfs files for this mapping. Simply leave it alone.
</para> </para>
<para>
Sometimes, your device can have one or more port regions which can not be
mapped to userspace. But if there are other possibilities for userspace to
access these ports, it makes sense to make information about the ports
available in sysfs. For each region, you have to set up a
<varname>struct uio_port</varname> in the <varname>port[]</varname> array.
Here's a description of the fields of <varname>struct uio_port</varname>:
</para>
<itemizedlist>
<listitem><para>
<varname>char *porttype</varname>: Required. Set this to one of the predefined
constants. Use <varname>UIO_PORT_X86</varname> for the ioports found in x86
architectures.
</para></listitem>
<listitem><para>
<varname>unsigned long start</varname>: Required if the port region is used.
Fill in the number of the first port of this region.
</para></listitem>
<listitem><para>
<varname>unsigned long size</varname>: Fill in the number of ports in this
region. If <varname>size</varname> is zero, the region is considered unused.
Note that you <emphasis>must</emphasis> initialize <varname>size</varname>
with zero for all unused regions.
</para></listitem>
</itemizedlist>
<para>
Please do not touch the <varname>portio</varname> element of
<varname>struct uio_port</varname>! It is used internally by the UIO
framework to set up sysfs files for this region. Simply leave it alone.
</para>
</sect1> </sect1>
<sect1 id="adding_irq_handler"> <sect1 id="adding_irq_handler">
...@@ -497,6 +610,78 @@ to set up sysfs files for this mapping. Simply leave it alone. ...@@ -497,6 +610,78 @@ to set up sysfs files for this mapping. Simply leave it alone.
</para> </para>
</sect1> </sect1>
<sect1 id="using_uio_pdrv">
<title>Using uio_pdrv for platform devices</title>
<para>
In many cases, UIO drivers for platform devices can be handled in a
generic way. In the same place where you define your
<varname>struct platform_device</varname>, you simply also implement
your interrupt handler and fill your
<varname>struct uio_info</varname>. A pointer to this
<varname>struct uio_info</varname> is then used as
<varname>platform_data</varname> for your platform device.
</para>
<para>
You also need to set up an array of <varname>struct resource</varname>
containing addresses and sizes of your memory mappings. This
information is passed to the driver using the
<varname>.resource</varname> and <varname>.num_resources</varname>
elements of <varname>struct platform_device</varname>.
</para>
<para>
You now have to set the <varname>.name</varname> element of
<varname>struct platform_device</varname> to
<varname>"uio_pdrv"</varname> to use the generic UIO platform device
driver. This driver will fill the <varname>mem[]</varname> array
according to the resources given, and register the device.
</para>
<para>
The advantage of this approach is that you only have to edit a file
you need to edit anyway. You do not have to create an extra driver.
</para>
</sect1>
<sect1 id="using_uio_pdrv_genirq">
<title>Using uio_pdrv_genirq for platform devices</title>
<para>
Especially in embedded devices, you frequently find chips where the
irq pin is tied to its own dedicated interrupt line. In such cases,
where you can be really sure the interrupt is not shared, we can take
the concept of <varname>uio_pdrv</varname> one step further and use a
generic interrupt handler. That's what
<varname>uio_pdrv_genirq</varname> does.
</para>
<para>
The setup for this driver is the same as described above for
<varname>uio_pdrv</varname>, except that you do not implement an
interrupt handler. The <varname>.handler</varname> element of
<varname>struct uio_info</varname> must remain
<varname>NULL</varname>. The <varname>.irq_flags</varname> element
must not contain <varname>IRQF_SHARED</varname>.
</para>
<para>
You will set the <varname>.name</varname> element of
<varname>struct platform_device</varname> to
<varname>"uio_pdrv_genirq"</varname> to use this driver.
</para>
<para>
The generic interrupt handler of <varname>uio_pdrv_genirq</varname>
will simply disable the interrupt line using
<function>disable_irq_nosync()</function>. After doing its work,
userspace can reenable the interrupt by writing 0x00000001 to the UIO
device file. The driver already implements an
<function>irq_control()</function> to make this possible, you must not
implement your own.
</para>
<para>
Using <varname>uio_pdrv_genirq</varname> not only saves a few lines of
interrupt handler code. You also do not need to know anything about
the chip's internal registers to create the kernel part of the driver.
All you need to know is the irq number of the pin the chip is
connected to.
</para>
</sect1>
</chapter> </chapter>
<chapter id="userspace_driver" xreflabel="Writing a driver in user space"> <chapter id="userspace_driver" xreflabel="Writing a driver in user space">
......
[ NOTE: The virt_to_bus() and bus_to_virt() functions have been [ NOTE: The virt_to_bus() and bus_to_virt() functions have been
superseded by the functionality provided by the PCI DMA superseded by the functionality provided by the PCI DMA interface
interface (see Documentation/DMA-mapping.txt). They continue (see Documentation/PCI/PCI-DMA-mapping.txt). They continue
to be documented below for historical purposes, but new code to be documented below for historical purposes, but new code
must not use them. --davidm 00/12/12 ] must not use them. --davidm 00/12/12 ]
......
...@@ -294,7 +294,8 @@ NOTE: pci_enable_device() can fail! Check the return value. ...@@ -294,7 +294,8 @@ NOTE: pci_enable_device() can fail! Check the return value.
pci_set_master() will enable DMA by setting the bus master bit pci_set_master() will enable DMA by setting the bus master bit
in the PCI_COMMAND register. It also fixes the latency timer value if in the PCI_COMMAND register. It also fixes the latency timer value if
it's set to something bogus by the BIOS. it's set to something bogus by the BIOS. pci_clear_master() will
disable DMA by clearing the bus master bit.
If the PCI device can use the PCI Memory-Write-Invalidate transaction, If the PCI device can use the PCI Memory-Write-Invalidate transaction,
call pci_set_mwi(). This enables the PCI_COMMAND bit for Mem-Wr-Inval call pci_set_mwi(). This enables the PCI_COMMAND bit for Mem-Wr-Inval
......
...@@ -12,6 +12,8 @@ rcuref.txt ...@@ -12,6 +12,8 @@ rcuref.txt
- Reference-count design for elements of lists/arrays protected by RCU - Reference-count design for elements of lists/arrays protected by RCU
rcu.txt rcu.txt
- RCU Concepts - RCU Concepts
rcubarrier.txt
- Unloading modules that use RCU callbacks
RTFP.txt RTFP.txt
- List of RCU papers (bibliography) going back to 1980. - List of RCU papers (bibliography) going back to 1980.
torture.txt torture.txt
......
RCU and Unloadable Modules
[Originally published in LWN Jan. 14, 2007: http://lwn.net/Articles/217484/]
RCU (read-copy update) is a synchronization mechanism that can be thought
of as a replacement for read-writer locking (among other things), but with
very low-overhead readers that are immune to deadlock, priority inversion,
and unbounded latency. RCU read-side critical sections are delimited
by rcu_read_lock() and rcu_read_unlock(), which, in non-CONFIG_PREEMPT
kernels, generate no code whatsoever.
This means that RCU writers are unaware of the presence of concurrent
readers, so that RCU updates to shared data must be undertaken quite
carefully, leaving an old version of the data structure in place until all
pre-existing readers have finished. These old versions are needed because
such readers might hold a reference to them. RCU updates can therefore be
rather expensive, and RCU is thus best suited for read-mostly situations.
How can an RCU writer possibly determine when all readers are finished,
given that readers might well leave absolutely no trace of their
presence? There is a synchronize_rcu() primitive that blocks until all
pre-existing readers have completed. An updater wishing to delete an
element p from a linked list might do the following, while holding an
appropriate lock, of course:
list_del_rcu(p);
synchronize_rcu();
kfree(p);
But the above code cannot be used in IRQ context -- the call_rcu()
primitive must be used instead. This primitive takes a pointer to an
rcu_head struct placed within the RCU-protected data structure and
another pointer to a function that may be invoked later to free that
structure. Code to delete an element p from the linked list from IRQ
context might then be as follows:
list_del_rcu(p);
call_rcu(&p->rcu, p_callback);
Since call_rcu() never blocks, this code can safely be used from within
IRQ context. The function p_callback() might be defined as follows:
static void p_callback(struct rcu_head *rp)
{
struct pstruct *p = container_of(rp, struct pstruct, rcu);
kfree(p);
}
Unloading Modules That Use call_rcu()
But what if p_callback is defined in an unloadable module?
If we unload the module while some RCU callbacks are pending,
the CPUs executing these callbacks are going to be severely
disappointed when they are later invoked, as fancifully depicted at
http://lwn.net/images/ns/kernel/rcu-drop.jpg.
We could try placing a synchronize_rcu() in the module-exit code path,
but this is not sufficient. Although synchronize_rcu() does wait for a
grace period to elapse, it does not wait for the callbacks to complete.
One might be tempted to try several back-to-back synchronize_rcu()
calls, but this is still not guaranteed to work. If there is a very
heavy RCU-callback load, then some of the callbacks might be deferred
in order to allow other processing to proceed. Such deferral is required
in realtime kernels in order to avoid excessive scheduling latencies.
rcu_barrier()
We instead need the rcu_barrier() primitive. This primitive is similar
to synchronize_rcu(), but instead of waiting solely for a grace
period to elapse, it also waits for all outstanding RCU callbacks to
complete. Pseudo-code using rcu_barrier() is as follows:
1. Prevent any new RCU callbacks from being posted.
2. Execute rcu_barrier().
3. Allow the module to be unloaded.
Quick Quiz #1: Why is there no srcu_barrier()?
The rcutorture module makes use of rcu_barrier in its exit function
as follows:
1 static void
2 rcu_torture_cleanup(void)
3 {
4 int i;
5
6 fullstop = 1;
7 if (shuffler_task != NULL) {
8 VERBOSE_PRINTK_STRING("Stopping rcu_torture_shuffle task");
9 kthread_stop(shuffler_task);
10 }
11 shuffler_task = NULL;
12
13 if (writer_task != NULL) {
14 VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
15 kthread_stop(writer_task);
16 }
17 writer_task = NULL;
18
19 if (reader_tasks != NULL) {
20 for (i = 0; i < nrealreaders; i++) {
21 if (reader_tasks[i] != NULL) {
22 VERBOSE_PRINTK_STRING(
23 "Stopping rcu_torture_reader task");
24 kthread_stop(reader_tasks[i]);
25 }
26 reader_tasks[i] = NULL;
27 }
28 kfree(reader_tasks);
29 reader_tasks = NULL;
30 }
31 rcu_torture_current = NULL;
32
33 if (fakewriter_tasks != NULL) {
34 for (i = 0; i < nfakewriters; i++) {
35 if (fakewriter_tasks[i] != NULL) {
36 VERBOSE_PRINTK_STRING(
37 "Stopping rcu_torture_fakewriter task");
38 kthread_stop(fakewriter_tasks[i]);
39 }
40 fakewriter_tasks[i] = NULL;
41 }
42 kfree(fakewriter_tasks);
43 fakewriter_tasks = NULL;
44 }
45
46 if (stats_task != NULL) {
47 VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
48 kthread_stop(stats_task);
49 }
50 stats_task = NULL;
51
52 /* Wait for all RCU callbacks to fire. */
53 rcu_barrier();
54
55 rcu_torture_stats_print(); /* -After- the stats thread is stopped! */
56
57 if (cur_ops->cleanup != NULL)
58 cur_ops->cleanup();
59 if (atomic_read(&n_rcu_torture_error))
60 rcu_torture_print_module_parms("End of test: FAILURE");
61 else
62 rcu_torture_print_module_parms("End of test: SUCCESS");
63 }
Line 6 sets a global variable that prevents any RCU callbacks from
re-posting themselves. This will not be necessary in most cases, since
RCU callbacks rarely include calls to call_rcu(). However, the rcutorture
module is an exception to this rule, and therefore needs to set this
global variable.
Lines 7-50 stop all the kernel tasks associated with the rcutorture
module. Therefore, once execution reaches line 53, no more rcutorture
RCU callbacks will be posted. The rcu_barrier() call on line 53 waits
for any pre-existing callbacks to complete.
Then lines 55-62 print status and do operation-specific cleanup, and
then return, permitting the module-unload operation to be completed.
Quick Quiz #2: Is there any other situation where rcu_barrier() might
be required?
Your module might have additional complications. For example, if your
module invokes call_rcu() from timers, you will need to first cancel all
the timers, and only then invoke rcu_barrier() to wait for any remaining
RCU callbacks to complete.
Implementing rcu_barrier()
Dipankar Sarma's implementation of rcu_barrier() makes use of the fact
that RCU callbacks are never reordered once queued on one of the per-CPU
queues. His implementation queues an RCU callback on each of the per-CPU
callback queues, and then waits until they have all started executing, at
which point, all earlier RCU callbacks are guaranteed to have completed.
The original code for rcu_barrier() was as follows:
1 void rcu_barrier(void)
2 {
3 BUG_ON(in_interrupt());
4 /* Take cpucontrol mutex to protect against CPU hotplug */
5 mutex_lock(&rcu_barrier_mutex);
6 init_completion(&rcu_barrier_completion);
7 atomic_set(&rcu_barrier_cpu_count, 0);
8 on_each_cpu(rcu_barrier_func, NULL, 0, 1);
9 wait_for_completion(&rcu_barrier_completion);
10 mutex_unlock(&rcu_barrier_mutex);
11 }
Line 3 verifies that the caller is in process context, and lines 5 and 10
use rcu_barrier_mutex to ensure that only one rcu_barrier() is using the
global completion and counters at a time, which are initialized on lines
6 and 7. Line 8 causes each CPU to invoke rcu_barrier_func(), which is
shown below. Note that the final "1" in on_each_cpu()'s argument list
ensures that all the calls to rcu_barrier_func() will have completed
before on_each_cpu() returns. Line 9 then waits for the completion.
This code was rewritten in 2008 to support rcu_barrier_bh() and
rcu_barrier_sched() in addition to the original rcu_barrier().
The rcu_barrier_func() runs on each CPU, where it invokes call_rcu()
to post an RCU callback, as follows:
1 static void rcu_barrier_func(void *notused)
2 {
3 int cpu = smp_processor_id();
4 struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
5 struct rcu_head *head;
6
7 head = &rdp->barrier;
8 atomic_inc(&rcu_barrier_cpu_count);
9 call_rcu(head, rcu_barrier_callback);
10 }
Lines 3 and 4 locate RCU's internal per-CPU rcu_data structure,
which contains the struct rcu_head that needed for the later call to
call_rcu(). Line 7 picks up a pointer to this struct rcu_head, and line
8 increments a global counter. This counter will later be decremented
by the callback. Line 9 then registers the rcu_barrier_callback() on
the current CPU's queue.
The rcu_barrier_callback() function simply atomically decrements the
rcu_barrier_cpu_count variable and finalizes the completion when it
reaches zero, as follows:
1 static void rcu_barrier_callback(struct rcu_head *notused)
2 {
3 if (atomic_dec_and_test(&rcu_barrier_cpu_count))
4 complete(&rcu_barrier_completion);
5 }
Quick Quiz #3: What happens if CPU 0's rcu_barrier_func() executes
immediately (thus incrementing rcu_barrier_cpu_count to the
value one), but the other CPU's rcu_barrier_func() invocations
are delayed for a full grace period? Couldn't this result in
rcu_barrier() returning prematurely?
rcu_barrier() Summary
The rcu_barrier() primitive has seen relatively little use, since most
code using RCU is in the core kernel rather than in modules. However, if
you are using RCU from an unloadable module, you need to use rcu_barrier()
so that your module may be safely unloaded.
Answers to Quick Quizzes
Quick Quiz #1: Why is there no srcu_barrier()?
Answer: Since there is no call_srcu(), there can be no outstanding SRCU
callbacks. Therefore, there is no need to wait for them.
Quick Quiz #2: Is there any other situation where rcu_barrier() might
be required?
Answer: Interestingly enough, rcu_barrier() was not originally
implemented for module unloading. Nikita Danilov was using
RCU in a filesystem, which resulted in a similar situation at
filesystem-unmount time. Dipankar Sarma coded up rcu_barrier()
in response, so that Nikita could invoke it during the
filesystem-unmount process.
Much later, yours truly hit the RCU module-unload problem when
implementing rcutorture, and found that rcu_barrier() solves
this problem as well.
Quick Quiz #3: What happens if CPU 0's rcu_barrier_func() executes
immediately (thus incrementing rcu_barrier_cpu_count to the
value one), but the other CPU's rcu_barrier_func() invocations
are delayed for a full grace period? Couldn't this result in
rcu_barrier() returning prematurely?
Answer: This cannot happen. The reason is that on_each_cpu() has its last
argument, the wait flag, set to "1". This flag is passed through
to smp_call_function() and further to smp_call_function_on_cpu(),
causing this latter to spin until the cross-CPU invocation of
rcu_barrier_func() has completed. This by itself would prevent
a grace period from completing on non-CONFIG_PREEMPT kernels,
since each CPU must undergo a context switch (or other quiescent
state) before the grace period can complete. However, this is
of no use in CONFIG_PREEMPT kernels.
Therefore, on_each_cpu() disables preemption across its call
to smp_call_function() and also across the local call to
rcu_barrier_func(). This prevents the local CPU from context
switching, again preventing grace periods from completing. This
means that all CPUs have executed rcu_barrier_func() before
the first rcu_barrier_callback() can possibly execute, in turn
preventing rcu_barrier_cpu_count from prematurely reaching zero.
Currently, -rt implementations of RCU keep but a single global
queue for RCU callbacks, and thus do not suffer from this
problem. However, when the -rt RCU eventually does have per-CPU
callback queues, things will have to change. One simple change
is to add an rcu_read_lock() before line 8 of rcu_barrier()
and an rcu_read_unlock() after line 8 of this same function. If
you can think of a better change, please let me know!
...@@ -392,6 +392,10 @@ int main(int argc, char *argv[]) ...@@ -392,6 +392,10 @@ int main(int argc, char *argv[])
goto err; goto err;
} }
} }
if (!maskset && !tid && !containerset) {
usage();
goto err;
}
do { do {
int i; int i;
......
March 2008
Jan-Simon Moeller, dl9pf@gmx.de
How to deal with bad memory e.g. reported by memtest86+ ?
#########################################################
There are three possibilities I know of:
1) Reinsert/swap the memory modules
2) Buy new modules (best!) or try to exchange the memory
if you have spare-parts
3) Use BadRAM or memmap
This Howto is about number 3) .
BadRAM
######
BadRAM is the actively developed and available as kernel-patch
here: http://rick.vanrein.org/linux/badram/
For more details see the BadRAM documentation.
memmap
######
memmap is already in the kernel and usable as kernel-parameter at
boot-time. Its syntax is slightly strange and you may need to
calculate the values by yourself!
Syntax to exclude a memory area (see kernel-parameters.txt for details):
memmap=<size>$<address>
Example: memtest86+ reported here errors at address 0x18691458, 0x18698424 and
some others. All had 0x1869xxxx in common, so I chose a pattern of
0x18690000,0xffff0000.
With the numbers of the example above:
memmap=64K$0x18690000
or
memmap=0x10000$0x18690000
...@@ -9,3 +9,6 @@ cachefeatures.txt ...@@ -9,3 +9,6 @@ cachefeatures.txt
Filesystems Filesystems
- Requirements for mounting the root file system. - Requirements for mounting the root file system.
bfin-gpio-note.txt
- Notes in developing/using bfin-gpio driver.
/*
* File: Documentation/blackfin/bfin-gpio-note.txt
* Based on:
* Author:
*
* Created: $Id: bfin-gpio-note.txt 2008-11-24 16:42 grafyang $
* Description: This file contains the notes in developing/using bfin-gpio.
*
*
* Rev:
*
* Modified:
* Copyright 2004-2008 Analog Devices Inc.
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
*/
1. Blackfin GPIO introduction
There are many GPIO pins on Blackfin. Most of these pins are muxed to
multi-functions. They can be configured as peripheral, or just as GPIO,
configured to input with interrupt enabled, or output.
For detailed information, please see "arch/blackfin/kernel/bfin_gpio.c",
or the relevant HRM.
2. Avoiding resource conflict
Followed function groups are used to avoiding resource conflict,
- Use the pin as peripheral,
int peripheral_request(unsigned short per, const char *label);
int peripheral_request_list(const unsigned short per[], const char *label);
void peripheral_free(unsigned short per);
void peripheral_free_list(const unsigned short per[]);
- Use the pin as GPIO,
int bfin_gpio_request(unsigned gpio, const char *label);
void bfin_gpio_free(unsigned gpio);
- Use the pin as GPIO interrupt,
int bfin_gpio_irq_request(unsigned gpio, const char *label);
void bfin_gpio_irq_free(unsigned gpio);
The request functions will record the function state for a certain pin,
the free functions will clear it's function state.
Once a pin is requested, it can't be requested again before it is freed by
previous caller, otherwise kernel will dump stacks, and the request
function fail.
These functions are wrapped by other functions, most of the users need not
care.
3. But there are some exceptions
- Kernel permit the identical GPIO be requested both as GPIO and GPIO
interrut.
Some drivers, like gpio-keys, need this behavior. Kernel only print out
warning messages like,
bfin-gpio: GPIO 24 is already reserved by gpio-keys: BTN0, and you are
configuring it as IRQ!
Note: Consider the case that, if there are two drivers need the
identical GPIO, one of them use it as GPIO, the other use it as
GPIO interrupt. This will really cause resource conflict. So if
there is any abnormal driver behavior, please check the bfin-gpio
warning messages.
- Kernel permit the identical GPIO be requested from the same driver twice.
...@@ -186,8 +186,9 @@ a virtual address mapping (unlike the earlier scheme of virtual address ...@@ -186,8 +186,9 @@ a virtual address mapping (unlike the earlier scheme of virtual address
do not have a corresponding kernel virtual address space mapping) and do not have a corresponding kernel virtual address space mapping) and
low-memory pages. low-memory pages.
Note: Please refer to DMA-mapping.txt for a discussion on PCI high mem DMA Note: Please refer to Documentation/PCI/PCI-DMA-mapping.txt for a discussion
aspects and mapping of scatter gather lists, and support for 64 bit PCI. on PCI high mem DMA aspects and mapping of scatter gather lists, and support
for 64 bit PCI.
Special handling is required only for cases where i/o needs to happen on Special handling is required only for cases where i/o needs to happen on
pages at physical memory addresses beyond what the device can support. In these pages at physical memory addresses beyond what the device can support. In these
...@@ -953,14 +954,14 @@ elevator_allow_merge_fn called whenever the block layer determines ...@@ -953,14 +954,14 @@ elevator_allow_merge_fn called whenever the block layer determines
results in some sort of conflict internally, results in some sort of conflict internally,
this hook allows it to do that. this hook allows it to do that.
elevator_dispatch_fn fills the dispatch queue with ready requests. elevator_dispatch_fn* fills the dispatch queue with ready requests.
I/O schedulers are free to postpone requests by I/O schedulers are free to postpone requests by
not filling the dispatch queue unless @force not filling the dispatch queue unless @force
is non-zero. Once dispatched, I/O schedulers is non-zero. Once dispatched, I/O schedulers
are not allowed to manipulate the requests - are not allowed to manipulate the requests -
they belong to generic dispatch queue. they belong to generic dispatch queue.
elevator_add_req_fn called to add a new request into the scheduler elevator_add_req_fn* called to add a new request into the scheduler
elevator_queue_empty_fn returns true if the merge queue is empty. elevator_queue_empty_fn returns true if the merge queue is empty.
Drivers shouldn't use this, but rather check Drivers shouldn't use this, but rather check
...@@ -990,7 +991,7 @@ elevator_activate_req_fn Called when device driver first sees a request. ...@@ -990,7 +991,7 @@ elevator_activate_req_fn Called when device driver first sees a request.
elevator_deactivate_req_fn Called when device driver decides to delay elevator_deactivate_req_fn Called when device driver decides to delay
a request by requeueing it. a request by requeueing it.
elevator_init_fn elevator_init_fn*
elevator_exit_fn Allocate and free any elevator specific storage elevator_exit_fn Allocate and free any elevator specific storage
for a queue. for a queue.
......
Queue sysfs files
=================
This text file will detail the queue files that are located in the sysfs tree
for each block device. Note that stacked devices typically do not export
any settings, since their queue merely functions are a remapping target.
These files are the ones found in the /sys/block/xxx/queue/ directory.
Files denoted with a RO postfix are readonly and the RW postfix means
read-write.
hw_sector_size (RO)
-------------------
This is the hardware sector size of the device, in bytes.
max_hw_sectors_kb (RO)
----------------------
This is the maximum number of kilobytes supported in a single data transfer.
max_sectors_kb (RW)
-------------------
This is the maximum number of kilobytes that the block layer will allow
for a filesystem request. Must be smaller than or equal to the maximum
size allowed by the hardware.
nomerges (RW)
-------------
This enables the user to disable the lookup logic involved with IO merging
requests in the block layer. Merging may still occur through a direct
1-hit cache, since that comes for (almost) free. The IO scheduler will not
waste cycles doing tree/hash lookups for merges if nomerges is 1. Defaults
to 0, enabling all merges.
nr_requests (RW)
----------------
This controls how many requests may be allocated in the block layer for
read or write requests. Note that the total allocated number may be twice
this amount, since it applies only to reads or writes (not the accumulated
sum).
read_ahead_kb (RW)
------------------
Maximum number of kilobytes to read-ahead for filesystems on this block
device.
rq_affinity (RW)
----------------
If this option is enabled, the block layer will migrate request completions
to the CPU that originally submitted the request. For some workloads
this provides a significant reduction in CPU cycles due to caching effects.
scheduler (RW)
--------------
When read, this file will display the current and available IO schedulers
for this block device. The currently active IO scheduler will be enclosed
in [] brackets. Writing an IO scheduler name to this file will switch
control of this block device to that new IO scheduler. Note that writing
an IO scheduler name to this file will attempt to load that IO scheduler
module, if it isn't already present in the system.
Jens Axboe <jens.axboe@oracle.com>, February 2009
CGROUPS CGROUPS
------- -------
Written by Paul Menage <menage@google.com> based on Documentation/cpusets.txt Written by Paul Menage <menage@google.com> based on
Documentation/cgroups/cpusets.txt
Original copyright statements from cpusets.txt: Original copyright statements from cpusets.txt:
Portions Copyright (C) 2004 BULL SA. Portions Copyright (C) 2004 BULL SA.
...@@ -68,7 +69,7 @@ On their own, the only use for cgroups is for simple job ...@@ -68,7 +69,7 @@ On their own, the only use for cgroups is for simple job
tracking. The intention is that other subsystems hook into the generic tracking. The intention is that other subsystems hook into the generic
cgroup support to provide new attributes for cgroups, such as cgroup support to provide new attributes for cgroups, such as
accounting/limiting the resources which processes in a cgroup can accounting/limiting the resources which processes in a cgroup can
access. For example, cpusets (see Documentation/cpusets.txt) allows access. For example, cpusets (see Documentation/cgroups/cpusets.txt) allows
you to associate a set of CPUs and a set of memory nodes with the you to associate a set of CPUs and a set of memory nodes with the
tasks in each cgroup. tasks in each cgroup.
...@@ -227,7 +228,6 @@ Each cgroup is represented by a directory in the cgroup file system ...@@ -227,7 +228,6 @@ Each cgroup is represented by a directory in the cgroup file system
containing the following files describing that cgroup: containing the following files describing that cgroup:
- tasks: list of tasks (by pid) attached to that cgroup - tasks: list of tasks (by pid) attached to that cgroup
- releasable flag: cgroup currently removeable?
- notify_on_release flag: run the release agent on exit? - notify_on_release flag: run the release agent on exit?
- release_agent: the path to use for release notifications (this file - release_agent: the path to use for release notifications (this file
exists in the top cgroup only) exists in the top cgroup only)
...@@ -360,7 +360,7 @@ Now you want to do something with this cgroup. ...@@ -360,7 +360,7 @@ Now you want to do something with this cgroup.
In this directory you can find several files: In this directory you can find several files:
# ls # ls
notify_on_release releasable tasks notify_on_release tasks
(plus whatever files added by the attached subsystems) (plus whatever files added by the attached subsystems)
Now attach your shell to this cgroup: Now attach your shell to this cgroup:
...@@ -479,7 +479,6 @@ newly-created cgroup if an error occurs after this subsystem's ...@@ -479,7 +479,6 @@ newly-created cgroup if an error occurs after this subsystem's
create() method has been called for the new cgroup). create() method has been called for the new cgroup).
void pre_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp); void pre_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
(cgroup_mutex held by caller)
Called before checking the reference count on each subsystem. This may Called before checking the reference count on each subsystem. This may
be useful for subsystems which have some extra references even if be useful for subsystems which have some extra references even if
...@@ -498,6 +497,7 @@ remain valid while the caller holds cgroup_mutex. ...@@ -498,6 +497,7 @@ remain valid while the caller holds cgroup_mutex.
void attach(struct cgroup_subsys *ss, struct cgroup *cgrp, void attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
struct cgroup *old_cgrp, struct task_struct *task) struct cgroup *old_cgrp, struct task_struct *task)
(cgroup_mutex held by caller)
Called after the task has been attached to the cgroup, to allow any Called after the task has been attached to the cgroup, to allow any
post-attachment activity that requires memory allocations or blocking. post-attachment activity that requires memory allocations or blocking.
...@@ -511,6 +511,7 @@ void exit(struct cgroup_subsys *ss, struct task_struct *task) ...@@ -511,6 +511,7 @@ void exit(struct cgroup_subsys *ss, struct task_struct *task)
Called during task exit. Called during task exit.
int populate(struct cgroup_subsys *ss, struct cgroup *cgrp) int populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
(cgroup_mutex held by caller)
Called after creation of a cgroup to allow a subsystem to populate Called after creation of a cgroup to allow a subsystem to populate
the cgroup directory with file entries. The subsystem should make the cgroup directory with file entries. The subsystem should make
...@@ -520,6 +521,7 @@ method can return an error code, the error code is currently not ...@@ -520,6 +521,7 @@ method can return an error code, the error code is currently not
always handled well. always handled well.
void post_clone(struct cgroup_subsys *ss, struct cgroup *cgrp) void post_clone(struct cgroup_subsys *ss, struct cgroup *cgrp)
(cgroup_mutex held by caller)
Called at the end of cgroup_clone() to do any paramater Called at the end of cgroup_clone() to do any paramater
initialization which might be required before a task could attach. For initialization which might be required before a task could attach. For
...@@ -527,7 +529,7 @@ example in cpusets, no task may attach before 'cpus' and 'mems' are set ...@@ -527,7 +529,7 @@ example in cpusets, no task may attach before 'cpus' and 'mems' are set
up. up.
void bind(struct cgroup_subsys *ss, struct cgroup *root) void bind(struct cgroup_subsys *ss, struct cgroup *root)
(cgroup_mutex held by caller) (cgroup_mutex and ss->hierarchy_mutex held by caller)
Called when a cgroup subsystem is rebound to a different hierarchy Called when a cgroup subsystem is rebound to a different hierarchy
and root cgroup. Currently this will only involve movement between and root cgroup. Currently this will only involve movement between
......
Memory Resource Controller(Memcg) Implementation Memo.
Last Updated: 2009/1/19
Base Kernel Version: based on 2.6.29-rc2.
Because VM is getting complex (one of reasons is memcg...), memcg's behavior
is complex. This is a document for memcg's internal behavior.
Please note that implementation details can be changed.
(*) Topics on API should be in Documentation/cgroups/memory.txt)
0. How to record usage ?
2 objects are used.
page_cgroup ....an object per page.
Allocated at boot or memory hotplug. Freed at memory hot removal.
swap_cgroup ... an entry per swp_entry.
Allocated at swapon(). Freed at swapoff().
The page_cgroup has USED bit and double count against a page_cgroup never
occurs. swap_cgroup is used only when a charged page is swapped-out.
1. Charge
a page/swp_entry may be charged (usage += PAGE_SIZE) at
mem_cgroup_newpage_charge()
Called at new page fault and Copy-On-Write.
mem_cgroup_try_charge_swapin()
Called at do_swap_page() (page fault on swap entry) and swapoff.
Followed by charge-commit-cancel protocol. (With swap accounting)
At commit, a charge recorded in swap_cgroup is removed.
mem_cgroup_cache_charge()
Called at add_to_page_cache()
mem_cgroup_cache_charge_swapin()
Called at shmem's swapin.
mem_cgroup_prepare_migration()
Called before migration. "extra" charge is done and followed by
charge-commit-cancel protocol.
At commit, charge against oldpage or newpage will be committed.
2. Uncharge
a page/swp_entry may be uncharged (usage -= PAGE_SIZE) by
mem_cgroup_uncharge_page()
Called when an anonymous page is fully unmapped. I.e., mapcount goes
to 0. If the page is SwapCache, uncharge is delayed until
mem_cgroup_uncharge_swapcache().
mem_cgroup_uncharge_cache_page()
Called when a page-cache is deleted from radix-tree. If the page is
SwapCache, uncharge is delayed until mem_cgroup_uncharge_swapcache().
mem_cgroup_uncharge_swapcache()
Called when SwapCache is removed from radix-tree. The charge itself
is moved to swap_cgroup. (If mem+swap controller is disabled, no
charge to swap occurs.)
mem_cgroup_uncharge_swap()
Called when swp_entry's refcnt goes down to 0. A charge against swap
disappears.
mem_cgroup_end_migration(old, new)
At success of migration old is uncharged (if necessary), a charge
to new page is committed. At failure, charge to old page is committed.
3. charge-commit-cancel
In some case, we can't know this "charge" is valid or not at charging
(because of races).
To handle such case, there are charge-commit-cancel functions.
mem_cgroup_try_charge_XXX
mem_cgroup_commit_charge_XXX
mem_cgroup_cancel_charge_XXX
these are used in swap-in and migration.
At try_charge(), there are no flags to say "this page is charged".
at this point, usage += PAGE_SIZE.
At commit(), the function checks the page should be charged or not
and set flags or avoid charging.(usage -= PAGE_SIZE)
At cancel(), simply usage -= PAGE_SIZE.
Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y.
4. Anonymous
Anonymous page is newly allocated at
- page fault into MAP_ANONYMOUS mapping.
- Copy-On-Write.
It is charged right after it's allocated before doing any page table
related operations. Of course, it's uncharged when another page is used
for the fault address.
At freeing anonymous page (by exit() or munmap()), zap_pte() is called
and pages for ptes are freed one by one.(see mm/memory.c). Uncharges
are done at page_remove_rmap() when page_mapcount() goes down to 0.
Another page freeing is by page-reclaim (vmscan.c) and anonymous
pages are swapped out. In this case, the page is marked as
PageSwapCache(). uncharge() routine doesn't uncharge the page marked
as SwapCache(). It's delayed until __delete_from_swap_cache().
4.1 Swap-in.
At swap-in, the page is taken from swap-cache. There are 2 cases.
(a) If the SwapCache is newly allocated and read, it has no charges.
(b) If the SwapCache has been mapped by processes, it has been
charged already.
This swap-in is one of the most complicated work. In do_swap_page(),
following events occur when pte is unchanged.
(1) the page (SwapCache) is looked up.
(2) lock_page()
(3) try_charge_swapin()
(4) reuse_swap_page() (may call delete_swap_cache())
(5) commit_charge_swapin()
(6) swap_free().
Considering following situation for example.
(A) The page has not been charged before (2) and reuse_swap_page()
doesn't call delete_from_swap_cache().
(B) The page has not been charged before (2) and reuse_swap_page()
calls delete_from_swap_cache().
(C) The page has been charged before (2) and reuse_swap_page() doesn't
call delete_from_swap_cache().
(D) The page has been charged before (2) and reuse_swap_page() calls
delete_from_swap_cache().
memory.usage/memsw.usage changes to this page/swp_entry will be
Case (A) (B) (C) (D)
Event
Before (2) 0/ 1 0/ 1 1/ 1 1/ 1
===========================================
(3) +1/+1 +1/+1 +1/+1 +1/+1
(4) - 0/ 0 - -1/ 0
(5) 0/-1 0/ 0 -1/-1 0/ 0
(6) - 0/-1 - 0/-1
===========================================
Result 1/ 1 1/ 1 1/ 1 1/ 1
In any cases, charges to this page should be 1/ 1.
4.2 Swap-out.
At swap-out, typical state transition is below.
(a) add to swap cache. (marked as SwapCache)
swp_entry's refcnt += 1.
(b) fully unmapped.
swp_entry's refcnt += # of ptes.
(c) write back to swap.
(d) delete from swap cache. (remove from SwapCache)
swp_entry's refcnt -= 1.
At (b), the page is marked as SwapCache and not uncharged.
At (d), the page is removed from SwapCache and a charge in page_cgroup
is moved to swap_cgroup.
Finally, at task exit,
(e) zap_pte() is called and swp_entry's refcnt -=1 -> 0.
Here, a charge in swap_cgroup disappears.
5. Page Cache
Page Cache is charged at
- add_to_page_cache_locked().
uncharged at
- __remove_from_page_cache().
The logic is very clear. (About migration, see below)
Note: __remove_from_page_cache() is called by remove_from_page_cache()
and __remove_mapping().
6. Shmem(tmpfs) Page Cache
Memcg's charge/uncharge have special handlers of shmem. The best way
to understand shmem's page state transition is to read mm/shmem.c.
But brief explanation of the behavior of memcg around shmem will be
helpful to understand the logic.
Shmem's page (just leaf page, not direct/indirect block) can be on
- radix-tree of shmem's inode.
- SwapCache.
- Both on radix-tree and SwapCache. This happens at swap-in
and swap-out,
It's charged when...
- A new page is added to shmem's radix-tree.
- A swp page is read. (move a charge from swap_cgroup to page_cgroup)
It's uncharged when
- A page is removed from radix-tree and not SwapCache.
- When SwapCache is removed, a charge is moved to swap_cgroup.
- When swp_entry's refcnt goes down to 0, a charge in swap_cgroup
disappears.
7. Page Migration
One of the most complicated functions is page-migration-handler.
Memcg has 2 routines. Assume that we are migrating a page's contents
from OLDPAGE to NEWPAGE.
Usual migration logic is..
(a) remove the page from LRU.
(b) allocate NEWPAGE (migration target)
(c) lock by lock_page().
(d) unmap all mappings.
(e-1) If necessary, replace entry in radix-tree.
(e-2) move contents of a page.
(f) map all mappings again.
(g) pushback the page to LRU.
(-) OLDPAGE will be freed.
Before (g), memcg should complete all necessary charge/uncharge to
NEWPAGE/OLDPAGE.
The point is....
- If OLDPAGE is anonymous, all charges will be dropped at (d) because
try_to_unmap() drops all mapcount and the page will not be
SwapCache.
- If OLDPAGE is SwapCache, charges will be kept at (g) because
__delete_from_swap_cache() isn't called at (e-1)
- If OLDPAGE is page-cache, charges will be kept at (g) because
remove_from_swap_cache() isn't called at (e-1)
memcg provides following hooks.
- mem_cgroup_prepare_migration(OLDPAGE)
Called after (b) to account a charge (usage += PAGE_SIZE) against
memcg which OLDPAGE belongs to.
- mem_cgroup_end_migration(OLDPAGE, NEWPAGE)
Called after (f) before (g).
If OLDPAGE is used, commit OLDPAGE again. If OLDPAGE is already
charged, a charge by prepare_migration() is automatically canceled.
If NEWPAGE is used, commit NEWPAGE and uncharge OLDPAGE.
But zap_pte() (by exit or munmap) can be called while migration,
we have to check if OLDPAGE/NEWPAGE is a valid page after commit().
8. LRU
Each memcg has its own private LRU. Now, it's handling is under global
VM's control (means that it's handled under global zone->lru_lock).
Almost all routines around memcg's LRU is called by global LRU's
list management functions under zone->lru_lock().
A special function is mem_cgroup_isolate_pages(). This scans
memcg's private LRU and call __isolate_lru_page() to extract a page
from LRU.
(By __isolate_lru_page(), the page is removed from both of global and
private LRU.)
9. Typical Tests.
Tests for racy cases.
9.1 Small limit to memcg.
When you do test to do racy case, it's good test to set memcg's limit
to be very small rather than GB. Many races found in the test under
xKB or xxMB limits.
(Memory behavior under GB and Memory behavior under MB shows very
different situation.)
9.2 Shmem
Historically, memcg's shmem handling was poor and we saw some amount
of troubles here. This is because shmem is page-cache but can be
SwapCache. Test with shmem/tmpfs is always good test.
9.3 Migration
For NUMA, migration is an another special case. To do easy test, cpuset
is useful. Following is a sample script to do migration.
mount -t cgroup -o cpuset none /opt/cpuset
mkdir /opt/cpuset/01
echo 1 > /opt/cpuset/01/cpuset.cpus
echo 0 > /opt/cpuset/01/cpuset.mems
echo 1 > /opt/cpuset/01/cpuset.memory_migrate
mkdir /opt/cpuset/02
echo 1 > /opt/cpuset/02/cpuset.cpus
echo 1 > /opt/cpuset/02/cpuset.mems
echo 1 > /opt/cpuset/02/cpuset.memory_migrate
In above set, when you moves a task from 01 to 02, page migration to
node 0 to node 1 will occur. Following is a script to migrate all
under cpuset.
--
move_task()
{
for pid in $1
do
/bin/echo $pid >$2/tasks 2>/dev/null
echo -n $pid
echo -n " "
done
echo END
}
G1_TASK=`cat ${G1}/tasks`
G2_TASK=`cat ${G2}/tasks`
move_task "${G1_TASK}" ${G2} &
--
9.4 Memory hotplug.
memory hotplug test is one of good test.
to offline memory, do following.
# echo offline > /sys/devices/system/memory/memoryXXX/state
(XXX is the place of memory)
This is an easy way to test page migration, too.
9.5 mkdir/rmdir
When using hierarchy, mkdir/rmdir test should be done.
Use tests like the following.
echo 1 >/opt/cgroup/01/memory/use_hierarchy
mkdir /opt/cgroup/01/child_a
mkdir /opt/cgroup/01/child_b
set limit to 01.
add limit to 01/child_b
run jobs under child_a and child_b
create/delete following groups at random while jobs are running.
/opt/cgroup/01/child_a/child_aa
/opt/cgroup/01/child_b/child_bb
/opt/cgroup/01/child_c
running new jobs in new group is also good.
9.6 Mount with other subsystems.
Mounting with other subsystems is a good test because there is a
race and lock dependency with other cgroup subsystems.
example)
# mount -t cgroup none /cgroup -t cpuset,memory,cpu,devices
and do task move, mkdir, rmdir etc...under this.
9.7 swapoff.
Besides management of swap is one of complicated parts of memcg,
call path of swap-in at swapoff is not same as usual swap-in path..
It's worth to be tested explicitly.
For example, test like following is good.
(Shell-A)
# mount -t cgroup none /cgroup -t memory
# mkdir /cgroup/test
# echo 40M > /cgroup/test/memory.limit_in_bytes
# echo 0 > /cgroup/test/tasks
Run malloc(100M) program under this. You'll see 60M of swaps.
(Shell-B)
# move all tasks in /cgroup/test to /cgroup
# /sbin/swapoff -a
# rmdir /test/cgroup
# kill malloc task.
Of course, tmpfs v.s. swapoff test should be tested, too.
Memory Resource Controller
NOTE: The Memory Resource Controller has been generically been referred
to as the memory controller in this document. Do not confuse memory controller
used here with the memory controller that is used in hardware.
Salient features
a. Enable control of both RSS (mapped) and Page Cache (unmapped) pages
b. The infrastructure allows easy addition of other types of memory to control
c. Provides *zero overhead* for non memory controller users
d. Provides a double LRU: global memory pressure causes reclaim from the
global LRU; a cgroup on hitting a limit, reclaims from the per
cgroup LRU
NOTE: Swap Cache (unmapped) is not accounted now.
Benefits and Purpose of the memory controller
The memory controller isolates the memory behaviour of a group of tasks
from the rest of the system. The article on LWN [12] mentions some probable
uses of the memory controller. The memory controller can be used to
a. Isolate an application or a group of applications
Memory hungry applications can be isolated and limited to a smaller
amount of memory.
b. Create a cgroup with limited amount of memory, this can be used
as a good alternative to booting with mem=XXXX.
c. Virtualization solutions can control the amount of memory they want
to assign to a virtual machine instance.
d. A CD/DVD burner could control the amount of memory used by the
rest of the system to ensure that burning does not fail due to lack
of available memory.
e. There are several other use cases, find one or use the controller just
for fun (to learn and hack on the VM subsystem).
1. History
The memory controller has a long history. A request for comments for the memory
controller was posted by Balbir Singh [1]. At the time the RFC was posted
there were several implementations for memory control. The goal of the
RFC was to build consensus and agreement for the minimal features required
for memory control. The first RSS controller was posted by Balbir Singh[2]
in Feb 2007. Pavel Emelianov [3][4][5] has since posted three versions of the
RSS controller. At OLS, at the resource management BoF, everyone suggested
that we handle both page cache and RSS together. Another request was raised
to allow user space handling of OOM. The current memory controller is
at version 6; it combines both mapped (RSS) and unmapped Page
Cache Control [11].
2. Memory Control
Memory is a unique resource in the sense that it is present in a limited
amount. If a task requires a lot of CPU processing, the task can spread
its processing over a period of hours, days, months or years, but with
memory, the same physical memory needs to be reused to accomplish the task.
The memory controller implementation has been divided into phases. These
are:
1. Memory controller
2. mlock(2) controller
3. Kernel user memory accounting and slab control
4. user mappings length controller
The memory controller is the first controller developed.
2.1. Design
The core of the design is a counter called the res_counter. The res_counter
tracks the current memory usage and limit of the group of processes associated
with the controller. Each cgroup has a memory controller specific data
structure (mem_cgroup) associated with it.
2.2. Accounting
+--------------------+
| mem_cgroup |
| (res_counter) |
+--------------------+
/ ^ \
/ | \
+---------------+ | +---------------+
| mm_struct | |.... | mm_struct |
| | | | |
+---------------+ | +---------------+
|
+ --------------+
|
+---------------+ +------+--------+
| page +----------> page_cgroup|
| | | |
+---------------+ +---------------+
(Figure 1: Hierarchy of Accounting)
Figure 1 shows the important aspects of the controller
1. Accounting happens per cgroup
2. Each mm_struct knows about which cgroup it belongs to
3. Each page has a pointer to the page_cgroup, which in turn knows the
cgroup it belongs to
The accounting is done as follows: mem_cgroup_charge() is invoked to setup
the necessary data structures and check if the cgroup that is being charged
is over its limit. If it is then reclaim is invoked on the cgroup.
More details can be found in the reclaim section of this document.
If everything goes well, a page meta-data-structure called page_cgroup is
allocated and associated with the page. This routine also adds the page to
the per cgroup LRU.
2.2.1 Accounting details
All mapped anon pages (RSS) and cache pages (Page Cache) are accounted.
(some pages which never be reclaimable and will not be on global LRU
are not accounted. we just accounts pages under usual vm management.)
RSS pages are accounted at page_fault unless they've already been accounted
for earlier. A file page will be accounted for as Page Cache when it's
inserted into inode (radix-tree). While it's mapped into the page tables of
processes, duplicate accounting is carefully avoided.
A RSS page is unaccounted when it's fully unmapped. A PageCache page is
unaccounted when it's removed from radix-tree.
At page migration, accounting information is kept.
Note: we just account pages-on-lru because our purpose is to control amount
of used pages. not-on-lru pages are tend to be out-of-control from vm view.
2.3 Shared Page Accounting
Shared pages are accounted on the basis of the first touch approach. The
cgroup that first touches a page is accounted for the page. The principle
behind this approach is that a cgroup that aggressively uses a shared
page will eventually get charged for it (once it is uncharged from
the cgroup that brought it in -- this will happen on memory pressure).
Exception: If CONFIG_CGROUP_CGROUP_MEM_RES_CTLR_SWAP is not used..
When you do swapoff and make swapped-out pages of shmem(tmpfs) to
be backed into memory in force, charges for pages are accounted against the
caller of swapoff rather than the users of shmem.
2.4 Swap Extension (CONFIG_CGROUP_MEM_RES_CTLR_SWAP)
Swap Extension allows you to record charge for swap. A swapped-in page is
charged back to original page allocator if possible.
When swap is accounted, following files are added.
- memory.memsw.usage_in_bytes.
- memory.memsw.limit_in_bytes.
usage of mem+swap is limited by memsw.limit_in_bytes.
Note: why 'mem+swap' rather than swap.
The global LRU(kswapd) can swap out arbitrary pages. Swap-out means
to move account from memory to swap...there is no change in usage of
mem+swap.
In other words, when we want to limit the usage of swap without affecting
global LRU, mem+swap limit is better than just limiting swap from OS point
of view.
2.5 Reclaim
Each cgroup maintains a per cgroup LRU that consists of an active
and inactive list. When a cgroup goes over its limit, we first try
to reclaim memory from the cgroup so as to make space for the new
pages that the cgroup has touched. If the reclaim is unsuccessful,
an OOM routine is invoked to select and kill the bulkiest task in the
cgroup.
The reclaim algorithm has not been modified for cgroups, except that
pages that are selected for reclaiming come from the per cgroup LRU
list.
2. Locking
The memory controller uses the following hierarchy
1. zone->lru_lock is used for selecting pages to be isolated
2. mem->per_zone->lru_lock protects the per cgroup LRU (per zone)
3. lock_page_cgroup() is used to protect page->page_cgroup
3. User Interface
0. Configuration
a. Enable CONFIG_CGROUPS
b. Enable CONFIG_RESOURCE_COUNTERS
c. Enable CONFIG_CGROUP_MEM_RES_CTLR
1. Prepare the cgroups
# mkdir -p /cgroups
# mount -t cgroup none /cgroups -o memory
2. Make the new group and move bash into it
# mkdir /cgroups/0
# echo $$ > /cgroups/0/tasks
Since now we're in the 0 cgroup,
We can alter the memory limit:
# echo 4M > /cgroups/0/memory.limit_in_bytes
NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo,
mega or gigabytes.
# cat /cgroups/0/memory.limit_in_bytes
4194304
NOTE: The interface has now changed to display the usage in bytes
instead of pages
We can check the usage:
# cat /cgroups/0/memory.usage_in_bytes
1216512
A successful write to this file does not guarantee a successful set of
this limit to the value written into the file. This can be due to a
number of factors, such as rounding up to page boundaries or the total
availability of memory on the system. The user is required to re-read
this file after a write to guarantee the value committed by the kernel.
# echo 1 > memory.limit_in_bytes
# cat memory.limit_in_bytes
4096
The memory.failcnt field gives the number of times that the cgroup limit was
exceeded.
The memory.stat file gives accounting information. Now, the number of
caches, RSS and Active pages/Inactive pages are shown.
4. Testing
Balbir posted lmbench, AIM9, LTP and vmmstress results [10] and [11].
Apart from that v6 has been tested with several applications and regular
daily use. The controller has also been tested on the PPC64, x86_64 and
UML platforms.
4.1 Troubleshooting
Sometimes a user might find that the application under a cgroup is
terminated. There are several causes for this:
1. The cgroup limit is too low (just too low to do anything useful)
2. The user is using anonymous memory and swap is turned off or too low
A sync followed by echo 1 > /proc/sys/vm/drop_caches will help get rid of
some of the pages cached in the cgroup (page cache pages).
4.2 Task migration
When a task migrates from one cgroup to another, it's charge is not
carried forward. The pages allocated from the original cgroup still
remain charged to it, the charge is dropped when the page is freed or
reclaimed.
4.3 Removing a cgroup
A cgroup can be removed by rmdir, but as discussed in sections 4.1 and 4.2, a
cgroup might have some charge associated with it, even though all
tasks have migrated away from it.
Such charges are freed(at default) or moved to its parent. When moved,
both of RSS and CACHES are moved to parent.
If both of them are busy, rmdir() returns -EBUSY. See 5.1 Also.
Charges recorded in swap information is not updated at removal of cgroup.
Recorded information is discarded and a cgroup which uses swap (swapcache)
will be charged as a new owner of it.
5. Misc. interfaces.
5.1 force_empty
memory.force_empty interface is provided to make cgroup's memory usage empty.
You can use this interface only when the cgroup has no tasks.
When writing anything to this
# echo 0 > memory.force_empty
Almost all pages tracked by this memcg will be unmapped and freed. Some of
pages cannot be freed because it's locked or in-use. Such pages are moved
to parent and this cgroup will be empty. But this may return -EBUSY in
some too busy case.
Typical use case of this interface is that calling this before rmdir().
Because rmdir() moves all pages to parent, some out-of-use page caches can be
moved to the parent. If you want to avoid that, force_empty will be useful.
5.2 stat file
memory.stat file includes following statistics (now)
cache - # of pages from page-cache and shmem.
rss - # of pages from anonymous memory.
pgpgin - # of event of charging
pgpgout - # of event of uncharging
active_anon - # of pages on active lru of anon, shmem.
inactive_anon - # of pages on active lru of anon, shmem
active_file - # of pages on active lru of file-cache
inactive_file - # of pages on inactive lru of file cache
unevictable - # of pages cannot be reclaimed.(mlocked etc)
Below is depend on CONFIG_DEBUG_VM.
inactive_ratio - VM inernal parameter. (see mm/page_alloc.c)
recent_rotated_anon - VM internal parameter. (see mm/vmscan.c)
recent_rotated_file - VM internal parameter. (see mm/vmscan.c)
recent_scanned_anon - VM internal parameter. (see mm/vmscan.c)
recent_scanned_file - VM internal parameter. (see mm/vmscan.c)
Memo:
recent_rotated means recent frequency of lru rotation.
recent_scanned means recent # of scans to lru.
showing for better debug please see the code for meanings.
5.3 swappiness
Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
Following cgroup's swapiness can't be changed.
- root cgroup (uses /proc/sys/vm/swappiness).
- a cgroup which uses hierarchy and it has child cgroup.
- a cgroup which uses hierarchy and not the root of hierarchy.
6. Hierarchy support
The memory controller supports a deep hierarchy and hierarchical accounting.
The hierarchy is created by creating the appropriate cgroups in the
cgroup filesystem. Consider for example, the following cgroup filesystem
hierarchy
root
/ | \
/ | \
a b c
| \
| \
d e
In the diagram above, with hierarchical accounting enabled, all memory
usage of e, is accounted to its ancestors up until the root (i.e, c and root),
that has memory.use_hierarchy enabled. If one of the ancestors goes over its
limit, the reclaim algorithm reclaims from the tasks in the ancestor and the
children of the ancestor.
6.1 Enabling hierarchical accounting and reclaim
The memory controller by default disables the hierarchy feature. Support
can be enabled by writing 1 to memory.use_hierarchy file of the root cgroup
# echo 1 > memory.use_hierarchy
The feature can be disabled by
# echo 0 > memory.use_hierarchy
NOTE1: Enabling/disabling will fail if the cgroup already has other
cgroups created below it.
NOTE2: This feature can be enabled/disabled per subtree.
7. TODO
1. Add support for accounting huge pages (as a separate controller)
2. Make per-cgroup scanner reclaim not-shared pages first
3. Teach controller to account for shared-pages
4. Start reclamation in the background when the limit is
not yet hit but the usage is getting closer
Summary
Overall, the memory controller has been a stable controller and has been
commented and discussed quite extensively in the community.
References
1. Singh, Balbir. RFC: Memory Controller, http://lwn.net/Articles/206697/
2. Singh, Balbir. Memory Controller (RSS Control),
http://lwn.net/Articles/222762/
3. Emelianov, Pavel. Resource controllers based on process cgroups
http://lkml.org/lkml/2007/3/6/198
4. Emelianov, Pavel. RSS controller based on process cgroups (v2)
http://lkml.org/lkml/2007/4/9/78
5. Emelianov, Pavel. RSS controller based on process cgroups (v3)
http://lkml.org/lkml/2007/5/30/244
6. Menage, Paul. Control Groups v10, http://lwn.net/Articles/236032/
7. Vaidyanathan, Srinivasan, Control Groups: Pagecache accounting and control
subsystem (v3), http://lwn.net/Articles/235534/
8. Singh, Balbir. RSS controller v2 test results (lmbench),
http://lkml.org/lkml/2007/5/17/232
9. Singh, Balbir. RSS controller v2 AIM9 results
http://lkml.org/lkml/2007/5/18/1
10. Singh, Balbir. Memory controller v6 test results,
http://lkml.org/lkml/2007/8/19/36
11. Singh, Balbir. Memory controller introduction (v6),
http://lkml.org/lkml/2007/8/17/69
12. Corbet, Jonathan, Controlling memory use in cgroups,
http://lwn.net/Articles/243795/
Memory Resource Controller
NOTE: The Memory Resource Controller has been generically been referred
to as the memory controller in this document. Do not confuse memory controller
used here with the memory controller that is used in hardware.
Salient features
a. Enable control of both RSS (mapped) and Page Cache (unmapped) pages
b. The infrastructure allows easy addition of other types of memory to control
c. Provides *zero overhead* for non memory controller users
d. Provides a double LRU: global memory pressure causes reclaim from the
global LRU; a cgroup on hitting a limit, reclaims from the per
cgroup LRU
NOTE: Swap Cache (unmapped) is not accounted now.
Benefits and Purpose of the memory controller
The memory controller isolates the memory behaviour of a group of tasks
from the rest of the system. The article on LWN [12] mentions some probable
uses of the memory controller. The memory controller can be used to
a. Isolate an application or a group of applications
Memory hungry applications can be isolated and limited to a smaller
amount of memory.
b. Create a cgroup with limited amount of memory, this can be used
as a good alternative to booting with mem=XXXX.
c. Virtualization solutions can control the amount of memory they want
to assign to a virtual machine instance.
d. A CD/DVD burner could control the amount of memory used by the
rest of the system to ensure that burning does not fail due to lack
of available memory.
e. There are several other use cases, find one or use the controller just
for fun (to learn and hack on the VM subsystem).
1. History
The memory controller has a long history. A request for comments for the memory
controller was posted by Balbir Singh [1]. At the time the RFC was posted
there were several implementations for memory control. The goal of the
RFC was to build consensus and agreement for the minimal features required
for memory control. The first RSS controller was posted by Balbir Singh[2]
in Feb 2007. Pavel Emelianov [3][4][5] has since posted three versions of the
RSS controller. At OLS, at the resource management BoF, everyone suggested
that we handle both page cache and RSS together. Another request was raised
to allow user space handling of OOM. The current memory controller is
at version 6; it combines both mapped (RSS) and unmapped Page
Cache Control [11].
2. Memory Control
Memory is a unique resource in the sense that it is present in a limited
amount. If a task requires a lot of CPU processing, the task can spread
its processing over a period of hours, days, months or years, but with
memory, the same physical memory needs to be reused to accomplish the task.
The memory controller implementation has been divided into phases. These
are:
1. Memory controller
2. mlock(2) controller
3. Kernel user memory accounting and slab control
4. user mappings length controller
The memory controller is the first controller developed.
2.1. Design
The core of the design is a counter called the res_counter. The res_counter
tracks the current memory usage and limit of the group of processes associated
with the controller. Each cgroup has a memory controller specific data
structure (mem_cgroup) associated with it.
2.2. Accounting
+--------------------+
| mem_cgroup |
| (res_counter) |
+--------------------+
/ ^ \
/ | \
+---------------+ | +---------------+
| mm_struct | |.... | mm_struct |
| | | | |
+---------------+ | +---------------+
|
+ --------------+
|
+---------------+ +------+--------+
| page +----------> page_cgroup|
| | | |
+---------------+ +---------------+
(Figure 1: Hierarchy of Accounting)
Figure 1 shows the important aspects of the controller
1. Accounting happens per cgroup
2. Each mm_struct knows about which cgroup it belongs to
3. Each page has a pointer to the page_cgroup, which in turn knows the
cgroup it belongs to
The accounting is done as follows: mem_cgroup_charge() is invoked to setup
the necessary data structures and check if the cgroup that is being charged
is over its limit. If it is then reclaim is invoked on the cgroup.
More details can be found in the reclaim section of this document.
If everything goes well, a page meta-data-structure called page_cgroup is
allocated and associated with the page. This routine also adds the page to
the per cgroup LRU.
2.2.1 Accounting details
All mapped anon pages (RSS) and cache pages (Page Cache) are accounted.
(some pages which never be reclaimable and will not be on global LRU
are not accounted. we just accounts pages under usual vm management.)
RSS pages are accounted at page_fault unless they've already been accounted
for earlier. A file page will be accounted for as Page Cache when it's
inserted into inode (radix-tree). While it's mapped into the page tables of
processes, duplicate accounting is carefully avoided.
A RSS page is unaccounted when it's fully unmapped. A PageCache page is
unaccounted when it's removed from radix-tree.
At page migration, accounting information is kept.
Note: we just account pages-on-lru because our purpose is to control amount
of used pages. not-on-lru pages are tend to be out-of-control from vm view.
2.3 Shared Page Accounting
Shared pages are accounted on the basis of the first touch approach. The
cgroup that first touches a page is accounted for the page. The principle
behind this approach is that a cgroup that aggressively uses a shared
page will eventually get charged for it (once it is uncharged from
the cgroup that brought it in -- this will happen on memory pressure).
2.4 Reclaim
Each cgroup maintains a per cgroup LRU that consists of an active
and inactive list. When a cgroup goes over its limit, we first try
to reclaim memory from the cgroup so as to make space for the new
pages that the cgroup has touched. If the reclaim is unsuccessful,
an OOM routine is invoked to select and kill the bulkiest task in the
cgroup.
The reclaim algorithm has not been modified for cgroups, except that
pages that are selected for reclaiming come from the per cgroup LRU
list.
2. Locking
The memory controller uses the following hierarchy
1. zone->lru_lock is used for selecting pages to be isolated
2. mem->per_zone->lru_lock protects the per cgroup LRU (per zone)
3. lock_page_cgroup() is used to protect page->page_cgroup
3. User Interface
0. Configuration
a. Enable CONFIG_CGROUPS
b. Enable CONFIG_RESOURCE_COUNTERS
c. Enable CONFIG_CGROUP_MEM_RES_CTLR
1. Prepare the cgroups
# mkdir -p /cgroups
# mount -t cgroup none /cgroups -o memory
2. Make the new group and move bash into it
# mkdir /cgroups/0
# echo $$ > /cgroups/0/tasks
Since now we're in the 0 cgroup,
We can alter the memory limit:
# echo 4M > /cgroups/0/memory.limit_in_bytes
NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo,
mega or gigabytes.
# cat /cgroups/0/memory.limit_in_bytes
4194304
NOTE: The interface has now changed to display the usage in bytes
instead of pages
We can check the usage:
# cat /cgroups/0/memory.usage_in_bytes
1216512
A successful write to this file does not guarantee a successful set of
this limit to the value written into the file. This can be due to a
number of factors, such as rounding up to page boundaries or the total
availability of memory on the system. The user is required to re-read
this file after a write to guarantee the value committed by the kernel.
# echo 1 > memory.limit_in_bytes
# cat memory.limit_in_bytes
4096
The memory.failcnt field gives the number of times that the cgroup limit was
exceeded.
The memory.stat file gives accounting information. Now, the number of
caches, RSS and Active pages/Inactive pages are shown.
The memory.force_empty gives an interface to drop *all* charges by force.
# echo 1 > memory.force_empty
will drop all charges in cgroup. Currently, this is maintained for test.
4. Testing
Balbir posted lmbench, AIM9, LTP and vmmstress results [10] and [11].
Apart from that v6 has been tested with several applications and regular
daily use. The controller has also been tested on the PPC64, x86_64 and
UML platforms.
4.1 Troubleshooting
Sometimes a user might find that the application under a cgroup is
terminated. There are several causes for this:
1. The cgroup limit is too low (just too low to do anything useful)
2. The user is using anonymous memory and swap is turned off or too low
A sync followed by echo 1 > /proc/sys/vm/drop_caches will help get rid of
some of the pages cached in the cgroup (page cache pages).
4.2 Task migration
When a task migrates from one cgroup to another, it's charge is not
carried forward. The pages allocated from the original cgroup still
remain charged to it, the charge is dropped when the page is freed or
reclaimed.
4.3 Removing a cgroup
A cgroup can be removed by rmdir, but as discussed in sections 4.1 and 4.2, a
cgroup might have some charge associated with it, even though all
tasks have migrated away from it. Such charges are automatically dropped at
rmdir() if there are no tasks.
5. TODO
1. Add support for accounting huge pages (as a separate controller)
2. Make per-cgroup scanner reclaim not-shared pages first
3. Teach controller to account for shared-pages
4. Start reclamation in the background when the limit is
not yet hit but the usage is getting closer
Summary
Overall, the memory controller has been a stable controller and has been
commented and discussed quite extensively in the community.
References
1. Singh, Balbir. RFC: Memory Controller, http://lwn.net/Articles/206697/
2. Singh, Balbir. Memory Controller (RSS Control),
http://lwn.net/Articles/222762/
3. Emelianov, Pavel. Resource controllers based on process cgroups
http://lkml.org/lkml/2007/3/6/198
4. Emelianov, Pavel. RSS controller based on process cgroups (v2)
http://lkml.org/lkml/2007/4/9/78
5. Emelianov, Pavel. RSS controller based on process cgroups (v3)
http://lkml.org/lkml/2007/5/30/244
6. Menage, Paul. Control Groups v10, http://lwn.net/Articles/236032/
7. Vaidyanathan, Srinivasan, Control Groups: Pagecache accounting and control
subsystem (v3), http://lwn.net/Articles/235534/
8. Singh, Balbir. RSS controller v2 test results (lmbench),
http://lkml.org/lkml/2007/5/17/232
9. Singh, Balbir. RSS controller v2 AIM9 results
http://lkml.org/lkml/2007/5/18/1
10. Singh, Balbir. Memory controller v6 test results,
http://lkml.org/lkml/2007/8/19/36
11. Singh, Balbir. Memory controller introduction (v6),
http://lkml.org/lkml/2007/8/17/69
12. Corbet, Jonathan, Controlling memory use in cgroups,
http://lwn.net/Articles/243795/
...@@ -50,16 +50,17 @@ additional_cpus=n (*) Use this to limit hotpluggable cpus. This option sets ...@@ -50,16 +50,17 @@ additional_cpus=n (*) Use this to limit hotpluggable cpus. This option sets
cpu_possible_map = cpu_present_map + additional_cpus cpu_possible_map = cpu_present_map + additional_cpus
(*) Option valid only for following architectures (*) Option valid only for following architectures
- x86_64, ia64 - ia64
ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT ia64 uses the number of disabled local apics in ACPI tables MADT to
to determine the number of potentially hot-pluggable cpus. The implementation determine the number of potentially hot-pluggable cpus. The implementation
should only rely on this to count the # of cpus, but *MUST* not rely on the should only rely on this to count the # of cpus, but *MUST* not rely
apicid values in those tables for disabled apics. In the event BIOS doesn't on the apicid values in those tables for disabled apics. In the event
mark such hot-pluggable cpus as disabled entries, one could use this BIOS doesn't mark such hot-pluggable cpus as disabled entries, one could
parameter "additional_cpus=x" to represent those cpus in the cpu_possible_map. use this parameter "additional_cpus=x" to represent those cpus in the
cpu_possible_map.
possible_cpus=n [s390 only] use this to set hotpluggable cpus. possible_cpus=n [s390,x86_64] use this to set hotpluggable cpus.
This option sets possible_cpus bits in This option sets possible_cpus bits in
cpu_possible_map. Thus keeping the numbers of bits set cpu_possible_map. Thus keeping the numbers of bits set
constant even if the machine gets rebooted. constant even if the machine gets rebooted.
......
...@@ -31,3 +31,51 @@ not defined by include/asm-XXX/topology.h: ...@@ -31,3 +31,51 @@ not defined by include/asm-XXX/topology.h:
2) core_id: 0 2) core_id: 0
3) thread_siblings: just the given CPU 3) thread_siblings: just the given CPU
4) core_siblings: just the given CPU 4) core_siblings: just the given CPU
Additionally, cpu topology information is provided under
/sys/devices/system/cpu and includes these files. The internal
source for the output is in brackets ("[]").
kernel_max: the maximum cpu index allowed by the kernel configuration.
[NR_CPUS-1]
offline: cpus that are not online because they have been
HOTPLUGGED off (see cpu-hotplug.txt) or exceed the limit
of cpus allowed by the kernel configuration (kernel_max
above). [~cpu_online_mask + cpus >= NR_CPUS]
online: cpus that are online and being scheduled [cpu_online_mask]
possible: cpus that have been allocated resources and can be
brought online if they are present. [cpu_possible_mask]
present: cpus that have been identified as being present in the
system. [cpu_present_mask]
The format for the above output is compatible with cpulist_parse()
[see <linux/cpumask.h>]. Some examples follow.
In this example, there are 64 cpus in the system but cpus 32-63 exceed
the kernel max which is limited to 0..31 by the NR_CPUS config option
being 32. Note also that cpus 2 and 4-31 are not online but could be
brought online as they are both present and possible.
kernel_max: 31
offline: 2,4-31,32-63
online: 0-1,3
possible: 0-31
present: 0-31
In this example, the NR_CPUS config option is 128, but the kernel was
started with possible_cpus=144. There are 4 cpus in the system and cpu2
was manually taken offline (and is the only cpu that can be brought
online.)
kernel_max: 127
offline: 2,4-127,128-143
online: 0-1,3
possible: 0-127
present: 0-3
See cpu-hotplug.txt for the possible_cpus=NUM kernel start parameter
as well as more information on the various cpumask's.
...@@ -13,9 +13,9 @@ ...@@ -13,9 +13,9 @@
3.6 Constraints 3.6 Constraints
3.7 Example 3.7 Example
4 DRIVER DEVELOPER NOTES 4 DMAENGINE DRIVER DEVELOPER NOTES
4.1 Conformance points 4.1 Conformance points
4.2 "My application needs finer control of hardware channels" 4.2 "My application needs exclusive control of hardware channels"
5 SOURCE 5 SOURCE
...@@ -150,6 +150,7 @@ ops_run_* and ops_complete_* routines in drivers/md/raid5.c for more ...@@ -150,6 +150,7 @@ ops_run_* and ops_complete_* routines in drivers/md/raid5.c for more
implementation examples. implementation examples.
4 DRIVER DEVELOPMENT NOTES 4 DRIVER DEVELOPMENT NOTES
4.1 Conformance points: 4.1 Conformance points:
There are a few conformance points required in dmaengine drivers to There are a few conformance points required in dmaengine drivers to
accommodate assumptions made by applications using the async_tx API: accommodate assumptions made by applications using the async_tx API:
...@@ -158,58 +159,49 @@ accommodate assumptions made by applications using the async_tx API: ...@@ -158,58 +159,49 @@ accommodate assumptions made by applications using the async_tx API:
3/ Use async_tx_run_dependencies() in the descriptor clean up path to 3/ Use async_tx_run_dependencies() in the descriptor clean up path to
handle submission of dependent operations handle submission of dependent operations
4.2 "My application needs finer control of hardware channels" 4.2 "My application needs exclusive control of hardware channels"
This requirement seems to arise from cases where a DMA engine driver is Primarily this requirement arises from cases where a DMA engine driver
trying to support device-to-memory DMA. The dmaengine and async_tx is being used to support device-to-memory operations. A channel that is
implementations were designed for offloading memory-to-memory performing these operations cannot, for many platform specific reasons,
operations; however, there are some capabilities of the dmaengine layer be shared. For these cases the dma_request_channel() interface is
that can be used for platform-specific channel management. provided.
Platform-specific constraints can be handled by registering the
application as a 'dma_client' and implementing a 'dma_event_callback' to The interface is:
apply a filter to the available channels in the system. Before showing struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
how to implement a custom dma_event callback some background of dma_filter_fn filter_fn,
dmaengine's client support is required. void *filter_param);
The following routines in dmaengine support multiple clients requesting Where dma_filter_fn is defined as:
use of a channel: typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
- dma_async_client_register(struct dma_client *client)
- dma_async_client_chan_request(struct dma_client *client) When the optional 'filter_fn' parameter is set to NULL
dma_request_channel simply returns the first channel that satisfies the
dma_async_client_register takes a pointer to an initialized dma_client capability mask. Otherwise, when the mask parameter is insufficient for
structure. It expects that the 'event_callback' and 'cap_mask' fields specifying the necessary channel, the filter_fn routine can be used to
are already initialized. disposition the available channels in the system. The filter_fn routine
is called once for each free channel in the system. Upon seeing a
dma_async_client_chan_request triggers dmaengine to notify the client of suitable channel filter_fn returns DMA_ACK which flags that channel to
all channels that satisfy the capability mask. It is up to the client's be the return value from dma_request_channel. A channel allocated via
event_callback routine to track how many channels the client needs and this interface is exclusive to the caller, until dma_release_channel()
how many it is currently using. The dma_event_callback routine returns a is called.
dma_state_client code to let dmaengine know the status of the
allocation. The DMA_PRIVATE capability flag is used to tag dma devices that should
not be used by the general-purpose allocator. It can be set at
Below is the example of how to extend this functionality for initialization time if it is known that a channel will always be
platform-specific filtering of the available channels beyond the private. Alternatively, it is set when dma_request_channel() finds an
standard capability mask: unused "public" channel.
static enum dma_state_client A couple caveats to note when implementing a driver and consumer:
my_dma_client_callback(struct dma_client *client, 1/ Once a channel has been privately allocated it will no longer be
struct dma_chan *chan, enum dma_state state) considered by the general-purpose allocator even after a call to
{ dma_release_channel().
struct dma_device *dma_dev; 2/ Since capabilities are specified at the device level a dma_device
struct my_platform_specific_dma *plat_dma_dev; with multiple channels will either have all channels public, or all
channels private.
dma_dev = chan->device;
plat_dma_dev = container_of(dma_dev,
struct my_platform_specific_dma,
dma_dev);
if (!plat_dma_dev->platform_specific_capability)
return DMA_DUP;
. . .
}
5 SOURCE 5 SOURCE
include/linux/dmaengine.h: core header file for DMA drivers and clients
include/linux/dmaengine.h: core header file for DMA drivers and api users
drivers/dma/dmaengine.c: offload engine channel management routines drivers/dma/dmaengine.c: offload engine channel management routines
drivers/dma/: location for offload engine drivers drivers/dma/: location for offload engine drivers
include/linux/async_tx.h: core header file for the async_tx api include/linux/async_tx.h: core header file for the async_tx api
......
...@@ -81,8 +81,8 @@ Until this step is completed the driver cannot be unloaded. ...@@ -81,8 +81,8 @@ Until this step is completed the driver cannot be unloaded.
Also echoing either mono ,packet or init in to image_type will free up the Also echoing either mono ,packet or init in to image_type will free up the
memory allocated by the driver. memory allocated by the driver.
If an user by accident executes steps 1 and 3 above without executing step 2; If a user by accident executes steps 1 and 3 above without executing step 2;
it will make the /sys/class/firmware/dell_rbu/ entries to disappear. it will make the /sys/class/firmware/dell_rbu/ entries disappear.
The entries can be recreated by doing the following The entries can be recreated by doing the following
echo init > /sys/devices/platform/dell_rbu/image_type echo init > /sys/devices/platform/dell_rbu/image_type
NOTE: echoing init in image_type does not change it original value. NOTE: echoing init in image_type does not change it original value.
......
...@@ -375,10 +375,10 @@ say, this can be a large job, so it is best to be sure that the ...@@ -375,10 +375,10 @@ say, this can be a large job, so it is best to be sure that the
justification is solid. justification is solid.
When making an incompatible API change, one should, whenever possible, When making an incompatible API change, one should, whenever possible,
ensure that code which has not been updated is caught by the compiler. ensure that code which has not been updated is caught by the compiler.
This will help you to be sure that you have found all in-tree uses of that This will help you to be sure that you have found all in-tree uses of that
interface. It will also alert developers of out-of-tree code that there is interface. It will also alert developers of out-of-tree code that there is
a change that they need to respond to. Supporting out-of-tree code is not a change that they need to respond to. Supporting out-of-tree code is not
something that kernel developers need to be worried about, but we also do something that kernel developers need to be worried about, but we also do
not have to make life harder for out-of-tree developers than it it needs to not have to make life harder for out-of-tree developers than it needs to
be. be.
See Documentation/crypto/async-tx-api.txt
...@@ -310,15 +310,6 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl> ...@@ -310,15 +310,6 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl>
--------------------------- ---------------------------
What: ide-scsi (BLK_DEV_IDESCSI)
When: 2.6.29
Why: The 2.6 kernel supports direct writing to ide CD drives, which
eliminates the need for ide-scsi. The new method is more
efficient in every way.
Who: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
---------------------------
What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client() What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()
When: 2.6.29 (ideally) or 2.6.30 (more likely) When: 2.6.29 (ideally) or 2.6.30 (more likely)
Why: Deprecated by the new (standard) device driver binding model. Use Why: Deprecated by the new (standard) device driver binding model. Use
...@@ -327,6 +318,14 @@ Who: Jean Delvare <khali@linux-fr.org> ...@@ -327,6 +318,14 @@ Who: Jean Delvare <khali@linux-fr.org>
--------------------------- ---------------------------
What: fscher and fscpos drivers
When: June 2009
Why: Deprecated by the new fschmd driver.
Who: Hans de Goede <hdegoede@redhat.com>
Jean Delvare <khali@linux-fr.org>
---------------------------
What: SELinux "compat_net" functionality What: SELinux "compat_net" functionality
When: 2.6.30 at the earliest When: 2.6.30 at the earliest
Why: In 2.6.18 the Secmark concept was introduced to replace the "compat_net" Why: In 2.6.18 the Secmark concept was introduced to replace the "compat_net"
......
...@@ -97,8 +97,8 @@ prototypes: ...@@ -97,8 +97,8 @@ prototypes:
void (*put_super) (struct super_block *); void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *); void (*write_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait); int (*sync_fs)(struct super_block *sb, int wait);
void (*write_super_lockfs) (struct super_block *); int (*freeze_fs) (struct super_block *);
void (*unlockfs) (struct super_block *); int (*unfreeze_fs) (struct super_block *);
int (*statfs) (struct dentry *, struct kstatfs *); int (*statfs) (struct dentry *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *); int (*remount_fs) (struct super_block *, int *, char *);
void (*clear_inode) (struct inode *); void (*clear_inode) (struct inode *);
...@@ -119,8 +119,8 @@ delete_inode: no ...@@ -119,8 +119,8 @@ delete_inode: no
put_super: yes yes no put_super: yes yes no
write_super: no yes read write_super: no yes read
sync_fs: no no read sync_fs: no no read
write_super_lockfs: ? freeze_fs: ?
unlockfs: ? unfreeze_fs: ?
statfs: no no no statfs: no no no
remount_fs: yes yes maybe (see below) remount_fs: yes yes maybe (see below)
clear_inode: no clear_inode: no
...@@ -394,11 +394,10 @@ prototypes: ...@@ -394,11 +394,10 @@ prototypes:
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long (*get_unmapped_area)(struct file *, unsigned long,
unsigned long, unsigned long, unsigned long); unsigned long, unsigned long, unsigned long);
int (*check_flags)(int); int (*check_flags)(int);
int (*dir_notify)(struct file *, unsigned long);
}; };
locking rules: locking rules:
All except ->poll() may block. All may block.
BKL BKL
llseek: no (see below) llseek: no (see below)
read: no read: no
...@@ -424,7 +423,6 @@ sendfile: no ...@@ -424,7 +423,6 @@ sendfile: no
sendpage: no sendpage: no
get_unmapped_area: no get_unmapped_area: no
check_flags: no check_flags: no
dir_notify: no
->llseek() locking has moved from llseek to the individual llseek ->llseek() locking has moved from llseek to the individual llseek
implementations. If your fs is not using generic_file_llseek, you implementations. If your fs is not using generic_file_llseek, you
......
BTRFS
=====
Btrfs is a new copy on write filesystem for Linux aimed at
implementing advanced features while focusing on fault tolerance,
repair and easy administration. Initially developed by Oracle, Btrfs
is licensed under the GPL and open for contribution from anyone.
Linux has a wealth of filesystems to choose from, but we are facing a
number of challenges with scaling to the large storage subsystems that
are becoming common in today's data centers. Filesystems need to scale
in their ability to address and manage large storage, and also in
their ability to detect, repair and tolerate errors in the data stored
on disk. Btrfs is under heavy development, and is not suitable for
any uses other than benchmarking and review. The Btrfs disk format is
not yet finalized.
The main Btrfs features include:
* Extent based file storage (2^64 max file size)
* Space efficient packing of small files
* Space efficient indexed directories
* Dynamic inode allocation
* Writable snapshots
* Subvolumes (separate internal filesystem roots)
* Object level mirroring and striping
* Checksums on data and metadata (multiple algorithms available)
* Compression
* Integrated multiple device support, with several raid algorithms
* Online filesystem check (not yet implemented)
* Very fast offline filesystem check
* Efficient incremental backup and FS mirroring (not yet implemented)
* Online filesystem defragmentation
MAILING LIST
============
There is a Btrfs mailing list hosted on vger.kernel.org. You can
find details on how to subscribe here:
http://vger.kernel.org/vger-lists.html#linux-btrfs
Mailing list archives are available from gmane:
http://dir.gmane.org/gmane.comp.file-systems.btrfs
IRC
===
Discussion of Btrfs also occurs on the #btrfs channel of the Freenode
IRC network.
UTILITIES
=========
Userspace tools for creating and manipulating Btrfs file systems are
available from the git repository at the following location:
http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-progs-unstable.git
git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-progs-unstable.git
These include the following tools:
mkfs.btrfs: create a filesystem
btrfsctl: control program to create snapshots and subvolumes:
mount /dev/sda2 /mnt
btrfsctl -s new_subvol_name /mnt
btrfsctl -s snapshot_of_default /mnt/default
btrfsctl -s snapshot_of_new_subvol /mnt/new_subvol_name
btrfsctl -s snapshot_of_a_snapshot /mnt/snapshot_of_new_subvol
ls /mnt
default snapshot_of_a_snapshot snapshot_of_new_subvol
new_subvol_name snapshot_of_default
Snapshots and subvolumes cannot be deleted right now, but you can
rm -rf all the files and directories inside them.
btrfsck: do a limited check of the FS extent trees.
btrfs-debug-tree: print all of the FS metadata in text form. Example:
btrfs-debug-tree /dev/sda2 >& big_output_file
To support containers, we now allow multiple instances of devpts filesystem,
such that indices of ptys allocated in one instance are independent of indices
allocated in other instances of devpts.
To preserve backward compatibility, this support for multiple instances is
enabled only if:
- CONFIG_DEVPTS_MULTIPLE_INSTANCES=y, and
- '-o newinstance' mount option is specified while mounting devpts
IOW, devpts now supports both single-instance and multi-instance semantics.
If CONFIG_DEVPTS_MULTIPLE_INSTANCES=n, there is no change in behavior and
this referred to as the "legacy" mode. In this mode, the new mount options
(-o newinstance and -o ptmxmode) will be ignored with a 'bogus option' message
on console.
If CONFIG_DEVPTS_MULTIPLE_INSTANCES=y and devpts is mounted without the
'newinstance' option (as in current start-up scripts) the new mount binds
to the initial kernel mount of devpts. This mode is referred to as the
'single-instance' mode and the current, single-instance semantics are
preserved, i.e PTYs are common across the system.
The only difference between this single-instance mode and the legacy mode
is the presence of new, '/dev/pts/ptmx' node with permissions 0000, which
can safely be ignored.
If CONFIG_DEVPTS_MULTIPLE_INSTANCES=y and 'newinstance' option is specified,
the mount is considered to be in the multi-instance mode and a new instance
of the devpts fs is created. Any ptys created in this instance are independent
of ptys in other instances of devpts. Like in the single-instance mode, the
/dev/pts/ptmx node is present. To effectively use the multi-instance mode,
open of /dev/ptmx must be a redirected to '/dev/pts/ptmx' using a symlink or
bind-mount.
Eg: A container startup script could do the following:
$ chmod 0666 /dev/pts/ptmx
$ rm /dev/ptmx
$ ln -s pts/ptmx /dev/ptmx
$ ns_exec -cm /bin/bash
# We are now in new container
$ umount /dev/pts
$ mount -t devpts -o newinstance lxcpts /dev/pts
$ sshd -p 1234
where 'ns_exec -cm /bin/bash' calls clone() with CLONE_NEWNS flag and execs
/bin/bash in the child process. A pty created by the sshd is not visible in
the original mount of /dev/pts.
User-space changes
------------------
In multi-instance mode (i.e '-o newinstance' mount option is specified at least
once), following user-space issues should be noted.
1. If -o newinstance mount option is never used, /dev/pts/ptmx can be ignored
and no change is needed to system-startup scripts.
2. To effectively use multi-instance mode (i.e -o newinstance is specified)
administrators or startup scripts should "redirect" open of /dev/ptmx to
/dev/pts/ptmx using either a bind mount or symlink.
$ mount -t devpts -o newinstance devpts /dev/pts
followed by either
$ rm /dev/ptmx
$ ln -s pts/ptmx /dev/ptmx
$ chmod 666 /dev/pts/ptmx
or
$ mount -o bind /dev/pts/ptmx /dev/ptmx
3. The '/dev/ptmx -> pts/ptmx' symlink is the preferred method since it
enables better error-reporting and treats both single-instance and
multi-instance mounts similarly.
But this method requires that system-startup scripts set the mode of
/dev/pts/ptmx correctly (default mode is 0000). The scripts can set the
mode by, either
- adding ptmxmode mount option to devpts entry in /etc/fstab, or
- using 'chmod 0666 /dev/pts/ptmx'
4. If multi-instance mode mount is needed for containers, but the system
startup scripts have not yet been updated, container-startup scripts
should bind mount /dev/ptmx to /dev/pts/ptmx to avoid breaking single-
instance mounts.
Or, in general, container-startup scripts should use:
mount -t devpts -o newinstance -o ptmxmode=0666 devpts /dev/pts
if [ ! -L /dev/ptmx ]; then
mount -o bind /dev/pts/ptmx /dev/ptmx
fi
When all devpts mounts are multi-instance, /dev/ptmx can permanently be
a symlink to pts/ptmx and the bind mount can be ignored.
5. A multi-instance mount that is not accompanied by the /dev/ptmx to
/dev/pts/ptmx redirection would result in an unusable/unreachable pty.
mount -t devpts -o newinstance lxcpts /dev/pts
immediately followed by:
open("/dev/ptmx")
would create a pty, say /dev/pts/7, in the initial kernel mount.
But /dev/pts/7 would be invisible in the new mount.
6. The permissions for /dev/pts/ptmx node should be specified when mounting
/dev/pts, using the '-o ptmxmode=%o' mount option (default is 0000).
mount -t devpts -o newinstance -o ptmxmode=0644 devpts /dev/pts
The permissions can be later be changed as usual with 'chmod'.
chmod 666 /dev/pts/ptmx
7. A mount of devpts without the 'newinstance' option results in binding to
initial kernel mount. This behavior while preserving legacy semantics,
does not provide strict isolation in a container environment. i.e by
mounting devpts without the 'newinstance' option, a container could
get visibility into the 'host' or root container's devpts.
To workaround this and have strict isolation, all mounts of devpts,
including the mount in the root container, should use the newinstance
option.
...@@ -58,13 +58,22 @@ Note: More extensive information for getting started with ext4 can be ...@@ -58,13 +58,22 @@ Note: More extensive information for getting started with ext4 can be
# mount -t ext4 /dev/hda1 /wherever # mount -t ext4 /dev/hda1 /wherever
- When comparing performance with other filesystems, remember that - When comparing performance with other filesystems, it's always
ext3/4 by default offers higher data integrity guarantees than most. important to try multiple workloads; very often a subtle change in a
So when comparing with a metadata-only journalling filesystem, such workload parameter can completely change the ranking of which
as ext3, use `mount -o data=writeback'. And you might as well use filesystems do well compared to others. When comparing versus ext3,
`mount -o nobh' too along with it. Making the journal larger than note that ext4 enables write barriers by default, while ext3 does
the mke2fs default often helps performance with metadata-intensive not enable write barriers by default. So it is useful to use
workloads. explicitly specify whether barriers are enabled or not when via the
'-o barriers=[0|1]' mount option for both ext3 and ext4 filesystems
for a fair comparison. When tuning ext3 for best benchmark numbers,
it is often worthwhile to try changing the data journaling mode; '-o
data=writeback,nobh' can be faster for some workloads. (Note
however that running mounted with data=writeback can potentially
leave stale data exposed in recently written files in case of an
unclean shutdown, which could be a security exposure in some
situations.) Configuring the filesystem with a large journal can
also be helpful for metadata-intensive workloads.
2. Features 2. Features
=========== ===========
...@@ -74,7 +83,7 @@ Note: More extensive information for getting started with ext4 can be ...@@ -74,7 +83,7 @@ Note: More extensive information for getting started with ext4 can be
* ability to use filesystems > 16TB (e2fsprogs support not available yet) * ability to use filesystems > 16TB (e2fsprogs support not available yet)
* extent format reduces metadata overhead (RAM, IO for access, transactions) * extent format reduces metadata overhead (RAM, IO for access, transactions)
* extent format more robust in face of on-disk corruption due to magics, * extent format more robust in face of on-disk corruption due to magics,
* internal redunancy in tree * internal redundancy in tree
* improved file allocation (multi-block alloc) * improved file allocation (multi-block alloc)
* fix 32000 subdirectory limit * fix 32000 subdirectory limit
* nsec timestamps for mtime, atime, ctime, create time * nsec timestamps for mtime, atime, ctime, create time
...@@ -116,10 +125,11 @@ grouping of bitmaps and inode tables. Some test results available here: ...@@ -116,10 +125,11 @@ grouping of bitmaps and inode tables. Some test results available here:
When mounting an ext4 filesystem, the following option are accepted: When mounting an ext4 filesystem, the following option are accepted:
(*) == default (*) == default
extents (*) ext4 will use extents to address file data. The ro Mount filesystem read only. Note that ext4 will
file system will no longer be mountable by ext3. replay the journal (and thus write to the
partition) even when mounted "read only". The
noextents ext4 will not use extents for newly created files mount options "ro,noload" can be used to prevent
writes to the filesystem.
journal_checksum Enable checksumming of the journal transactions. journal_checksum Enable checksumming of the journal transactions.
This will allow the recovery code in e2fsck and the This will allow the recovery code in e2fsck and the
...@@ -134,17 +144,17 @@ journal_async_commit Commit block can be written to disk without waiting ...@@ -134,17 +144,17 @@ journal_async_commit Commit block can be written to disk without waiting
journal=update Update the ext4 file system's journal to the current journal=update Update the ext4 file system's journal to the current
format. format.
journal=inum When a journal already exists, this option is ignored.
Otherwise, it specifies the number of the inode which
will represent the ext4 file system's journal file.
journal_dev=devnum When the external journal device's major/minor numbers journal_dev=devnum When the external journal device's major/minor numbers
have changed, this option allows the user to specify have changed, this option allows the user to specify
the new journal location. The journal device is the new journal location. The journal device is
identified through its new major/minor numbers encoded identified through its new major/minor numbers encoded
in devnum. in devnum.
noload Don't load the journal on mounting. noload Don't load the journal on mounting. Note that
if the filesystem was not unmounted cleanly,
skipping the journal replay will lead to the
filesystem containing inconsistencies that can
lead to any number of problems.
data=journal All data are committed into the journal prior to being data=journal All data are committed into the journal prior to being
written into the main file system. written into the main file system.
...@@ -219,9 +229,12 @@ minixdf Make 'df' act like Minix. ...@@ -219,9 +229,12 @@ minixdf Make 'df' act like Minix.
debug Extra debugging information is sent to syslog. debug Extra debugging information is sent to syslog.
errors=remount-ro(*) Remount the filesystem read-only on an error. errors=remount-ro Remount the filesystem read-only on an error.
errors=continue Keep going on a filesystem error. errors=continue Keep going on a filesystem error.
errors=panic Panic and halt the machine if an error occurs. errors=panic Panic and halt the machine if an error occurs.
(These mount options override the errors behavior
specified in the superblock, which can be configured
using tune2fs)
data_err=ignore(*) Just print an error message if an error occurs data_err=ignore(*) Just print an error message if an error occurs
in a file data buffer in ordered mode. in a file data buffer in ordered mode.
...@@ -261,6 +274,42 @@ delalloc (*) Deferring block allocation until write-out time. ...@@ -261,6 +274,42 @@ delalloc (*) Deferring block allocation until write-out time.
nodelalloc Disable delayed allocation. Blocks are allocation nodelalloc Disable delayed allocation. Blocks are allocation
when data is copied from user to page cache. when data is copied from user to page cache.
max_batch_time=usec Maximum amount of time ext4 should wait for
additional filesystem operations to be batch
together with a synchronous write operation.
Since a synchronous write operation is going to
force a commit and then a wait for the I/O
complete, it doesn't cost much, and can be a
huge throughput win, we wait for a small amount
of time to see if any other transactions can
piggyback on the synchronous write. The
algorithm used is designed to automatically tune
for the speed of the disk, by measuring the
amount of time (on average) that it takes to
finish committing a transaction. Call this time
the "commit time". If the time that the
transactoin has been running is less than the
commit time, ext4 will try sleeping for the
commit time to see if other operations will join
the transaction. The commit time is capped by
the max_batch_time, which defaults to 15000us
(15ms). This optimization can be turned off
entirely by setting max_batch_time to 0.
min_batch_time=usec This parameter sets the commit time (as
described above) to be at least min_batch_time.
It defaults to zero microseconds. Increasing
this parameter may improve the throughput of
multi-threaded, synchronous workloads on very
fast disks, at the cost of increasing latency.
journal_ioprio=prio The I/O priority (from 0 to 7, where 0 is the
highest priorty) which should be used for I/O
operations submitted by kjournald2 during a
commit operation. This defaults to 3, which is
a slightly higher priority than the default I/O
priority.
Data Mode Data Mode
========= =========
There are 3 different data modes: There are 3 different data modes:
......
...@@ -76,13 +76,13 @@ the fdtable structure - ...@@ -76,13 +76,13 @@ the fdtable structure -
5. Handling of the file structures is special. Since the look-up 5. Handling of the file structures is special. Since the look-up
of the fd (fget()/fget_light()) are lock-free, it is possible of the fd (fget()/fget_light()) are lock-free, it is possible
that look-up may race with the last put() operation on the that look-up may race with the last put() operation on the
file structure. This is avoided using atomic_inc_not_zero() file structure. This is avoided using atomic_long_inc_not_zero()
on ->f_count : on ->f_count :
rcu_read_lock(); rcu_read_lock();
file = fcheck_files(files, fd); file = fcheck_files(files, fd);
if (file) { if (file) {
if (atomic_inc_not_zero(&file->f_count)) if (atomic_long_inc_not_zero(&file->f_count))
*fput_needed = 1; *fput_needed = 1;
else else
/* Didn't get the reference, someone's freed */ /* Didn't get the reference, someone's freed */
...@@ -92,7 +92,7 @@ the fdtable structure - ...@@ -92,7 +92,7 @@ the fdtable structure -
.... ....
return file; return file;
atomic_inc_not_zero() detects if refcounts is already zero or atomic_long_inc_not_zero() detects if refcounts is already zero or
goes to zero during increment. If it does, we fail goes to zero during increment. If it does, we fail
fget()/fget_light(). fget()/fget_light().
......
...@@ -251,7 +251,7 @@ NFS/RDMA Setup ...@@ -251,7 +251,7 @@ NFS/RDMA Setup
Instruct the server to listen on the RDMA transport: Instruct the server to listen on the RDMA transport:
$ echo rdma 2050 > /proc/fs/nfsd/portlist $ echo rdma 20049 > /proc/fs/nfsd/portlist
- On the client system - On the client system
...@@ -263,7 +263,7 @@ NFS/RDMA Setup ...@@ -263,7 +263,7 @@ NFS/RDMA Setup
Regardless of how the client was built (module or built-in), use this Regardless of how the client was built (module or built-in), use this
command to mount the NFS/RDMA server: command to mount the NFS/RDMA server:
$ mount -o rdma,port=2050 <IPoIB-server-name-or-address>:/<export> /mnt $ mount -o rdma,port=20049 <IPoIB-server-name-or-address>:/<export> /mnt
To verify that the mount is using RDMA, run "cat /proc/mounts" and check To verify that the mount is using RDMA, run "cat /proc/mounts" and check
the "proto" field for the given mount. the "proto" field for the given mount.
......
...@@ -31,7 +31,6 @@ Features which OCFS2 does not support yet: ...@@ -31,7 +31,6 @@ Features which OCFS2 does not support yet:
- quotas - quotas
- Directory change notification (F_NOTIFY) - Directory change notification (F_NOTIFY)
- Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease) - Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease)
- POSIX ACLs
Mount options Mount options
============= =============
...@@ -79,3 +78,5 @@ inode64 Indicates that Ocfs2 is allowed to create inodes at ...@@ -79,3 +78,5 @@ inode64 Indicates that Ocfs2 is allowed to create inodes at
bits of significance. bits of significance.
user_xattr (*) Enables Extended User Attributes. user_xattr (*) Enables Extended User Attributes.
nouser_xattr Disables Extended User Attributes. nouser_xattr Disables Extended User Attributes.
acl Enables POSIX Access Control Lists support.
noacl (*) Disables POSIX Access Control Lists support.
...@@ -140,6 +140,7 @@ Table 1-1: Process specific entries in /proc ...@@ -140,6 +140,7 @@ Table 1-1: Process specific entries in /proc
statm Process memory status information statm Process memory status information
status Process status in human readable form status Process status in human readable form
wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan
stack Report full stack trace, enable via CONFIG_STACKTRACE
smaps Extension based on maps, the rss size for each mapped file smaps Extension based on maps, the rss size for each mapped file
.............................................................................. ..............................................................................
...@@ -1370,268 +1371,8 @@ auto_msgmni default value is 1. ...@@ -1370,268 +1371,8 @@ auto_msgmni default value is 1.
2.4 /proc/sys/vm - The virtual memory subsystem 2.4 /proc/sys/vm - The virtual memory subsystem
----------------------------------------------- -----------------------------------------------
The files in this directory can be used to tune the operation of the virtual Please see: Documentation/sysctls/vm.txt for a description of these
memory (VM) subsystem of the Linux kernel. entries.
vfs_cache_pressure
------------------
Controls the tendency of the kernel to reclaim the memory which is used for
caching of directory and inode objects.
At the default value of vfs_cache_pressure=100 the kernel will attempt to
reclaim dentries and inodes at a "fair" rate with respect to pagecache and
swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer
to retain dentry and inode caches. Increasing vfs_cache_pressure beyond 100
causes the kernel to prefer to reclaim dentries and inodes.
dirty_background_ratio
----------------------
Contains, as a percentage of the dirtyable system memory (free pages + mapped
pages + file cache, not including locked pages and HugePages), the number of
pages at which the pdflush background writeback daemon will start writing out
dirty data.
dirty_ratio
-----------------
Contains, as a percentage of the dirtyable system memory (free pages + mapped
pages + file cache, not including locked pages and HugePages), the number of
pages at which a process which is generating disk writes will itself start
writing out dirty data.
dirty_writeback_centisecs
-------------------------
The pdflush writeback daemons will periodically wake up and write `old' data
out to disk. This tunable expresses the interval between those wakeups, in
100'ths of a second.
Setting this to zero disables periodic writeback altogether.
dirty_expire_centisecs
----------------------
This tunable is used to define when dirty data is old enough to be eligible
for writeout by the pdflush daemons. It is expressed in 100'ths of a second.
Data which has been dirty in-memory for longer than this interval will be
written out next time a pdflush daemon wakes up.
highmem_is_dirtyable
--------------------
Only present if CONFIG_HIGHMEM is set.
This defaults to 0 (false), meaning that the ratios set above are calculated
as a percentage of lowmem only. This protects against excessive scanning
in page reclaim, swapping and general VM distress.
Setting this to 1 can be useful on 32 bit machines where you want to make
random changes within an MMAPed file that is larger than your available
lowmem without causing large quantities of random IO. Is is safe if the
behavior of all programs running on the machine is known and memory will
not be otherwise stressed.
legacy_va_layout
----------------
If non-zero, this sysctl disables the new 32-bit mmap mmap layout - the kernel
will use the legacy (2.4) layout for all processes.
lowmem_reserve_ratio
---------------------
For some specialised workloads on highmem machines it is dangerous for
the kernel to allow process memory to be allocated from the "lowmem"
zone. This is because that memory could then be pinned via the mlock()
system call, or by unavailability of swapspace.
And on large highmem machines this lack of reclaimable lowmem memory
can be fatal.
So the Linux page allocator has a mechanism which prevents allocations
which _could_ use highmem from using too much lowmem. This means that
a certain amount of lowmem is defended from the possibility of being
captured into pinned user memory.
(The same argument applies to the old 16 megabyte ISA DMA region. This
mechanism will also defend that region from allocations which could use
highmem or lowmem).
The `lowmem_reserve_ratio' tunable determines how aggressive the kernel is
in defending these lower zones.
If you have a machine which uses highmem or ISA DMA and your
applications are using mlock(), or if you are running with no swap then
you probably should change the lowmem_reserve_ratio setting.
The lowmem_reserve_ratio is an array. You can see them by reading this file.
-
% cat /proc/sys/vm/lowmem_reserve_ratio
256 256 32
-
Note: # of this elements is one fewer than number of zones. Because the highest
zone's value is not necessary for following calculation.
But, these values are not used directly. The kernel calculates # of protection
pages for each zones from them. These are shown as array of protection pages
in /proc/zoneinfo like followings. (This is an example of x86-64 box).
Each zone has an array of protection pages like this.
-
Node 0, zone DMA
pages free 1355
min 3
low 3
high 4
:
:
numa_other 0
protection: (0, 2004, 2004, 2004)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pagesets
cpu: 0 pcp: 0
:
-
These protections are added to score to judge whether this zone should be used
for page allocation or should be reclaimed.
In this example, if normal pages (index=2) are required to this DMA zone and
pages_high is used for watermark, the kernel judges this zone should not be
used because pages_free(1355) is smaller than watermark + protection[2]
(4 + 2004 = 2008). If this protection value is 0, this zone would be used for
normal page requirement. If requirement is DMA zone(index=0), protection[0]
(=0) is used.
zone[i]'s protection[j] is calculated by following expression.
(i < j):
zone[i]->protection[j]
= (total sums of present_pages from zone[i+1] to zone[j] on the node)
/ lowmem_reserve_ratio[i];
(i = j):
(should not be protected. = 0;
(i > j):
(not necessary, but looks 0)
The default values of lowmem_reserve_ratio[i] are
256 (if zone[i] means DMA or DMA32 zone)
32 (others).
As above expression, they are reciprocal number of ratio.
256 means 1/256. # of protection pages becomes about "0.39%" of total present
pages of higher zones on the node.
If you would like to protect more pages, smaller values are effective.
The minimum value is 1 (1/1 -> 100%).
page-cluster
------------
page-cluster controls the number of pages which are written to swap in
a single attempt. The swap I/O size.
It is a logarithmic value - setting it to zero means "1 page", setting
it to 1 means "2 pages", setting it to 2 means "4 pages", etc.
The default value is three (eight pages at a time). There may be some
small benefits in tuning this to a different value if your workload is
swap-intensive.
overcommit_memory
-----------------
Controls overcommit of system memory, possibly allowing processes
to allocate (but not use) more memory than is actually available.
0 - Heuristic overcommit handling. Obvious overcommits of
address space are refused. Used for a typical system. It
ensures a seriously wild allocation fails while allowing
overcommit to reduce swap usage. root is allowed to
allocate slightly more memory in this mode. This is the
default.
1 - Always overcommit. Appropriate for some scientific
applications.
2 - Don't overcommit. The total address space commit
for the system is not permitted to exceed swap plus a
configurable percentage (default is 50) of physical RAM.
Depending on the percentage you use, in most situations
this means a process will not be killed while attempting
to use already-allocated memory but will receive errors
on memory allocation as appropriate.
overcommit_ratio
----------------
Percentage of physical memory size to include in overcommit calculations
(see above.)
Memory allocation limit = swapspace + physmem * (overcommit_ratio / 100)
swapspace = total size of all swap areas
physmem = size of physical memory in system
nr_hugepages and hugetlb_shm_group
----------------------------------
nr_hugepages configures number of hugetlb page reserved for the system.
hugetlb_shm_group contains group id that is allowed to create SysV shared
memory segment using hugetlb page.
hugepages_treat_as_movable
--------------------------
This parameter is only useful when kernelcore= is specified at boot time to
create ZONE_MOVABLE for pages that may be reclaimed or migrated. Huge pages
are not movable so are not normally allocated from ZONE_MOVABLE. A non-zero
value written to hugepages_treat_as_movable allows huge pages to be allocated
from ZONE_MOVABLE.
Once enabled, the ZONE_MOVABLE is treated as an area of memory the huge
pages pool can easily grow or shrink within. Assuming that applications are
not running that mlock() a lot of memory, it is likely the huge pages pool
can grow to the size of ZONE_MOVABLE by repeatedly entering the desired value
into nr_hugepages and triggering page reclaim.
laptop_mode
-----------
laptop_mode is a knob that controls "laptop mode". All the things that are
controlled by this knob are discussed in Documentation/laptops/laptop-mode.txt.
block_dump
----------
block_dump enables block I/O debugging when set to a nonzero value. More
information on block I/O debugging is in Documentation/laptops/laptop-mode.txt.
swap_token_timeout
------------------
This file contains valid hold time of swap out protection token. The Linux
VM has token based thrashing control mechanism and uses the token to prevent
unnecessary page faults in thrashing situation. The unit of the value is
second. The value would be useful to tune thrashing behavior.
drop_caches
-----------
Writing to this will cause the kernel to drop clean caches, dentries and
inodes from memory, causing that memory to become free.
To free pagecache:
echo 1 > /proc/sys/vm/drop_caches
To free dentries and inodes:
echo 2 > /proc/sys/vm/drop_caches
To free pagecache, dentries and inodes:
echo 3 > /proc/sys/vm/drop_caches
As this is a non-destructive operation and dirty objects are not freeable, the
user should run `sync' first.
2.5 /proc/sys/dev - Device specific parameters 2.5 /proc/sys/dev - Device specific parameters
...@@ -2286,6 +2027,34 @@ increase the likelihood of this process being killed by the oom-killer. Valid ...@@ -2286,6 +2027,34 @@ increase the likelihood of this process being killed by the oom-killer. Valid
values are in the range -16 to +15, plus the special value -17, which disables values are in the range -16 to +15, plus the special value -17, which disables
oom-killing altogether for this process. oom-killing altogether for this process.
The process to be killed in an out-of-memory situation is selected among all others
based on its badness score. This value equals the original memory size of the process
and is then updated according to its CPU time (utime + stime) and the
run time (uptime - start time). The longer it runs the smaller is the score.
Badness score is divided by the square root of the CPU time and then by
the double square root of the run time.
Swapped out tasks are killed first. Half of each child's memory size is added to
the parent's score if they do not share the same memory. Thus forking servers
are the prime candidates to be killed. Having only one 'hungry' child will make
parent less preferable than the child.
/proc/<pid>/oom_score shows process' current badness score.
The following heuristics are then applied:
* if the task was reniced, its score doubles
* superuser or direct hardware access tasks (CAP_SYS_ADMIN, CAP_SYS_RESOURCE
or CAP_SYS_RAWIO) have their score divided by 4
* if oom condition happened in one cpuset and checked task does not belong
to it, its score is divided by 8
* the resulting score is multiplied by two to the power of oom_adj, i.e.
points <<= oom_adj when it is positive and
points >>= -(oom_adj) otherwise
The task with the highest badness score is then selected and its children
are killed, process itself will be killed in an OOM situation when it does
not have children or some of them disabled oom like described above.
2.13 /proc/<pid>/oom_score - Display current oom-killer score 2.13 /proc/<pid>/oom_score - Display current oom-killer score
------------------------------------------------------------- -------------------------------------------------------------
......
SQUASHFS 4.0 FILESYSTEM
=======================
Squashfs is a compressed read-only filesystem for Linux.
It uses zlib compression to compress files, inodes and directories.
Inodes in the system are very small and all blocks are packed to minimise
data overhead. Block sizes greater than 4K are supported up to a maximum
of 1Mbytes (default block size 128K).
Squashfs is intended for general read-only filesystem use, for archival
use (i.e. in cases where a .tar.gz file may be used), and in constrained
block device/memory systems (e.g. embedded systems) where low overhead is
needed.
Mailing list: squashfs-devel@lists.sourceforge.net
Web site: www.squashfs.org
1. FILESYSTEM FEATURES
----------------------
Squashfs filesystem features versus Cramfs:
Squashfs Cramfs
Max filesystem size: 2^64 16 MiB
Max file size: ~ 2 TiB 16 MiB
Max files: unlimited unlimited
Max directories: unlimited unlimited
Max entries per directory: unlimited unlimited
Max block size: 1 MiB 4 KiB
Metadata compression: yes no
Directory indexes: yes no
Sparse file support: yes no
Tail-end packing (fragments): yes no
Exportable (NFS etc.): yes no
Hard link support: yes no
"." and ".." in readdir: yes no
Real inode numbers: yes no
32-bit uids/gids: yes no
File creation time: yes no
Xattr and ACL support: no no
Squashfs compresses data, inodes and directories. In addition, inode and
directory data are highly compacted, and packed on byte boundaries. Each
compressed inode is on average 8 bytes in length (the exact length varies on
file type, i.e. regular file, directory, symbolic link, and block/char device
inodes have different sizes).
2. USING SQUASHFS
-----------------
As squashfs is a read-only filesystem, the mksquashfs program must be used to
create populated squashfs filesystems. This and other squashfs utilities
can be obtained from http://www.squashfs.org. Usage instructions can be
obtained from this site also.
3. SQUASHFS FILESYSTEM DESIGN
-----------------------------
A squashfs filesystem consists of seven parts, packed together on a byte
alignment:
---------------
| superblock |
|---------------|
| datablocks |
| & fragments |
|---------------|
| inode table |
|---------------|
| directory |
| table |
|---------------|
| fragment |
| table |
|---------------|
| export |
| table |
|---------------|
| uid/gid |
| lookup table |
---------------
Compressed data blocks are written to the filesystem as files are read from
the source directory, and checked for duplicates. Once all file data has been
written the completed inode, directory, fragment, export and uid/gid lookup
tables are written.
3.1 Inodes
----------
Metadata (inodes and directories) are compressed in 8Kbyte blocks. Each
compressed block is prefixed by a two byte length, the top bit is set if the
block is uncompressed. A block will be uncompressed if the -noI option is set,
or if the compressed block was larger than the uncompressed block.
Inodes are packed into the metadata blocks, and are not aligned to block
boundaries, therefore inodes overlap compressed blocks. Inodes are identified
by a 48-bit number which encodes the location of the compressed metadata block
containing the inode, and the byte offset into that block where the inode is
placed (<block, offset>).
To maximise compression there are different inodes for each file type
(regular file, directory, device, etc.), the inode contents and length
varying with the type.
To further maximise compression, two types of regular file inode and
directory inode are defined: inodes optimised for frequently occurring
regular files and directories, and extended types where extra
information has to be stored.
3.2 Directories
---------------
Like inodes, directories are packed into compressed metadata blocks, stored
in a directory table. Directories are accessed using the start address of
the metablock containing the directory and the offset into the
decompressed block (<block, offset>).
Directories are organised in a slightly complex way, and are not simply
a list of file names. The organisation takes advantage of the
fact that (in most cases) the inodes of the files will be in the same
compressed metadata block, and therefore, can share the start block.
Directories are therefore organised in a two level list, a directory
header containing the shared start block value, and a sequence of directory
entries, each of which share the shared start block. A new directory header
is written once/if the inode start block changes. The directory
header/directory entry list is repeated as many times as necessary.
Directories are sorted, and can contain a directory index to speed up
file lookup. Directory indexes store one entry per metablock, each entry
storing the index/filename mapping to the first directory header
in each metadata block. Directories are sorted in alphabetical order,
and at lookup the index is scanned linearly looking for the first filename
alphabetically larger than the filename being looked up. At this point the
location of the metadata block the filename is in has been found.
The general idea of the index is ensure only one metadata block needs to be
decompressed to do a lookup irrespective of the length of the directory.
This scheme has the advantage that it doesn't require extra memory overhead
and doesn't require much extra storage on disk.
3.3 File data
-------------
Regular files consist of a sequence of contiguous compressed blocks, and/or a
compressed fragment block (tail-end packed block). The compressed size
of each datablock is stored in a block list contained within the
file inode.
To speed up access to datablocks when reading 'large' files (256 Mbytes or
larger), the code implements an index cache that caches the mapping from
block index to datablock location on disk.
The index cache allows Squashfs to handle large files (up to 1.75 TiB) while
retaining a simple and space-efficient block list on disk. The cache
is split into slots, caching up to eight 224 GiB files (128 KiB blocks).
Larger files use multiple slots, with 1.75 TiB files using all 8 slots.
The index cache is designed to be memory efficient, and by default uses
16 KiB.
3.4 Fragment lookup table
-------------------------
Regular files can contain a fragment index which is mapped to a fragment
location on disk and compressed size using a fragment lookup table. This
fragment lookup table is itself stored compressed into metadata blocks.
A second index table is used to locate these. This second index table for
speed of access (and because it is small) is read at mount time and cached
in memory.
3.5 Uid/gid lookup table
------------------------
For space efficiency regular files store uid and gid indexes, which are
converted to 32-bit uids/gids using an id look up table. This table is
stored compressed into metadata blocks. A second index table is used to
locate these. This second index table for speed of access (and because it
is small) is read at mount time and cached in memory.
3.6 Export table
----------------
To enable Squashfs filesystems to be exportable (via NFS etc.) filesystems
can optionally (disabled with the -no-exports Mksquashfs option) contain
an inode number to inode disk location lookup table. This is required to
enable Squashfs to map inode numbers passed in filehandles to the inode
location on disk, which is necessary when the export code reinstantiates
expired/flushed inodes.
This table is stored compressed into metadata blocks. A second index table is
used to locate these. This second index table for speed of access (and because
it is small) is read at mount time and cached in memory.
4. TODOS AND OUTSTANDING ISSUES
-------------------------------
4.1 Todo list
-------------
Implement Xattr and ACL support. The Squashfs 4.0 filesystem layout has hooks
for these but the code has not been written. Once the code has been written
the existing layout should not require modification.
4.2 Squashfs internal cache
---------------------------
Blocks in Squashfs are compressed. To avoid repeatedly decompressing
recently accessed data Squashfs uses two small metadata and fragment caches.
The cache is not used for file datablocks, these are decompressed and cached in
the page-cache in the normal way. The cache is used to temporarily cache
fragment and metadata blocks which have been read as a result of a metadata
(i.e. inode or directory) or fragment access. Because metadata and fragments
are packed together into blocks (to gain greater compression) the read of a
particular piece of metadata or fragment will retrieve other metadata/fragments
which have been packed with it, these because of locality-of-reference may be
read in the near future. Temporarily caching them ensures they are available
for near future access without requiring an additional read and decompress.
In the future this internal cache may be replaced with an implementation which
uses the kernel page cache. Because the page cache operates on page sized
units this may introduce additional complexity in terms of locking and
associated race conditions.
...@@ -79,13 +79,6 @@ Mount options ...@@ -79,13 +79,6 @@ Mount options
(*) == default. (*) == default.
norm_unmount (*) commit on unmount; the journal is committed
when the file-system is unmounted so that the
next mount does not have to replay the journal
and it becomes very fast;
fast_unmount do not commit on unmount; this option makes
unmount faster, but the next mount slower
because of the need to replay the journal.
bulk_read read more in one go to take advantage of flash bulk_read read more in one go to take advantage of flash
media that read faster sequentially media that read faster sequentially
no_bulk_read (*) do not bulk-read no_bulk_read (*) do not bulk-read
...@@ -95,6 +88,9 @@ no_chk_data_crc skip checking of CRCs on data nodes in order to ...@@ -95,6 +88,9 @@ no_chk_data_crc skip checking of CRCs on data nodes in order to
of this option is that corruption of the contents of this option is that corruption of the contents
of a file can go unnoticed. of a file can go unnoticed.
chk_data_crc (*) do not skip checking CRCs on data nodes chk_data_crc (*) do not skip checking CRCs on data nodes
compr=none override default compressor and set it to "none"
compr=lzo override default compressor and set it to "lzo"
compr=zlib override default compressor and set it to "zlib"
Quick usage instructions Quick usage instructions
......
...@@ -210,8 +210,8 @@ struct super_operations { ...@@ -210,8 +210,8 @@ struct super_operations {
void (*put_super) (struct super_block *); void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *); void (*write_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait); int (*sync_fs)(struct super_block *sb, int wait);
void (*write_super_lockfs) (struct super_block *); int (*freeze_fs) (struct super_block *);
void (*unlockfs) (struct super_block *); int (*unfreeze_fs) (struct super_block *);
int (*statfs) (struct dentry *, struct kstatfs *); int (*statfs) (struct dentry *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *); int (*remount_fs) (struct super_block *, int *, char *);
void (*clear_inode) (struct inode *); void (*clear_inode) (struct inode *);
...@@ -270,11 +270,11 @@ or bottom half). ...@@ -270,11 +270,11 @@ or bottom half).
a superblock. The second parameter indicates whether the method a superblock. The second parameter indicates whether the method
should wait until the write out has been completed. Optional. should wait until the write out has been completed. Optional.
write_super_lockfs: called when VFS is locking a filesystem and freeze_fs: called when VFS is locking a filesystem and
forcing it into a consistent state. This method is currently forcing it into a consistent state. This method is currently
used by the Logical Volume Manager (LVM). used by the Logical Volume Manager (LVM).
unlockfs: called when VFS is unlocking a filesystem and making it writable unfreeze_fs: called when VFS is unlocking a filesystem and making it writable
again. again.
statfs: called when the VFS needs to get filesystem statistics. This statfs: called when the VFS needs to get filesystem statistics. This
...@@ -733,7 +733,6 @@ struct file_operations { ...@@ -733,7 +733,6 @@ struct file_operations {
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
int (*check_flags)(int); int (*check_flags)(int);
int (*dir_notify)(struct file *filp, unsigned long arg);
int (*flock) (struct file *, int, struct file_lock *); int (*flock) (struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int);
...@@ -800,8 +799,6 @@ otherwise noted. ...@@ -800,8 +799,6 @@ otherwise noted.
check_flags: called by the fcntl(2) system call for F_SETFL command check_flags: called by the fcntl(2) system call for F_SETFL command
dir_notify: called by the fcntl(2) system call for F_NOTIFY command
flock: called by the flock(2) system call flock: called by the flock(2) system call
splice_write: called by the VFS to splice data from a pipe to a file. This splice_write: called by the VFS to splice data from a pipe to a file. This
...@@ -931,7 +928,7 @@ manipulate dentries: ...@@ -931,7 +928,7 @@ manipulate dentries:
d_lookup: look up a dentry given its parent and path name component d_lookup: look up a dentry given its parent and path name component
It looks up the child of that given name from the dcache It looks up the child of that given name from the dcache
hash table. If it is found, the reference count is incremented hash table. If it is found, the reference count is incremented
and the dentry is returned. The caller must use d_put() and the dentry is returned. The caller must use dput()
to free the dentry when it finishes using it. to free the dentry when it finishes using it.
For further information on dentry locking, please refer to the document For further information on dentry locking, please refer to the document
......
...@@ -74,7 +74,7 @@ a sensor. ...@@ -74,7 +74,7 @@ a sensor.
Notice that some banks have both a read and a write address this is how the Notice that some banks have both a read and a write address this is how the
uGuru determines if a read from or a write to the bank is taking place, thus uGuru determines if a read from or a write to the bank is taking place, thus
when reading you should always use the read address and when writing the when reading you should always use the read address and when writing the
write address. The write address is always one (1) more then the read address. write address. The write address is always one (1) more than the read address.
uGuru ready uGuru ready
...@@ -121,7 +121,7 @@ Once all bytes have been read data will hold 0x09, but there is no reason to ...@@ -121,7 +121,7 @@ Once all bytes have been read data will hold 0x09, but there is no reason to
test for this. Notice that the number of bytes is bank address dependent see test for this. Notice that the number of bytes is bank address dependent see
above and below. above and below.
After completing a successfull read it is advised to put the uGuru back in After completing a successful read it is advised to put the uGuru back in
ready mode, so that it is ready for the next read / write cycle. This way ready mode, so that it is ready for the next read / write cycle. This way
if your program / driver is unloaded and later loaded again the detection if your program / driver is unloaded and later loaded again the detection
algorithm described above will still work. algorithm described above will still work.
...@@ -141,7 +141,7 @@ don't ask why this is the way it is. ...@@ -141,7 +141,7 @@ don't ask why this is the way it is.
Once DATA holds 0x01 read CMD it should hold 0xAC now. Once DATA holds 0x01 read CMD it should hold 0xAC now.
After completing a successfull write it is advised to put the uGuru back in After completing a successful write it is advised to put the uGuru back in
ready mode, so that it is ready for the next read / write cycle. This way ready mode, so that it is ready for the next read / write cycle. This way
if your program / driver is unloaded and later loaded again the detection if your program / driver is unloaded and later loaded again the detection
algorithm described above will still work. algorithm described above will still work.
...@@ -224,7 +224,7 @@ Bit 3: Beep if alarm (RW) ...@@ -224,7 +224,7 @@ Bit 3: Beep if alarm (RW)
Bit 4: 1 if alarm cause measured temp is over the warning threshold (R) Bit 4: 1 if alarm cause measured temp is over the warning threshold (R)
Bit 5: 1 if alarm cause measured volt is over the max threshold (R) Bit 5: 1 if alarm cause measured volt is over the max threshold (R)
Bit 6: 1 if alarm cause measured volt is under the min threshold (R) Bit 6: 1 if alarm cause measured volt is under the min threshold (R)
Bit 7: Volt sensor: Shutdown if alarm persist for more then 4 seconds (RW) Bit 7: Volt sensor: Shutdown if alarm persist for more than 4 seconds (RW)
Temp sensor: Shutdown if temp is over the shutdown threshold (RW) Temp sensor: Shutdown if temp is over the shutdown threshold (RW)
* This bit is only honored/used by the uGuru if a temp sensor is connected * This bit is only honored/used by the uGuru if a temp sensor is connected
...@@ -293,7 +293,7 @@ Byte 0: ...@@ -293,7 +293,7 @@ Byte 0:
Alarm behaviour for the selected sensor. A 1 enables the described behaviour. Alarm behaviour for the selected sensor. A 1 enables the described behaviour.
Bit 0: Give an alarm if measured rpm is under the min threshold (RW) Bit 0: Give an alarm if measured rpm is under the min threshold (RW)
Bit 3: Beep if alarm (RW) Bit 3: Beep if alarm (RW)
Bit 7: Shutdown if alarm persist for more then 4 seconds (RW) Bit 7: Shutdown if alarm persist for more than 4 seconds (RW)
Byte 1: Byte 1:
min threshold (scale as bank 0x26) min threshold (scale as bank 0x26)
......
...@@ -31,15 +31,11 @@ Each of the measured inputs (temperature, fan speed) has corresponding high/low ...@@ -31,15 +31,11 @@ Each of the measured inputs (temperature, fan speed) has corresponding high/low
limit values. The ADT7470 will signal an ALARM if any measured value exceeds limit values. The ADT7470 will signal an ALARM if any measured value exceeds
either limit. either limit.
The ADT7470 DOES NOT sample all inputs continuously. A single pin on the The ADT7470 samples all inputs continuously. A kernel thread is started up for
ADT7470 is connected to a multitude of thermal diodes, but the chip must be the purpose of periodically querying the temperature sensors, thus allowing the
instructed explicitly to read the multitude of diodes. If you want to use automatic fan pwm control to set the fan speed. The driver will not read the
automatic fan control mode, you must manually read any of the temperature registers more often than once every 5 seconds. Further, configuration data is
sensors or the fan control algorithm will not run. The chip WILL NOT DO THIS only read once per minute.
AUTOMATICALLY; this must be done from userspace. This may be a bug in the chip
design, given that many other AD chips take care of this. The driver will not
read the registers more often than once every 5 seconds. Further,
configuration data is only read once per minute.
Special Features Special Features
---------------- ----------------
...@@ -72,5 +68,6 @@ pwm#_auto_point2_temp. ...@@ -72,5 +68,6 @@ pwm#_auto_point2_temp.
Notes Notes
----- -----
As stated above, the temperature inputs must be read periodically from The temperature inputs no longer need to be read periodically from userspace in
userspace in order for the automatic pwm algorithm to run. order for the automatic pwm algorithm to run. This was the case for earlier
versions of the driver.
This describes the interface for the ADT7475 driver:
(there are 4 fans, numbered fan1 to fan4):
fanX_input Read the current speed of the fan (in RPMs)
fanX_min Read/write the minimum speed of the fan. Dropping
below this sets an alarm.
(there are three PWMs, numbered pwm1 to pwm3):
pwmX Read/write the current duty cycle of the PWM. Writes
only have effect when auto mode is turned off (see
below). Range is 0 - 255.
pwmX_enable Fan speed control method:
0 - No control (fan at full speed)
1 - Manual fan speed control (using pwm[1-*])
2 - Automatic fan speed control
pwmX_auto_channels_temp Select which channels affect this PWM
1 - TEMP1 controls PWM
2 - TEMP2 controls PWM
4 - TEMP3 controls PWM
6 - TEMP2 and TEMP3 control PWM
7 - All three inputs control PWM
pwmX_freq Read/write the PWM frequency in Hz. The number
should be one of the following:
11 Hz
14 Hz
22 Hz
29 Hz
35 Hz
44 Hz
58 Hz
88 Hz
pwmX_auto_point1_pwm Read/write the minimum PWM duty cycle in automatic mode
pwmX_auto_point2_pwm Read/write the maximum PWM duty cycle in automatic mode
(there are three temperature settings numbered temp1 to temp3):
tempX_input Read the current temperature. The value is in milli
degrees of Celsius.
tempX_max Read/write the upper temperature limit - exceeding this
will cause an alarm.
tempX_min Read/write the lower temperature limit - exceeding this
will cause an alarm.
tempX_offset Read/write the temperature adjustment offset
tempX_crit Read/write the THERM limit for remote1.
tempX_crit_hyst Set the temperature value below crit where the
fans will stay on - this helps drive the temperature
low enough so it doesn't stay near the edge and
cause THERM to keep tripping.
tempX_auto_point1_temp Read/write the minimum temperature where the fans will
turn on in automatic mode.
tempX_auto_point2_temp Read/write the maximum temperature over which the fans
will run in automatic mode. tempX_auto_point1_temp
and tempX_auto_point2_temp together define the
range of automatic control.
tempX_alarm Read a 1 if the max/min alarm is set
tempX_fault Read a 1 if either temp1 or temp3 diode has a fault
(There are two voltage settings, in1 and in2):
inX_input Read the current voltage on VCC. Value is in
millivolts.
inX_min read/write the minimum voltage limit.
Dropping below this causes an alarm.
inX_max read/write the maximum voltage limit.
Exceeding this causes an alarm.
inX_alarm Read a 1 if the max/min alarm is set.
Kernel driver f71882fg
======================
Supported chips:
* Fintek F71882FG and F71883FG
Prefix: 'f71882fg'
Addresses scanned: none, address read from Super I/O config space
Datasheet: Available from the Fintek website
* Fintek F71862FG and F71863FG
Prefix: 'f71862fg'
Addresses scanned: none, address read from Super I/O config space
Datasheet: Available from the Fintek website
* Fintek F8000
Prefix: 'f8000'
Addresses scanned: none, address read from Super I/O config space
Datasheet: Not public
Author: Hans de Goede <hdegoede@redhat.com>
Description
-----------
Fintek F718xxFG/F8000 Super I/O chips include complete hardware monitoring
capabilities. They can monitor up to 9 voltages (3 for the F8000), 4 fans and
3 temperature sensors.
These chips also have fan controlling features, using either DC or PWM, in
three different modes (one manual, two automatic).
The driver assumes that no more than one chip is present, which seems
reasonable.
Monitoring
----------
The Voltage, Fan and Temperature Monitoring uses the standard sysfs
interface as documented in sysfs-interface, without any exceptions.
Fan Control
-----------
Both PWM (pulse-width modulation) and DC fan speed control methods are
supported. The right one to use depends on external circuitry on the
motherboard, so the driver assumes that the BIOS set the method
properly.
There are 2 modes to specify the speed of the fan, PWM duty cycle (or DC
voltage) mode, where 0-100% duty cycle (0-100% of 12V) is specified. And RPM
mode where the actual RPM of the fan (as measured) is controlled and the speed
gets specified as 0-100% of the fan#_full_speed file.
Since both modes work in a 0-100% (mapped to 0-255) scale, there isn't a
whole lot of a difference when modifying fan control settings. The only
important difference is that in RPM mode the 0-100% controls the fan speed
between 0-100% of fan#_full_speed. It is assumed that if the BIOS programs
RPM mode, it will also set fan#_full_speed properly, if it does not then
fan control will not work properly, unless you set a sane fan#_full_speed
value yourself.
Switching between these modes requires re-initializing a whole bunch of
registers, so the mode which the BIOS has set is kept. The mode is
printed when loading the driver.
Three different fan control modes are supported; the mode number is written
to the pwm#_enable file. Note that not all modes are supported on all
chips, and some modes may only be available in RPM / PWM mode on the F8000.
Writing an unsupported mode will result in an invalid parameter error.
* 1: Manual mode
You ask for a specific PWM duty cycle / DC voltage or a specific % of
fan#_full_speed by writing to the pwm# file. This mode is only
available on the F8000 if the fan channel is in RPM mode.
* 2: Normal auto mode
You can define a number of temperature/fan speed trip points, which % the
fan should run at at this temp and which temp a fan should follow using the
standard sysfs interface. The number and type of trip points is chip
depended, see which files are available in sysfs.
Fan/PWM channel 3 of the F8000 is always in this mode!
* 3: Thermostat mode (Only available on the F8000 when in duty cycle mode)
The fan speed is regulated to keep the temp the fan is mapped to between
temp#_auto_point2_temp and temp#_auto_point3_temp.
Both of the automatic modes require that pwm1 corresponds to fan1, pwm2 to
fan2 and pwm3 to fan3.
...@@ -26,6 +26,10 @@ Supported chips: ...@@ -26,6 +26,10 @@ Supported chips:
Datasheet: Publicly available at the ITE website Datasheet: Publicly available at the ITE website
http://www.ite.com.tw/product_info/file/pc/IT8718F_V0.2.zip http://www.ite.com.tw/product_info/file/pc/IT8718F_V0.2.zip
http://www.ite.com.tw/product_info/file/pc/IT8718F_V0%203_(for%20C%20version).zip http://www.ite.com.tw/product_info/file/pc/IT8718F_V0%203_(for%20C%20version).zip
* IT8720F
Prefix: 'it8720'
Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Not yet publicly available.
* SiS950 [clone of IT8705F] * SiS950 [clone of IT8705F]
Prefix: 'it87' Prefix: 'it87'
Addresses scanned: from Super I/O config space (8 I/O ports) Addresses scanned: from Super I/O config space (8 I/O ports)
...@@ -71,7 +75,7 @@ Description ...@@ -71,7 +75,7 @@ Description
----------- -----------
This driver implements support for the IT8705F, IT8712F, IT8716F, This driver implements support for the IT8705F, IT8712F, IT8716F,
IT8718F, IT8726F and SiS950 chips. IT8718F, IT8720F, IT8726F and SiS950 chips.
These chips are 'Super I/O chips', supporting floppy disks, infrared ports, These chips are 'Super I/O chips', supporting floppy disks, infrared ports,
joysticks and other miscellaneous stuff. For hardware monitoring, they joysticks and other miscellaneous stuff. For hardware monitoring, they
...@@ -84,19 +88,19 @@ the IT8716F and late IT8712F have 6. They are shared with other functions ...@@ -84,19 +88,19 @@ the IT8716F and late IT8712F have 6. They are shared with other functions
though, so the functionality may not be available on a given system. though, so the functionality may not be available on a given system.
The driver dumbly assume it is there. The driver dumbly assume it is there.
The IT8718F also features VID inputs (up to 8 pins) but the value is The IT8718F and IT8720F also features VID inputs (up to 8 pins) but the value
stored in the Super-I/O configuration space. Due to technical limitations, is stored in the Super-I/O configuration space. Due to technical limitations,
this value can currently only be read once at initialization time, so this value can currently only be read once at initialization time, so
the driver won't notice and report changes in the VID value. The two the driver won't notice and report changes in the VID value. The two
upper VID bits share their pins with voltage inputs (in5 and in6) so you upper VID bits share their pins with voltage inputs (in5 and in6) so you
can't have both on a given board. can't have both on a given board.
The IT8716F, IT8718F and later IT8712F revisions have support for The IT8716F, IT8718F, IT8720F and later IT8712F revisions have support for
2 additional fans. The additional fans are supported by the driver. 2 additional fans. The additional fans are supported by the driver.
The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional The IT8716F, IT8718F and IT8720F, and late IT8712F and IT8705F also have
16-bit tachometer counters for fans 1 to 3. This is better (no more fan optional 16-bit tachometer counters for fans 1 to 3. This is better (no more
clock divider mess) but not compatible with the older chips and fan clock divider mess) but not compatible with the older chips and
revisions. The 16-bit tachometer mode is enabled by the driver when one revisions. The 16-bit tachometer mode is enabled by the driver when one
of the above chips is detected. of the above chips is detected.
...@@ -122,7 +126,7 @@ zero'; this is important for negative voltage measurements. All voltage ...@@ -122,7 +126,7 @@ zero'; this is important for negative voltage measurements. All voltage
inputs can measure voltages between 0 and 4.08 volts, with a resolution of inputs can measure voltages between 0 and 4.08 volts, with a resolution of
0.016 volt. The battery voltage in8 does not have limit registers. 0.016 volt. The battery voltage in8 does not have limit registers.
The VID lines (IT8712F/IT8716F/IT8718F) encode the core voltage value: The VID lines (IT8712F/IT8716F/IT8718F/IT8720F) encode the core voltage value:
the voltage level your processor should work with. This is hardcoded by the voltage level your processor should work with. This is hardcoded by
the mainboard and/or processor itself. It is a value in volts. the mainboard and/or processor itself. It is a value in volts.
......
...@@ -13,18 +13,21 @@ Author: ...@@ -13,18 +13,21 @@ Author:
Description Description
----------- -----------
This driver provides support for the accelerometer found in various HP laptops This driver provides support for the accelerometer found in various HP
sporting the feature officially called "HP Mobile Data Protection System 3D" or laptops sporting the feature officially called "HP Mobile Data
"HP 3D DriveGuard". It detect automatically laptops with this sensor. Known models Protection System 3D" or "HP 3D DriveGuard". It detect automatically
(for now the HP 2133, nc6420, nc2510, nc8510, nc84x0, nw9440 and nx9420) will laptops with this sensor. Known models (for now the HP 2133, nc6420,
have their axis automatically oriented on standard way (eg: you can directly nc2510, nc8510, nc84x0, nw9440 and nx9420) will have their axis
play neverball). The accelerometer data is readable via automatically oriented on standard way (eg: you can directly play
neverball). The accelerometer data is readable via
/sys/devices/platform/lis3lv02d. /sys/devices/platform/lis3lv02d.
Sysfs attributes under /sys/devices/platform/lis3lv02d/: Sysfs attributes under /sys/devices/platform/lis3lv02d/:
position - 3D position that the accelerometer reports. Format: "(x,y,z)" position - 3D position that the accelerometer reports. Format: "(x,y,z)"
calibrate - read: values (x, y, z) that are used as the base for input class device operation. calibrate - read: values (x, y, z) that are used as the base for input
write: forces the base to be recalibrated with the current position. class device operation.
write: forces the base to be recalibrated with the current
position.
rate - reports the sampling rate of the accelerometer device in HZ rate - reports the sampling rate of the accelerometer device in HZ
This driver also provides an absolute input class device, allowing This driver also provides an absolute input class device, allowing
...@@ -39,11 +42,12 @@ the accelerometer are converted into a "standard" organisation of the axes ...@@ -39,11 +42,12 @@ the accelerometer are converted into a "standard" organisation of the axes
* When the laptop is horizontal the position reported is about 0 for X and Y * When the laptop is horizontal the position reported is about 0 for X and Y
and a positive value for Z and a positive value for Z
* If the left side is elevated, X increases (becomes positive) * If the left side is elevated, X increases (becomes positive)
* If the front side (where the touchpad is) is elevated, Y decreases (becomes negative) * If the front side (where the touchpad is) is elevated, Y decreases
(becomes negative)
* If the laptop is put upside-down, Z becomes negative * If the laptop is put upside-down, Z becomes negative
If your laptop model is not recognized (cf "dmesg"), you can send an email to the If your laptop model is not recognized (cf "dmesg"), you can send an
authors to add it to the database. When reporting a new laptop, please include email to the authors to add it to the database. When reporting a new
the output of "dmidecode" plus the value of /sys/devices/platform/lis3lv02d/position laptop, please include the output of "dmidecode" plus the value of
in these four cases. /sys/devices/platform/lis3lv02d/position in these four cases.
Kernel driver lm70 Kernel driver lm70
================== ==================
Supported chip: Supported chips:
* National Semiconductor LM70 * National Semiconductor LM70
Datasheet: http://www.national.com/pf/LM/LM70.html Datasheet: http://www.national.com/pf/LM/LM70.html
* Texas Instruments TMP121/TMP123
Information: http://focus.ti.com/docs/prod/folders/print/tmp121.html
Author: Author:
Kaiwan N Billimoria <kaiwan@designergraphix.com> Kaiwan N Billimoria <kaiwan@designergraphix.com>
...@@ -25,6 +27,14 @@ complement digital temperature (sent via the SIO line), is available in the ...@@ -25,6 +27,14 @@ complement digital temperature (sent via the SIO line), is available in the
driver for interpretation. This driver makes use of the kernel's in-core driver for interpretation. This driver makes use of the kernel's in-core
SPI support. SPI support.
As a real (in-tree) example of this "SPI protocol driver" interfacing
with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c
and its associated documentation.
The TMP121/TMP123 are very similar; main differences are 4 wire SPI inter-
face (read only) and 13-bit temperature data (0.0625 degrees celsius reso-
lution).
Thanks to Thanks to
--------- ---------
Jean Delvare <khali@linux-fr.org> for mentoring the hwmon-side driver Jean Delvare <khali@linux-fr.org> for mentoring the hwmon-side driver
......
...@@ -164,7 +164,7 @@ configured individually according to the following options. ...@@ -164,7 +164,7 @@ configured individually according to the following options.
temperature. (PWM value from 0 to 255) temperature. (PWM value from 0 to 255)
* pwm#_auto_pwm_minctl - this flags selects for temp#_auto_temp_off temperature * pwm#_auto_pwm_minctl - this flags selects for temp#_auto_temp_off temperature
the bahaviour of fans. Write 1 to let fans spinning at the behaviour of fans. Write 1 to let fans spinning at
pwm#_auto_pwm_min or write 0 to let them off. pwm#_auto_pwm_min or write 0 to let them off.
NOTE: It has been reported that there is a bug in the LM85 that causes the flag NOTE: It has been reported that there is a bug in the LM85 that causes the flag
......
Kernel driver ltc4245
=====================
Supported chips:
* Linear Technology LTC4245
Prefix: 'ltc4245'
Addresses scanned: 0x20-0x3f
Datasheet:
http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1140,P19392,D13517
Author: Ira W. Snyder <iws@ovro.caltech.edu>
Description
-----------
The LTC4245 controller allows a board to be safely inserted and removed
from a live backplane in multiple supply systems such as CompactPCI and
PCI Express.
Usage Notes
-----------
This driver does not probe for LTC4245 devices, due to the fact that some
of the possible addresses are unfriendly to probing. You will need to use
the "force" parameter to tell the driver where to find the device.
Example: the following will load the driver for an LTC4245 at address 0x23
on I2C bus #1:
$ modprobe ltc4245 force=1,0x23
Sysfs entries
-------------
The LTC4245 has built-in limits for over and under current warnings. This
makes it very likely that the reference circuit will be used.
This driver uses the values in the datasheet to change the register values
into the values specified in the sysfs-interface document. The current readings
rely on the sense resistors listed in Table 2: "Sense Resistor Values".
in1_input 12v input voltage (mV)
in2_input 5v input voltage (mV)
in3_input 3v input voltage (mV)
in4_input Vee (-12v) input voltage (mV)
in1_min_alarm 12v input undervoltage alarm
in2_min_alarm 5v input undervoltage alarm
in3_min_alarm 3v input undervoltage alarm
in4_min_alarm Vee (-12v) input undervoltage alarm
curr1_input 12v current (mA)
curr2_input 5v current (mA)
curr3_input 3v current (mA)
curr4_input Vee (-12v) current (mA)
curr1_max_alarm 12v overcurrent alarm
curr2_max_alarm 5v overcurrent alarm
curr3_max_alarm 3v overcurrent alarm
curr4_max_alarm Vee (-12v) overcurrent alarm
in5_input 12v output voltage (mV)
in6_input 5v output voltage (mV)
in7_input 3v output voltage (mV)
in8_input Vee (-12v) output voltage (mV)
in5_min_alarm 12v output undervoltage alarm
in6_min_alarm 5v output undervoltage alarm
in7_min_alarm 3v output undervoltage alarm
in8_min_alarm Vee (-12v) output undervoltage alarm
in9_input GPIO #1 voltage data
in10_input GPIO #2 voltage data
in11_input GPIO #3 voltage data
power1_input 12v power usage (mW)
power2_input 5v power usage (mW)
power3_input 3v power usage (mW)
power4_input Vee (-12v) power usage (mW)
...@@ -11,3 +11,8 @@ unplug old device(s) and plug new device(s) ...@@ -11,3 +11,8 @@ unplug old device(s) and plug new device(s)
# echo -n "1" > /sys/class/ide_port/idex/scan # echo -n "1" > /sys/class/ide_port/idex/scan
done done
NOTE: please make sure that partitions are unmounted and that there are
no other active references to devices before doing "delete_devices" step,
also do not attempt "scan" step on devices currently in use -- otherwise
results may be unpredictable and lead to data loss if you're unlucky
Walkera WK-0701 transmitter is supplied with a ready to fly Walkera
helicopters such as HM36, HM37, HM60. The walkera0701 module enables to use
this transmitter as joystick
Devel homepage and download:
http://zub.fei.tuke.sk/walkera-wk0701/
or use cogito:
cg-clone http://zub.fei.tuke.sk/GIT/walkera0701-joystick
Connecting to PC:
At back side of transmitter S-video connector can be found. Modulation
pulses from processor to HF part can be found at pin 2 of this connector,
pin 3 is GND. Between pin 3 and CPU 5k6 resistor can be found. To get
modulation pulses to PC, signal pulses must be amplified.
Cable: (walkera TX to parport)
Walkera WK-0701 TX S-VIDEO connector:
(back side of TX)
__ __ S-video: canon25
/ |_| \ pin 2 (signal) NPN parport
/ O 4 3 O \ pin 3 (GND) LED ________________ 10 ACK
( O 2 1 O ) | C
\ ___ / 2 ________________________|\|_____|/
| [___] | |/| B |\
------- 3 __________________________________|________________ 25 GND
E
I use green LED and BC109 NPN transistor.
Software:
Build kernel with walkera0701 module. Module walkera0701 need exclusive
access to parport, modules like lp must be unloaded before loading
walkera0701 module, check dmesg for error messages. Connect TX to PC by
cable and run jstest /dev/input/js0 to see values from TX. If no value can
be changed by TX "joystick", check output from /proc/interrupts. Value for
(usually irq7) parport must increase if TX is on.
Technical details:
Driver use interrupt from parport ACK input bit to measure pulse length
using hrtimers.
Frame format:
Based on walkera WK-0701 PCM Format description by Shaul Eizikovich.
(downloaded from http://www.smartpropoplus.com/Docs/Walkera_Wk-0701_PCM.pdf)
Signal pulses:
(ANALOG)
SYNC BIN OCT
+---------+ +------+
| | | |
--+ +------+ +---
Frame:
SYNC , BIN1, OCT1, BIN2, OCT2 ... BIN24, OCT24, BIN25, next frame SYNC ..
pulse length:
Binary values: Analog octal values:
288 uS Binary 0 318 uS 000
438 uS Binary 1 398 uS 001
478 uS 010
558 uS 011
638 uS 100
1306 uS SYNC 718 uS 101
798 uS 110
878 uS 111
24 bin+oct values + 1 bin value = 24*4+1 bits = 97 bits
(Warning, pulses on ACK ar inverted by transistor, irq is rised up on sync
to bin change or octal value to bin change).
Binary data representations:
One binary and octal value can be grouped to nibble. 24 nibbles + one binary
values can be sampled between sync pulses.
Values for first four channels (analog joystick values) can be found in
first 10 nibbles. Analog value is represented by one sign bit and 9 bit
absolute binary value. (10 bits per channel). Next nibble is checksum for
first ten nibbles.
Next nibbles 12 .. 21 represents four channels (not all channels can be
directly controlled from TX). Binary representations ar the same as in first
four channels. In nibbles 22 and 23 is a special magic number. Nibble 24 is
checksum for nibbles 12..23.
After last octal value for nibble 24 and next sync pulse one additional
binary value can be sampled. This bit and magic number is not used in
software driver. Some details about this magic numbers can be found in
Walkera_Wk-0701_PCM.pdf.
Checksum calculation:
Summary of octal values in nibbles must be same as octal value in checksum
nibble (only first 3 bits are used). Binary value for checksum nibble is
calculated by sum of binary values in checked nibbles + sum of octal values
in checked nibbles divided by 8. Only bit 0 of this sum is used.
...@@ -84,7 +84,7 @@ Code Seq# Include File Comments ...@@ -84,7 +84,7 @@ Code Seq# Include File Comments
'B' C0-FF advanced bbus 'B' C0-FF advanced bbus
<mailto:maassen@uni-freiburg.de> <mailto:maassen@uni-freiburg.de>
'C' all linux/soundcard.h 'C' all linux/soundcard.h
'D' all asm-s390/dasd.h 'D' all arch/s390/include/asm/dasd.h
'E' all linux/input.h 'E' all linux/input.h
'F' all linux/fb.h 'F' all linux/fb.h
'H' all linux/hiddev.h 'H' all linux/hiddev.h
...@@ -97,6 +97,7 @@ Code Seq# Include File Comments ...@@ -97,6 +97,7 @@ Code Seq# Include File Comments
<http://linux01.gwdg.de/~alatham/ppdd.html> <http://linux01.gwdg.de/~alatham/ppdd.html>
'M' all linux/soundcard.h 'M' all linux/soundcard.h
'N' 00-1F drivers/usb/scanner.h 'N' 00-1F drivers/usb/scanner.h
'O' 00-02 include/mtd/ubi-user.h UBI
'P' all linux/soundcard.h 'P' all linux/soundcard.h
'Q' all linux/soundcard.h 'Q' all linux/soundcard.h
'R' 00-1F linux/random.h 'R' 00-1F linux/random.h
...@@ -104,7 +105,7 @@ Code Seq# Include File Comments ...@@ -104,7 +105,7 @@ Code Seq# Include File Comments
'S' 80-81 scsi/scsi_ioctl.h conflict! 'S' 80-81 scsi/scsi_ioctl.h conflict!
'S' 82-FF scsi/scsi.h conflict! 'S' 82-FF scsi/scsi.h conflict!
'T' all linux/soundcard.h conflict! 'T' all linux/soundcard.h conflict!
'T' all asm-i386/ioctls.h conflict! 'T' all arch/x86/include/asm/ioctls.h conflict!
'U' 00-EF linux/drivers/usb/usb.h 'U' 00-EF linux/drivers/usb/usb.h
'V' all linux/vt.h 'V' all linux/vt.h
'W' 00-1F linux/watchdog.h conflict! 'W' 00-1F linux/watchdog.h conflict!
...@@ -119,7 +120,7 @@ Code Seq# Include File Comments ...@@ -119,7 +120,7 @@ Code Seq# Include File Comments
<mailto:natalia@nikhefk.nikhef.nl> <mailto:natalia@nikhefk.nikhef.nl>
'c' 00-7F linux/comstats.h conflict! 'c' 00-7F linux/comstats.h conflict!
'c' 00-7F linux/coda.h conflict! 'c' 00-7F linux/coda.h conflict!
'c' 80-9F asm-s390/chsc.h 'c' 80-9F arch/s390/include/asm/chsc.h
'd' 00-FF linux/char/drm/drm/h conflict! 'd' 00-FF linux/char/drm/drm/h conflict!
'd' 00-DF linux/video_decoder.h conflict! 'd' 00-DF linux/video_decoder.h conflict!
'd' F0-FF linux/digi1.h 'd' F0-FF linux/digi1.h
...@@ -142,6 +143,9 @@ Code Seq# Include File Comments ...@@ -142,6 +143,9 @@ Code Seq# Include File Comments
'n' 00-7F linux/ncp_fs.h 'n' 00-7F linux/ncp_fs.h
'n' E0-FF video/matrox.h matroxfb 'n' E0-FF video/matrox.h matroxfb
'o' 00-1F fs/ocfs2/ocfs2_fs.h OCFS2 'o' 00-1F fs/ocfs2/ocfs2_fs.h OCFS2
'o' 00-03 include/mtd/ubi-user.h conflict! (OCFS2 and UBI overlaps)
'o' 40-41 include/mtd/ubi-user.h UBI
'o' 01-A1 include/linux/dvb/*.h DVB
'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this) 'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this)
'p' 00-3F linux/mc146818rtc.h conflict! 'p' 00-3F linux/mc146818rtc.h conflict!
'p' 40-7F linux/nvram.h 'p' 40-7F linux/nvram.h
...@@ -166,7 +170,7 @@ Code Seq# Include File Comments ...@@ -166,7 +170,7 @@ Code Seq# Include File Comments
<mailto:oe@port.de> <mailto:oe@port.de>
0x80 00-1F linux/fb.h 0x80 00-1F linux/fb.h
0x81 00-1F linux/videotext.h 0x81 00-1F linux/videotext.h
0x89 00-06 asm-i386/sockios.h 0x89 00-06 arch/x86/include/asm/sockios.h
0x89 0B-DF linux/sockios.h 0x89 0B-DF linux/sockios.h
0x89 E0-EF linux/sockios.h SIOCPROTOPRIVATE range 0x89 E0-EF linux/sockios.h SIOCPROTOPRIVATE range
0x89 F0-FF linux/sockios.h SIOCDEVPRIVATE range 0x89 F0-FF linux/sockios.h SIOCDEVPRIVATE range
......
...@@ -12,11 +12,11 @@ file at first. ...@@ -12,11 +12,11 @@ file at first.
================================== ==================================
これは、 これは、
linux-2.6.24/Documentation/stable_kernel_rules.txt linux-2.6.29/Documentation/stable_kernel_rules.txt
の和訳です。 の和訳です。
翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ > 翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
翻訳日: 2007/12/30 翻訳日: 2009/1/14
翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com> 翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com>
校正者: 武井伸光さん、<takei at webmasters dot gr dot jp> 校正者: 武井伸光さん、<takei at webmasters dot gr dot jp>
かねこさん (Seiji Kaneko) <skaneko at a2 dot mbn dot or dot jp> かねこさん (Seiji Kaneko) <skaneko at a2 dot mbn dot or dot jp>
...@@ -38,12 +38,15 @@ linux-2.6.24/Documentation/stable_kernel_rules.txt ...@@ -38,12 +38,15 @@ linux-2.6.24/Documentation/stable_kernel_rules.txt
- ビルドエラー(CONFIG_BROKENになっているものを除く), oops, ハング、デー - ビルドエラー(CONFIG_BROKENになっているものを除く), oops, ハング、デー
タ破壊、現実のセキュリティ問題、その他 "ああ、これはダメだね"という タ破壊、現実のセキュリティ問題、その他 "ああ、これはダメだね"という
ようなものを修正しなければならない。短く言えば、重大な問題。 ようなものを修正しなければならない。短く言えば、重大な問題。
- 新しい device ID とクオークも受け入れられる。
- どのように競合状態が発生するかの説明も一緒に書かれていない限り、 - どのように競合状態が発生するかの説明も一緒に書かれていない限り、
"理論的には競合状態になる"ようなものは不可。 "理論的には競合状態になる"ようなものは不可。
- いかなる些細な修正も含めることはできない。(スペルの修正、空白のクリー - いかなる些細な修正も含めることはできない。(スペルの修正、空白のクリー
ンアップなど) ンアップなど)
- 対応するサブシステムメンテナが受け入れたものでなければならない。
- Documentation/SubmittingPatches の規則に従ったものでなければならない。 - Documentation/SubmittingPatches の規則に従ったものでなければならない。
- パッチ自体か同等の修正が Linus のツリーに既に存在しなければならない。
  Linus のツリーでのコミットID を -stable へのパッチ投稿の際に引用す
ること。
-stable ツリーにパッチを送付する手続き- -stable ツリーにパッチを送付する手続き-
...@@ -52,8 +55,10 @@ linux-2.6.24/Documentation/stable_kernel_rules.txt ...@@ -52,8 +55,10 @@ linux-2.6.24/Documentation/stable_kernel_rules.txt
- 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合 - 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
には NAK を受け取る。この反応は開発者たちのスケジュールによって、数 には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
日かかる場合がある。 日かかる場合がある。
- もし受け取られたら、パッチは他の開発者たちのレビューのために - もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの
-stable キューに追加される。 メンテナーによるレビューのために -stable キューに追加される。
- パッチに stable@kernel.org のアドレスが付加されているときには、それ
が Linus のツリーに入る時に自動的に stable チームに email される。
- セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ - セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ
きではなく、代わりに security@kernel.org のアドレスに送られる。 きではなく、代わりに security@kernel.org のアドレスに送られる。
......
00-INDEX 00-INDEX
- this file: info on the kernel build process - this file: info on the kernel build process
kbuild.txt
- developer information on kbuild
kconfig.txt
- usage help for make *config
kconfig-language.txt kconfig-language.txt
- specification of Config Language, the language in Kconfig files - specification of Config Language, the language in Kconfig files
makefiles.txt makefiles.txt
......
Environment variables
KCPPFLAGS
--------------------------------------------------
Additional options to pass when preprocessing. The preprocessing options
will be used in all cases where kbuild does preprocessing including
building C files and assembler files.
KAFLAGS
--------------------------------------------------
Additional options to the assembler.
KCFLAGS
--------------------------------------------------
Additional options to the C compiler.
KBUILD_VERBOSE
--------------------------------------------------
Set the kbuild verbosity. Can be assigned same values as "V=...".
See make help for the full list.
Setting "V=..." takes precedence over KBUILD_VERBOSE.
KBUILD_EXTMOD
--------------------------------------------------
Set the directory to look for the kernel source when building external
modules.
The directory can be specified in several ways:
1) Use "M=..." on the command line
2) Environmnet variable KBUILD_EXTMOD
3) Environmnet variable SUBDIRS
The possibilities are listed in the order they take precedence.
Using "M=..." will always override the others.
KBUILD_OUTPUT
--------------------------------------------------
Specify the output directory when building the kernel.
The output directory can also be specificed using "O=...".
Setting "O=..." takes precedence over KBUILD_OUTPUT.
ARCH
--------------------------------------------------
Set ARCH to the architecture to be built.
In most cases the name of the architecture is the same as the
directory name found in the arch/ directory.
But some architectures such as x86 and sparc have aliases.
x86: i386 for 32 bit, x86_64 for 64 bit
sparc: sparc for 32 bit, sparc64 for 64 bit
CROSS_COMPILE
--------------------------------------------------
Specify an optional fixed part of the binutils filename.
CROSS_COMPILE can be a part of the filename or the full path.
CROSS_COMPILE is also used for ccache is some setups.
CF
--------------------------------------------------
Additional options for sparse.
CF is often used on the command-line like this:
make CF=-Wbitwise C=2
INSTALL_PATH
--------------------------------------------------
INSTALL_PATH specifies where to place the updated kernel and system map
images. Default is /boot, but you can set it to other values.
MODLIB
--------------------------------------------------
Specify where to install modules.
The default value is:
$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
The value can be overridden in which case the default value is ignored.
INSTALL_MOD_PATH
--------------------------------------------------
INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
relocations required by build roots. This is not defined in the
makefile but the argument can be passed to make if needed.
INSTALL_MOD_STRIP
--------------------------------------------------
INSTALL_MOD_STRIP, if defined, will cause modules to be
stripped after they are installed. If INSTALL_MOD_STRIP is '1', then
the default option --strip-debug will be used. Otherwise,
INSTALL_MOD_STRIP will used as the options to the strip command.
INSTALL_FW_PATH
--------------------------------------------------
INSTALL_FW_PATH specifies where to install the firmware blobs.
The default value is:
$(INSTALL_MOD_PATH)/lib/firmware
The value can be overridden in which case the default value is ignored.
INSTALL_HDR_PATH
--------------------------------------------------
INSTALL_HDR_PATH specifies where to install user space headers when
executing "make headers_*".
The default value is:
$(objtree)/usr
$(objtree) is the directory where output files are saved.
The output directory is often set using "O=..." on the commandline.
The value can be overridden in which case the default value is ignored.
KBUILD_MODPOST_WARN
--------------------------------------------------
KBUILD_MODPOST_WARN can be set to avoid errors in case of undefined
symbols in the final module linking stage. It changes such errors
into warnings.
KBUILD_MODPOST_NOFINAL
--------------------------------------------------
KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
This is solely useful to speed up test compiles.
KBUILD_EXTRA_SYMBOLS
--------------------------------------------------
For modules that use symbols from other modules.
See more details in modules.txt.
ALLSOURCE_ARCHS
--------------------------------------------------
For tags/TAGS/cscope targets, you can specify more than one arch
to be included in the databases, separated by blank space. E.g.:
$ make ALLSOURCE_ARCHS="x86 mips arm" tags
此差异已折叠。
...@@ -253,7 +253,7 @@ following files: ...@@ -253,7 +253,7 @@ following files:
# Module specific targets # Module specific targets
genbin: genbin:
echo "X" > 8123_bin_shipped echo "X" > 8123_bin.o_shipped
In example 2, we are down to two fairly simple files and for simple In example 2, we are down to two fairly simple files and for simple
...@@ -279,7 +279,7 @@ following files: ...@@ -279,7 +279,7 @@ following files:
# Module specific targets # Module specific targets
genbin: genbin:
echo "X" > 8123_bin_shipped echo "X" > 8123_bin.o_shipped
endif endif
......
...@@ -71,6 +71,11 @@ The @argument descriptions must begin on the very next line following ...@@ -71,6 +71,11 @@ The @argument descriptions must begin on the very next line following
this opening short function description line, with no intervening this opening short function description line, with no intervening
empty comment lines. empty comment lines.
If a function parameter is "..." (varargs), it should be listed in
kernel-doc notation as:
* @...: description
Example kernel-doc data structure comment. Example kernel-doc data structure comment.
/** /**
...@@ -282,6 +287,32 @@ struct my_struct { ...@@ -282,6 +287,32 @@ struct my_struct {
}; };
Including documentation blocks in source files
----------------------------------------------
To facilitate having source code and comments close together, you can
include kernel-doc documentation blocks that are free-form comments
instead of being kernel-doc for functions, structures, unions,
enums, or typedefs. This could be used for something like a
theory of operation for a driver or library code, for example.
This is done by using a DOC: section keyword with a section title. E.g.:
/**
* DOC: Theory of Operation
*
* The whizbang foobar is a dilly of a gizmo. It can do whatever you
* want it to do, at any time. It reads your mind. Here's how it works.
*
* foo bar splat
*
* The only drawback to this gizmo is that is can sometimes damage
* hardware, software, or its subject(s).
*/
DOC: sections are used in SGML templates files as indicated below.
How to make new SGML template files How to make new SGML template files
----------------------------------- -----------------------------------
...@@ -302,6 +333,9 @@ exported using EXPORT_SYMBOL. ...@@ -302,6 +333,9 @@ exported using EXPORT_SYMBOL.
!F<filename> <function [functions...]> is replaced by the !F<filename> <function [functions...]> is replaced by the
documentation, in <filename>, for the functions listed. documentation, in <filename>, for the functions listed.
!P<filename> <section title> is replaced by the contents of the DOC:
section titled <section title> from <filename>.
Spaces are allowed in <section title>; do not quote the <section title>.
Tim. Tim.
*/ <twaugh@redhat.com> */ <twaugh@redhat.com>
此差异已折叠。
...@@ -118,8 +118,8 @@ the name of the kobject, call kobject_rename(): ...@@ -118,8 +118,8 @@ the name of the kobject, call kobject_rename():
int kobject_rename(struct kobject *kobj, const char *new_name); int kobject_rename(struct kobject *kobj, const char *new_name);
Note kobject_rename does perform any locking or have a solid notion of kobject_rename does not perform any locking or have a solid notion of
what names are valid so the provide must provide their own sanity checking what names are valid so the caller must provide their own sanity checking
and serialization. and serialization.
There is a function called kobject_set_name() but that is legacy cruft and There is a function called kobject_set_name() but that is legacy cruft and
......
...@@ -497,7 +497,10 @@ The first column provides the kernel address where the probe is inserted. ...@@ -497,7 +497,10 @@ The first column provides the kernel address where the probe is inserted.
The second column identifies the type of probe (k - kprobe, r - kretprobe The second column identifies the type of probe (k - kprobe, r - kretprobe
and j - jprobe), while the third column specifies the symbol+offset of and j - jprobe), while the third column specifies the symbol+offset of
the probe. If the probed function belongs to a module, the module name the probe. If the probed function belongs to a module, the module name
is also specified. is also specified. Following columns show probe status. If the probe is on
a virtual address that is no longer valid (module init sections, module
virtual addresses that correspond to modules that've been unloaded),
such probes are marked with [GONE].
/debug/kprobes/enabled: Turn kprobes ON/OFF /debug/kprobes/enabled: Turn kprobes ON/OFF
......
ThinkPad ACPI Extras Driver ThinkPad ACPI Extras Driver
Version 0.21 Version 0.22
May 29th, 2008 November 23rd, 2008
Borislav Deianov <borislav@users.sf.net> Borislav Deianov <borislav@users.sf.net>
Henrique de Moraes Holschuh <hmh@hmh.eng.br> Henrique de Moraes Holschuh <hmh@hmh.eng.br>
...@@ -16,7 +16,8 @@ supported by the generic Linux ACPI drivers. ...@@ -16,7 +16,8 @@ supported by the generic Linux ACPI drivers.
This driver used to be named ibm-acpi until kernel 2.6.21 and release This driver used to be named ibm-acpi until kernel 2.6.21 and release
0.13-20070314. It used to be in the drivers/acpi tree, but it was 0.13-20070314. It used to be in the drivers/acpi tree, but it was
moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel
2.6.22, and release 0.14. 2.6.22, and release 0.14. It was moved to drivers/platform/x86 for
kernel 2.6.29 and release 0.22.
The driver is named "thinkpad-acpi". In some places, like module The driver is named "thinkpad-acpi". In some places, like module
names, "thinkpad_acpi" is used because of userspace issues. names, "thinkpad_acpi" is used because of userspace issues.
...@@ -1412,6 +1413,24 @@ Sysfs notes: ...@@ -1412,6 +1413,24 @@ Sysfs notes:
rfkill controller switch "tpacpi_wwan_sw": refer to rfkill controller switch "tpacpi_wwan_sw": refer to
Documentation/rfkill.txt for details. Documentation/rfkill.txt for details.
EXPERIMENTAL: UWB
-----------------
This feature is marked EXPERIMENTAL because it has not been extensively
tested and validated in various ThinkPad models yet. The feature may not
work as expected. USE WITH CAUTION! To use this feature, you need to supply
the experimental=1 parameter when loading the module.
sysfs rfkill class: switch "tpacpi_uwb_sw"
This feature exports an rfkill controller for the UWB device, if one is
present and enabled in the BIOS.
Sysfs notes:
rfkill controller switch "tpacpi_uwb_sw": refer to
Documentation/rfkill.txt for details.
Multiple Commands, Module Parameters Multiple Commands, Module Parameters
------------------------------------ ------------------------------------
...@@ -1475,7 +1494,7 @@ Sysfs interface changelog: ...@@ -1475,7 +1494,7 @@ Sysfs interface changelog:
0x020100: Marker for thinkpad-acpi with hot key NVRAM polling 0x020100: Marker for thinkpad-acpi with hot key NVRAM polling
support. If you must, use it to know you should not support. If you must, use it to know you should not
start an userspace NVRAM poller (allows to detect when start a userspace NVRAM poller (allows to detect when
NVRAM is compiled out by the user because it is NVRAM is compiled out by the user because it is
unneeded/undesired in the first place). unneeded/undesired in the first place).
0x020101: Marker for thinkpad-acpi with hot key NVRAM polling 0x020101: Marker for thinkpad-acpi with hot key NVRAM polling
......
# This creates the demonstration utility "lguest" which runs a Linux guest. # This creates the demonstration utility "lguest" which runs a Linux guest.
CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -I../../include -I../../arch/x86/include CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -I../../include -I../../arch/x86/include -U_FORTIFY_SOURCE
LDLIBS:=-lz LDLIBS:=-lz
all: lguest all: lguest
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册