From 8a409b0118c2d78f84f740f60fe03abda1fe3333 Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Mon, 5 Sep 2005 00:08:08 -0500 Subject: Input: HID - add more consumer usages Extend mapping of the consumer usage page in hid-input.c to handle more cases appearing on new USB keyboards. Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/input.h b/include/linux/input.h index bdc53c6cc962..227a497c0678 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -287,6 +287,8 @@ struct input_absinfo { #define KEY_SCROLLDOWN 178 #define KEY_KPLEFTPAREN 179 #define KEY_KPRIGHTPAREN 180 +#define KEY_NEW 181 +#define KEY_REDO 182 #define KEY_F13 183 #define KEY_F14 184 @@ -333,6 +335,12 @@ struct input_absinfo { #define KEY_KBDILLUMDOWN 229 #define KEY_KBDILLUMUP 230 +#define KEY_SEND 231 +#define KEY_REPLY 232 +#define KEY_FORWARDMAIL 233 +#define KEY_SAVE 234 +#define KEY_DOCUMENTS 235 + #define KEY_UNKNOWN 240 #define BTN_MISC 0x100 -- cgit v1.2.3 From 507d37cf269ebbd1b32bcc435fe577e411f73151 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 9 Sep 2005 02:30:07 -0300 Subject: [CCID] Only call the HC insert_options methods when requested Signed-off-by: Arnaldo Carvalho de Melo --- include/linux/dccp.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 007c290f74d4..5e0af0d08a93 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -433,6 +433,8 @@ struct dccp_sock { struct ccid *dccps_hc_tx_ccid; struct dccp_options_received dccps_options_received; enum dccp_role dccps_role:2; + __u8 dccps_hc_rx_insert_options:1; + __u8 dccps_hc_tx_insert_options:1; }; static inline struct dccp_sock *dccp_sk(const struct sock *sk) -- cgit v1.2.3 From b0e567806d16586629468c824dfb2e71155df7da Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 9 Sep 2005 02:38:35 -0300 Subject: [DCCP] Introduce dccp_timestamp To start the timestamps with 0.0ms, easing the integer maths in the CCIDs, this probably will be reworked to use the to be introduced struct timeval_offset infrastructure out of skb_get_timestamp, etc. Signed-off-by: Arnaldo Carvalho de Melo --- include/linux/dccp.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 5e0af0d08a93..8bf4bacb5051 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -432,6 +432,7 @@ struct dccp_sock { struct ccid *dccps_hc_rx_ccid; struct ccid *dccps_hc_tx_ccid; struct dccp_options_received dccps_options_received; + struct timeval dccps_epoch; enum dccp_role dccps_role:2; __u8 dccps_hc_rx_insert_options:1; __u8 dccps_hc_tx_insert_options:1; -- cgit v1.2.3 From 144a50ea5e1487b8b8e722289b4177713354448a Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 9 Aug 2005 00:20:10 -0400 Subject: [PATCH] must_check attributes for PCI layer. Self explanatory really. Some newer gcc's print a warning if a function is used and we don't check its result. We do this for a bunch of things in the kernel already, this extends that to the PCI layer. Based on a patch originally from Arjan van de Ven. Signed-off-by: Dave Jones Signed-off-by: Arjan van de Ven Signed-off-by: Greg Kroah-Hartman --- include/linux/pci.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 6caaba0af469..609499356e07 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -376,32 +376,32 @@ static inline int pci_write_config_dword(struct pci_dev *dev, int where, u32 val return pci_bus_write_config_dword (dev->bus, dev->devfn, where, val); } -int pci_enable_device(struct pci_dev *dev); -int pci_enable_device_bars(struct pci_dev *dev, int mask); +int __must_check pci_enable_device(struct pci_dev *dev); +int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask); void pci_disable_device(struct pci_dev *dev); void pci_set_master(struct pci_dev *dev); #define HAVE_PCI_SET_MWI -int pci_set_mwi(struct pci_dev *dev); +int __must_check pci_set_mwi(struct pci_dev *dev); void pci_clear_mwi(struct pci_dev *dev); void pci_intx(struct pci_dev *dev, int enable); -int pci_set_dma_mask(struct pci_dev *dev, u64 mask); -int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); +int __must_check pci_set_dma_mask(struct pci_dev *dev, u64 mask); +int __must_check pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); int pci_assign_resource(struct pci_dev *dev, int i); void pci_restore_bars(struct pci_dev *dev); /* ROM control related routines */ -void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size); -void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size); +void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); +void __iomem __must_check *pci_map_rom_copy(struct pci_dev *pdev, size_t *size); void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); void pci_remove_rom(struct pci_dev *pdev); /* Power management related routines */ int pci_save_state(struct pci_dev *dev); int pci_restore_state(struct pci_dev *dev); -int pci_set_power_state(struct pci_dev *dev, pci_power_t state); -pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); -int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); +int __must_check pci_set_power_state(struct pci_dev *dev, pci_power_t state); +pci_power_t __must_check pci_choose_state(struct pci_dev *dev, pm_message_t state); +int __must_check pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ void pci_bus_assign_resources(struct pci_bus *bus); -- cgit v1.2.3 From 5e41ff9e0650f327a6c819841fa412da95d57319 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Fri, 9 Sep 2005 13:01:35 -0700 Subject: [PATCH] security: enable atomic inode security labeling The following patch set enables atomic security labeling of newly created inodes by altering the fs code to invoke a new LSM hook to obtain the security attribute to apply to a newly created inode and to set up the incore inode security state during the inode creation transaction. This parallels the existing processing for setting ACLs on newly created inodes. Otherwise, it is possible for new inodes to be accessed by another thread via the dcache prior to complete security setup (presently handled by the post_create/mkdir/... LSM hooks in the VFS) and a newly created inode may be left unlabeled on the disk in the event of a crash. SELinux presently works around the issue by ensuring that the incore inode security label is initialized to a special SID that is inaccessible to unprivileged processes (in accordance with policy), thereby preventing inappropriate access but potentially causing false denials on legitimate accesses. A simple test program demonstrates such false denials on SELinux, and the patch solves the problem. Similar such false denials have been encountered in real applications. This patch defines a new inode_init_security LSM hook to obtain the security attribute to apply to a newly created inode and to set up the incore inode security state for it, and adds a corresponding hook function implementation to SELinux. Signed-off-by: Stephen Smalley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/security.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'include/linux') diff --git a/include/linux/security.h b/include/linux/security.h index 7aab6ab7c57f..d4f3b7a94ea6 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -250,6 +250,25 @@ struct swap_info_struct; * @inode contains the inode structure. * Deallocate the inode security structure and set @inode->i_security to * NULL. + * @inode_init_security: + * Obtain the security attribute name suffix and value to set on a newly + * created inode and set up the incore security field for the new inode. + * This hook is called by the fs code as part of the inode creation + * transaction and provides for atomic labeling of the inode, unlike + * the post_create/mkdir/... hooks called by the VFS. The hook function + * is expected to allocate the name and value via kmalloc, with the caller + * being responsible for calling kfree after using them. + * If the security module does not use security attributes or does + * not wish to put a security attribute on this particular inode, + * then it should return -EOPNOTSUPP to skip this processing. + * @inode contains the inode structure of the newly created inode. + * @dir contains the inode structure of the parent directory. + * @name will be set to the allocated name suffix (e.g. selinux). + * @value will be set to the allocated attribute value. + * @len will be set to the length of the value. + * Returns 0 if @name and @value have been successfully set, + * -EOPNOTSUPP if no security attribute is needed, or + * -ENOMEM on memory allocation failure. * @inode_create: * Check permission to create a regular file. * @dir contains inode structure of the parent of the new file. @@ -1080,6 +1099,8 @@ struct security_operations { int (*inode_alloc_security) (struct inode *inode); void (*inode_free_security) (struct inode *inode); + int (*inode_init_security) (struct inode *inode, struct inode *dir, + char **name, void **value, size_t *len); int (*inode_create) (struct inode *dir, struct dentry *dentry, int mode); void (*inode_post_create) (struct inode *dir, @@ -1442,6 +1463,17 @@ static inline void security_inode_free (struct inode *inode) return; security_ops->inode_free_security (inode); } + +static inline int security_inode_init_security (struct inode *inode, + struct inode *dir, + char **name, + void **value, + size_t *len) +{ + if (unlikely (IS_PRIVATE (inode))) + return -EOPNOTSUPP; + return security_ops->inode_init_security (inode, dir, name, value, len); +} static inline int security_inode_create (struct inode *dir, struct dentry *dentry, @@ -2171,6 +2203,15 @@ static inline int security_inode_alloc (struct inode *inode) static inline void security_inode_free (struct inode *inode) { } + +static inline int security_inode_init_security (struct inode *inode, + struct inode *dir, + char **name, + void **value, + size_t *len) +{ + return -EOPNOTSUPP; +} static inline int security_inode_create (struct inode *dir, struct dentry *dentry, -- cgit v1.2.3 From a74574aafea3a63add3251047601611111f44562 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Fri, 9 Sep 2005 13:01:44 -0700 Subject: [PATCH] Remove security_inode_post_create/mkdir/symlink/mknod hooks This patch removes the inode_post_create/mkdir/mknod/symlink LSM hooks as they are obsoleted by the new inode_init_security hook that enables atomic inode security labeling. If anyone sees any reason to retain these hooks, please speak now. Also, is anyone using the post_rename/link hooks; if not, those could also be removed. Signed-off-by: Stephen Smalley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/security.h | 90 ------------------------------------------------ 1 file changed, 90 deletions(-) (limited to 'include/linux') diff --git a/include/linux/security.h b/include/linux/security.h index d4f3b7a94ea6..875225bf8986 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -275,12 +275,6 @@ struct swap_info_struct; * @dentry contains the dentry structure for the file to be created. * @mode contains the file mode of the file to be created. * Return 0 if permission is granted. - * @inode_post_create: - * Set the security attributes on a newly created regular file. This hook - * is called after a file has been successfully created. - * @dir contains the inode structure of the parent directory of the new file. - * @dentry contains the the dentry structure for the newly created file. - * @mode contains the file mode. * @inode_link: * Check permission before creating a new hard link to a file. * @old_dentry contains the dentry structure for an existing link to the file. @@ -303,13 +297,6 @@ struct swap_info_struct; * @dentry contains the dentry structure of the symbolic link. * @old_name contains the pathname of file. * Return 0 if permission is granted. - * @inode_post_symlink: - * @dir contains the inode structure of the parent directory of the new link. - * @dentry contains the dentry structure of new symbolic link. - * @old_name contains the pathname of file. - * Set security attributes for a newly created symbolic link. Note that - * @dentry->d_inode may be NULL, since the filesystem might not - * instantiate the dentry (e.g. NFS). * @inode_mkdir: * Check permissions to create a new directory in the existing directory * associated with inode strcture @dir. @@ -317,11 +304,6 @@ struct swap_info_struct; * @dentry contains the dentry structure of new directory. * @mode contains the mode of new directory. * Return 0 if permission is granted. - * @inode_post_mkdir: - * Set security attributes on a newly created directory. - * @dir contains the inode structure of parent of the directory to be created. - * @dentry contains the dentry structure of new directory. - * @mode contains the mode of new directory. * @inode_rmdir: * Check the permission to remove a directory. * @dir contains the inode structure of parent of the directory to be removed. @@ -337,13 +319,6 @@ struct swap_info_struct; * @mode contains the mode of the new file. * @dev contains the the device number. * Return 0 if permission is granted. - * @inode_post_mknod: - * Set security attributes on a newly created special file (or socket or - * fifo file created via the mknod system call). - * @dir contains the inode structure of parent of the new node. - * @dentry contains the dentry structure of the new node. - * @mode contains the mode of the new node. - * @dev contains the the device number. * @inode_rename: * Check for permission to rename a file or directory. * @old_dir contains the inode structure for parent of the old link. @@ -1103,8 +1078,6 @@ struct security_operations { char **name, void **value, size_t *len); int (*inode_create) (struct inode *dir, struct dentry *dentry, int mode); - void (*inode_post_create) (struct inode *dir, - struct dentry *dentry, int mode); int (*inode_link) (struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); void (*inode_post_link) (struct dentry *old_dentry, @@ -1112,17 +1085,10 @@ struct security_operations { int (*inode_unlink) (struct inode *dir, struct dentry *dentry); int (*inode_symlink) (struct inode *dir, struct dentry *dentry, const char *old_name); - void (*inode_post_symlink) (struct inode *dir, - struct dentry *dentry, - const char *old_name); int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode); - void (*inode_post_mkdir) (struct inode *dir, struct dentry *dentry, - int mode); int (*inode_rmdir) (struct inode *dir, struct dentry *dentry); int (*inode_mknod) (struct inode *dir, struct dentry *dentry, int mode, dev_t dev); - void (*inode_post_mknod) (struct inode *dir, struct dentry *dentry, - int mode, dev_t dev); int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); void (*inode_post_rename) (struct inode *old_dir, @@ -1484,15 +1450,6 @@ static inline int security_inode_create (struct inode *dir, return security_ops->inode_create (dir, dentry, mode); } -static inline void security_inode_post_create (struct inode *dir, - struct dentry *dentry, - int mode) -{ - if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode))) - return; - security_ops->inode_post_create (dir, dentry, mode); -} - static inline int security_inode_link (struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) @@ -1528,15 +1485,6 @@ static inline int security_inode_symlink (struct inode *dir, return security_ops->inode_symlink (dir, dentry, old_name); } -static inline void security_inode_post_symlink (struct inode *dir, - struct dentry *dentry, - const char *old_name) -{ - if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode))) - return; - security_ops->inode_post_symlink (dir, dentry, old_name); -} - static inline int security_inode_mkdir (struct inode *dir, struct dentry *dentry, int mode) @@ -1546,15 +1494,6 @@ static inline int security_inode_mkdir (struct inode *dir, return security_ops->inode_mkdir (dir, dentry, mode); } -static inline void security_inode_post_mkdir (struct inode *dir, - struct dentry *dentry, - int mode) -{ - if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode))) - return; - security_ops->inode_post_mkdir (dir, dentry, mode); -} - static inline int security_inode_rmdir (struct inode *dir, struct dentry *dentry) { @@ -1572,15 +1511,6 @@ static inline int security_inode_mknod (struct inode *dir, return security_ops->inode_mknod (dir, dentry, mode, dev); } -static inline void security_inode_post_mknod (struct inode *dir, - struct dentry *dentry, - int mode, dev_t dev) -{ - if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode))) - return; - security_ops->inode_post_mknod (dir, dentry, mode, dev); -} - static inline int security_inode_rename (struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, @@ -2220,11 +2150,6 @@ static inline int security_inode_create (struct inode *dir, return 0; } -static inline void security_inode_post_create (struct inode *dir, - struct dentry *dentry, - int mode) -{ } - static inline int security_inode_link (struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) @@ -2250,11 +2175,6 @@ static inline int security_inode_symlink (struct inode *dir, return 0; } -static inline void security_inode_post_symlink (struct inode *dir, - struct dentry *dentry, - const char *old_name) -{ } - static inline int security_inode_mkdir (struct inode *dir, struct dentry *dentry, int mode) @@ -2262,11 +2182,6 @@ static inline int security_inode_mkdir (struct inode *dir, return 0; } -static inline void security_inode_post_mkdir (struct inode *dir, - struct dentry *dentry, - int mode) -{ } - static inline int security_inode_rmdir (struct inode *dir, struct dentry *dentry) { @@ -2280,11 +2195,6 @@ static inline int security_inode_mknod (struct inode *dir, return 0; } -static inline void security_inode_post_mknod (struct inode *dir, - struct dentry *dentry, - int mode, dev_t dev) -{ } - static inline int security_inode_rename (struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, -- cgit v1.2.3 From e31e14ec356f36b131576be5bc31d8fef7e95483 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Fri, 9 Sep 2005 13:01:45 -0700 Subject: [PATCH] remove the inode_post_link and inode_post_rename LSM hooks This patch removes the inode_post_link and inode_post_rename LSM hooks as they are unused (and likely useless). Signed-off-by: Stephen Smalley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/security.h | 49 ------------------------------------------------ 1 file changed, 49 deletions(-) (limited to 'include/linux') diff --git a/include/linux/security.h b/include/linux/security.h index 875225bf8986..55b02e1c73f4 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -281,11 +281,6 @@ struct swap_info_struct; * @dir contains the inode structure of the parent directory of the new link. * @new_dentry contains the dentry structure for the new link. * Return 0 if permission is granted. - * @inode_post_link: - * Set security attributes for a new hard link to a file. - * @old_dentry contains the dentry structure for the existing link. - * @dir contains the inode structure of the parent directory of the new file. - * @new_dentry contains the dentry structure for the new file link. * @inode_unlink: * Check the permission to remove a hard link to a file. * @dir contains the inode structure of parent directory of the file. @@ -326,12 +321,6 @@ struct swap_info_struct; * @new_dir contains the inode structure for parent of the new link. * @new_dentry contains the dentry structure of the new link. * Return 0 if permission is granted. - * @inode_post_rename: - * Set security attributes on a renamed file or directory. - * @old_dir contains the inode structure for parent of the old link. - * @old_dentry contains the dentry structure of the old link. - * @new_dir contains the inode structure for parent of the new link. - * @new_dentry contains the dentry structure of the new link. * @inode_readlink: * Check the permission to read the symbolic link. * @dentry contains the dentry structure for the file link. @@ -1080,8 +1069,6 @@ struct security_operations { struct dentry *dentry, int mode); int (*inode_link) (struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); - void (*inode_post_link) (struct dentry *old_dentry, - struct inode *dir, struct dentry *new_dentry); int (*inode_unlink) (struct inode *dir, struct dentry *dentry); int (*inode_symlink) (struct inode *dir, struct dentry *dentry, const char *old_name); @@ -1091,10 +1078,6 @@ struct security_operations { int mode, dev_t dev); int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); - void (*inode_post_rename) (struct inode *old_dir, - struct dentry *old_dentry, - struct inode *new_dir, - struct dentry *new_dentry); int (*inode_readlink) (struct dentry *dentry); int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd); @@ -1459,15 +1442,6 @@ static inline int security_inode_link (struct dentry *old_dentry, return security_ops->inode_link (old_dentry, dir, new_dentry); } -static inline void security_inode_post_link (struct dentry *old_dentry, - struct inode *dir, - struct dentry *new_dentry) -{ - if (new_dentry->d_inode && unlikely (IS_PRIVATE (new_dentry->d_inode))) - return; - security_ops->inode_post_link (old_dentry, dir, new_dentry); -} - static inline int security_inode_unlink (struct inode *dir, struct dentry *dentry) { @@ -1523,18 +1497,6 @@ static inline int security_inode_rename (struct inode *old_dir, new_dir, new_dentry); } -static inline void security_inode_post_rename (struct inode *old_dir, - struct dentry *old_dentry, - struct inode *new_dir, - struct dentry *new_dentry) -{ - if (unlikely (IS_PRIVATE (old_dentry->d_inode) || - (new_dentry->d_inode && IS_PRIVATE (new_dentry->d_inode)))) - return; - security_ops->inode_post_rename (old_dir, old_dentry, - new_dir, new_dentry); -} - static inline int security_inode_readlink (struct dentry *dentry) { if (unlikely (IS_PRIVATE (dentry->d_inode))) @@ -2157,11 +2119,6 @@ static inline int security_inode_link (struct dentry *old_dentry, return 0; } -static inline void security_inode_post_link (struct dentry *old_dentry, - struct inode *dir, - struct dentry *new_dentry) -{ } - static inline int security_inode_unlink (struct inode *dir, struct dentry *dentry) { @@ -2203,12 +2160,6 @@ static inline int security_inode_rename (struct inode *old_dir, return 0; } -static inline void security_inode_post_rename (struct inode *old_dir, - struct dentry *old_dentry, - struct inode *new_dir, - struct dentry *new_dentry) -{ } - static inline int security_inode_readlink (struct dentry *dentry) { return 0; -- cgit v1.2.3 From 383f2835eb9afb723af71850037b2f074ac9db60 Mon Sep 17 00:00:00 2001 From: "Chen, Kenneth W" Date: Fri, 9 Sep 2005 13:02:02 -0700 Subject: [PATCH] Prefetch kernel stacks to speed up context switch For architecture like ia64, the switch stack structure is fairly large (currently 528 bytes). For context switch intensive application, we found that significant amount of cache misses occurs in switch_to() function. The following patch adds a hook in the schedule() function to prefetch switch stack structure as soon as 'next' task is determined. This allows maximum overlap in prefetch cache lines for that structure. Signed-off-by: Ken Chen Cc: Ingo Molnar Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sched.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index ea1b5f32ec5c..c551e6a1447e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -604,6 +604,11 @@ extern int groups_search(struct group_info *group_info, gid_t grp); #define GROUP_AT(gi, i) \ ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK]) +#ifdef ARCH_HAS_PREFETCH_SWITCH_STACK +extern void prefetch_stack(struct task_struct*); +#else +static inline void prefetch_stack(struct task_struct *t) { } +#endif struct audit_context; /* See audit.c */ struct mempolicy; -- cgit v1.2.3 From fac92becdaecff64dd91daab0292c5131de92f0d Mon Sep 17 00:00:00 2001 From: Andrew Stribblehill Date: Fri, 9 Sep 2005 13:02:04 -0700 Subject: [PATCH] bfs: fix endianness, signedness; add trivial bugfix * Makes BFS code endianness-clean. * Fixes some signedness warnings. * Fixes a problem in fs/bfs/inode.c:164 where inodes not synced to disk don't get fully marked as clean. Here's how to reproduce it: # mount -o loop -t bfs /bfs.img /mnt # df -i /mnt Filesystem Inodes IUsed IFree IUse% Mounted on /bfs.img 48 1 47 3% /mnt # df -k /mnt Filesystem 1K-blocks Used Available Use% Mounted on /bfs.img 512 5 508 1% /mnt # cp 60k-archive.zip /mnt/mt.zip # df -k /mnt Filesystem 1K-blocks Used Available Use% Mounted on /bfs.img 512 65 447 13% /mnt # df -i /mnt Filesystem Inodes IUsed IFree IUse% Mounted on /bfs.img 48 2 46 5% /mnt # rm /mnt/mt.zip # echo $? 0 [If the unlink happens before the buffers flush, the following happens:] # df -i /mnt Filesystem Inodes IUsed IFree IUse% Mounted on /bfs.img 48 2 46 5% /mnt # df -k /mnt Filesystem 1K-blocks Used Available Use% Mounted on /bfs.img 512 65 447 13% /mnt fs/bfs/bfs.h | 1 Signed-off-by: Andrew Stribblehill Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bfs_fs.h | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bfs_fs.h b/include/linux/bfs_fs.h index f7f0913cd110..c1237aa92e38 100644 --- a/include/linux/bfs_fs.h +++ b/include/linux/bfs_fs.h @@ -14,8 +14,9 @@ #define BFS_INODES_PER_BLOCK 8 /* SVR4 vnode type values (bfs_inode->i_vtype) */ -#define BFS_VDIR 2 -#define BFS_VREG 1 +#define BFS_VDIR 2L +#define BFS_VREG 1L + /* BFS inode layout on disk */ struct bfs_inode { @@ -58,22 +59,22 @@ struct bfs_super_block { __u32 s_padding[118]; }; -#define BFS_NZFILESIZE(ip) \ - (((ip)->i_eoffset + 1) - (ip)->i_sblock * BFS_BSIZE) - -#define BFS_FILESIZE(ip) \ - ((ip)->i_sblock == 0 ? 0 : BFS_NZFILESIZE(ip)) - -#define BFS_FILEBLOCKS(ip) \ - ((ip)->i_sblock == 0 ? 0 : ((ip)->i_eblock + 1) - (ip)->i_sblock) #define BFS_OFF2INO(offset) \ ((((offset) - BFS_BSIZE) / sizeof(struct bfs_inode)) + BFS_ROOT_INO) #define BFS_INO2OFF(ino) \ ((__u32)(((ino) - BFS_ROOT_INO) * sizeof(struct bfs_inode)) + BFS_BSIZE) +#define BFS_NZFILESIZE(ip) \ + ((cpu_to_le32((ip)->i_eoffset) + 1) - cpu_to_le32((ip)->i_sblock) * BFS_BSIZE) + +#define BFS_FILESIZE(ip) \ + ((ip)->i_sblock == 0 ? 0 : BFS_NZFILESIZE(ip)) +#define BFS_FILEBLOCKS(ip) \ + ((ip)->i_sblock == 0 ? 0 : (cpu_to_le32((ip)->i_eblock) + 1) - cpu_to_le32((ip)->i_sblock)) #define BFS_UNCLEAN(bfs_sb, sb) \ - ((bfs_sb->s_from != -1) && (bfs_sb->s_to != -1) && !(sb->s_flags & MS_RDONLY)) + ((cpu_to_le32(bfs_sb->s_from) != -1) && (cpu_to_le32(bfs_sb->s_to) != -1) && !(sb->s_flags & MS_RDONLY)) + #endif /* _LINUX_BFS_FS_H */ -- cgit v1.2.3 From b3743fa4442fc172e950ff0eaf6aa96e7d5ce9be Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Fri, 9 Sep 2005 13:03:23 -0700 Subject: [PATCH] yenta: share code with PCI core Share code between setup-bus.c and yenta_socket.c: use the write-out code of resources to the bridge also in yenta_socket.c, as it provides useful debug output. In addition, it fixes the bug that the CPU-centric resource view might need to be transferred to the PCI-centric view: setup-bus.c does that, while yenta-socket.c did not. Signed-off-by: Dominik Brodowski Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 6caaba0af469..c62e89270237 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -326,6 +326,7 @@ extern struct pci_dev *pci_dev_get(struct pci_dev *dev); extern void pci_dev_put(struct pci_dev *dev); extern void pci_remove_bus(struct pci_bus *b); extern void pci_remove_bus_device(struct pci_dev *dev); +void pci_setup_cardbus(struct pci_bus *bus); /* Generic PCI functions exported to card drivers */ -- cgit v1.2.3 From 793cf9e6a54c698e109a599c8b8e303658fcaae6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 9 Sep 2005 13:03:37 -0700 Subject: [PATCH] v4l: common part Updates and tuner additions - Remove $Id CVS logs for V4L files - Included newer cards. - Added a new NEC protocol for ir based on pulse distance. - Enable ATSC support for DViCO FusionHDTV5 Gold. - Added tuner LG NTSC (TALN mini series). - Fixed tea5767 autodetection. - Resolve more tuner types. - Commented debug function removed from mainstream. - Remove comments from mainstream. Still on development tree. - linux/version dependencies removed. - BTSC Lang1 now is set to auto_stereo mode. - New tuner standby API. - i2c-core.c uses hexadecimal for the i2c address, so it should stay consistent. Signed-off-by: Uli Luckas Signed-off-by: Mac Michaels Signed-off-by: Michael Krufky Signed-off-by: Hermann Pitton Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/videodev.h | 3 --- include/linux/videodev2.h | 4 ---- 2 files changed, 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/videodev.h b/include/linux/videodev.h index 9d6fbde3d29c..1cc8c31b7988 100644 --- a/include/linux/videodev.h +++ b/include/linux/videodev.h @@ -3,7 +3,6 @@ #include #include -#include #define HAVE_V4L2 1 #include @@ -29,7 +28,6 @@ struct video_device void (*release)(struct video_device *vfd); -#if 1 /* to be removed in 2.7.x */ /* obsolete -- fops->owner is used instead */ struct module *owner; /* dev->driver_data will be used instead some day. @@ -37,7 +35,6 @@ struct video_device * so the switch over will be transparent for you. * Or use {pci|usb}_{get|set}_drvdata() directly. */ void *priv; -#endif /* for videodev.c intenal usage -- please don't touch */ int users; /* video_exclusive_{open|close} ... */ diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index acbfc525576d..f623a33b9abe 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -270,7 +270,6 @@ struct v4l2_timecode /* The above is based on SMPTE timecodes */ -#if 1 /* * M P E G C O M P R E S S I O N P A R A M E T E R S * @@ -357,7 +356,6 @@ struct v4l2_mpeg_compression { /* I don't expect the above being perfect yet ;) */ __u32 reserved_5[8]; }; -#endif struct v4l2_jpegcompression { @@ -871,10 +869,8 @@ struct v4l2_streamparm #define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc) #define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format) #define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format) -#if 1 /* experimental */ #define VIDIOC_G_MPEGCOMP _IOR ('V', 6, struct v4l2_mpeg_compression) #define VIDIOC_S_MPEGCOMP _IOW ('V', 7, struct v4l2_mpeg_compression) -#endif #define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers) #define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer) #define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer) -- cgit v1.2.3 From 8b6490e5faafb3a16ea45654fb55f9ff086f1495 Mon Sep 17 00:00:00 2001 From: Dipankar Sarma Date: Fri, 9 Sep 2005 13:04:07 -0700 Subject: [PATCH] files: fix rcu initializers First of a number of files_lock scaability patches. Here are the x86 numbers - tiobench on a 4(8)-way (HT) P4 system on ramdisk : (lockfree) Test 2.6.10-vanilla Stdev 2.6.10-fd Stdev ------------------------------------------------------------- Seqread 1400.8 11.52 1465.4 34.27 Randread 1594 8.86 2397.2 29.21 Seqwrite 242.72 3.47 238.46 6.53 Randwrite 445.74 9.15 446.4 9.75 The performance improvement is very significant. We are getting killed by the cacheline bouncing of the files_struct lock here. Writes on ramdisk (ext2) seems to vary just too much to get any meaningful number. Also, With Tridge's thread_perf test on a 4(8)-way (HT) P4 xeon system : 2.6.12-rc5-vanilla : Running test 'readwrite' with 8 tasks Threads 0.34 +/- 0.01 seconds Processes 0.16 +/- 0.00 seconds 2.6.12-rc5-fd : Running test 'readwrite' with 8 tasks Threads 0.17 +/- 0.02 seconds Processes 0.17 +/- 0.02 seconds I repeated the measurements on ramfs (as opposed to ext2 on ramdisk in the earlier measurement) and I got more consistent results from tiobench : 4(8) way xeon P4 ----------------- (lock-free) Test 2.6.12-rc5 Stdev 2.6.12-rc5-fd Stdev ------------------------------------------------------------- Seqread 1282 18.59 1343.6 26.37 Randread 1517 7 2415 34.27 Seqwrite 702.2 5.27 709.46 5.9 Randwrite 846.86 15.15 919.68 21.4 4-way ppc64 ------------ (lock-free) Test 2.6.12-rc5 Stdev 2.6.12-rc5-fd Stdev ------------------------------------------------------------- Seqread 1549 91.16 1569.6 47.2 Randread 1473.6 25.11 1585.4 69.99 Seqwrite 1096.8 20.03 1136 29.61 Randwrite 1189.6 4.04 1275.2 32.96 Also running Tridge's thread_perf test on ppc64 : 2.6.12-rc5-vanilla -------------------- Running test 'readwrite' with 4 tasks Threads 0.20 +/- 0.02 seconds Processes 0.16 +/- 0.01 seconds 2.6.12-rc5-fd -------------------- Running test 'readwrite' with 4 tasks Threads 0.18 +/- 0.04 seconds Processes 0.16 +/- 0.01 seconds The benefits are huge (upto ~60%) in some cases on x86 primarily due to the atomic operations during acquisition of ->file_lock and cache line bouncing in fast path. ppc64 benefits are modest due to LL/SC based locking, but still statistically significant. This patch: RCU head initilizer no longer needs the head varible name since we don't use list.h lists anymore. Signed-off-by: Dipankar Sarma Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rcupdate.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index fd276adf0fd5..4e65eb44adfd 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -52,8 +52,8 @@ struct rcu_head { void (*func)(struct rcu_head *head); }; -#define RCU_HEAD_INIT(head) { .next = NULL, .func = NULL } -#define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT(head) +#define RCU_HEAD_INIT { .next = NULL, .func = NULL } +#define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT #define INIT_RCU_HEAD(ptr) do { \ (ptr)->next = NULL; (ptr)->func = NULL; \ } while (0) -- cgit v1.2.3 From c0dfb2905126e9e94edebbce8d3e05001301f52d Mon Sep 17 00:00:00 2001 From: Dipankar Sarma Date: Fri, 9 Sep 2005 13:04:09 -0700 Subject: [PATCH] files: rcuref APIs Adds a set of primitives to do reference counting for objects that are looked up without locks using RCU. Signed-off-by: Ravikiran Thirumalai Signed-off-by: Dipankar Sarma Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rcuref.h | 220 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 include/linux/rcuref.h (limited to 'include/linux') diff --git a/include/linux/rcuref.h b/include/linux/rcuref.h new file mode 100644 index 000000000000..e1adbba14b67 --- /dev/null +++ b/include/linux/rcuref.h @@ -0,0 +1,220 @@ +/* + * rcuref.h + * + * Reference counting for elements of lists/arrays protected by + * RCU. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2005 + * + * Author: Dipankar Sarma + * Ravikiran Thirumalai + * + * See Documentation/RCU/rcuref.txt for detailed user guide. + * + */ + +#ifndef _RCUREF_H_ +#define _RCUREF_H_ + +#ifdef __KERNEL__ + +#include +#include +#include +#include + +/* + * These APIs work on traditional atomic_t counters used in the + * kernel for reference counting. Under special circumstances + * where a lock-free get() operation races with a put() operation + * these APIs can be used. See Documentation/RCU/rcuref.txt. + */ + +#ifdef __HAVE_ARCH_CMPXCHG + +/** + * rcuref_inc - increment refcount for object. + * @rcuref: reference counter in the object in question. + * + * This should be used only for objects where we use RCU and + * use the rcuref_inc_lf() api to acquire a reference + * in a lock-free reader-side critical section. + */ +static inline void rcuref_inc(atomic_t *rcuref) +{ + atomic_inc(rcuref); +} + +/** + * rcuref_dec - decrement refcount for object. + * @rcuref: reference counter in the object in question. + * + * This should be used only for objects where we use RCU and + * use the rcuref_inc_lf() api to acquire a reference + * in a lock-free reader-side critical section. + */ +static inline void rcuref_dec(atomic_t *rcuref) +{ + atomic_dec(rcuref); +} + +/** + * rcuref_dec_and_test - decrement refcount for object and test + * @rcuref: reference counter in the object. + * @release: pointer to the function that will clean up the object + * when the last reference to the object is released. + * This pointer is required. + * + * Decrement the refcount, and if 0, return 1. Else return 0. + * + * This should be used only for objects where we use RCU and + * use the rcuref_inc_lf() api to acquire a reference + * in a lock-free reader-side critical section. + */ +static inline int rcuref_dec_and_test(atomic_t *rcuref) +{ + return atomic_dec_and_test(rcuref); +} + +/* + * cmpxchg is needed on UP too, if deletions to the list/array can happen + * in interrupt context. + */ + +/** + * rcuref_inc_lf - Take reference to an object in a read-side + * critical section protected by RCU. + * @rcuref: reference counter in the object in question. + * + * Try and increment the refcount by 1. The increment might fail if + * the reference counter has been through a 1 to 0 transition and + * is no longer part of the lock-free list. + * Returns non-zero on successful increment and zero otherwise. + */ +static inline int rcuref_inc_lf(atomic_t *rcuref) +{ + int c, old; + c = atomic_read(rcuref); + while (c && (old = cmpxchg(&rcuref->counter, c, c + 1)) != c) + c = old; + return c; +} + +#else /* !__HAVE_ARCH_CMPXCHG */ + +extern spinlock_t __rcuref_hash[]; + +/* + * Use a hash table of locks to protect the reference count + * since cmpxchg is not available in this arch. + */ +#ifdef CONFIG_SMP +#define RCUREF_HASH_SIZE 4 +#define RCUREF_HASH(k) \ + (&__rcuref_hash[(((unsigned long)k)>>8) & (RCUREF_HASH_SIZE-1)]) +#else +#define RCUREF_HASH_SIZE 1 +#define RCUREF_HASH(k) &__rcuref_hash[0] +#endif /* CONFIG_SMP */ + +/** + * rcuref_inc - increment refcount for object. + * @rcuref: reference counter in the object in question. + * + * This should be used only for objects where we use RCU and + * use the rcuref_inc_lf() api to acquire a reference in a lock-free + * reader-side critical section. + */ +static inline void rcuref_inc(atomic_t *rcuref) +{ + unsigned long flags; + spin_lock_irqsave(RCUREF_HASH(rcuref), flags); + rcuref->counter += 1; + spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags); +} + +/** + * rcuref_dec - decrement refcount for object. + * @rcuref: reference counter in the object in question. + * + * This should be used only for objects where we use RCU and + * use the rcuref_inc_lf() api to acquire a reference in a lock-free + * reader-side critical section. + */ +static inline void rcuref_dec(atomic_t *rcuref) +{ + unsigned long flags; + spin_lock_irqsave(RCUREF_HASH(rcuref), flags); + rcuref->counter -= 1; + spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags); +} + +/** + * rcuref_dec_and_test - decrement refcount for object and test + * @rcuref: reference counter in the object. + * @release: pointer to the function that will clean up the object + * when the last reference to the object is released. + * This pointer is required. + * + * Decrement the refcount, and if 0, return 1. Else return 0. + * + * This should be used only for objects where we use RCU and + * use the rcuref_inc_lf() api to acquire a reference in a lock-free + * reader-side critical section. + */ +static inline int rcuref_dec_and_test(atomic_t *rcuref) +{ + unsigned long flags; + spin_lock_irqsave(RCUREF_HASH(rcuref), flags); + rcuref->counter--; + if (!rcuref->counter) { + spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags); + return 1; + } else { + spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags); + return 0; + } +} + +/** + * rcuref_inc_lf - Take reference to an object of a lock-free collection + * by traversing a lock-free list/array. + * @rcuref: reference counter in the object in question. + * + * Try and increment the refcount by 1. The increment might fail if + * the reference counter has been through a 1 to 0 transition and + * object is no longer part of the lock-free list. + * Returns non-zero on successful increment and zero otherwise. + */ +static inline int rcuref_inc_lf(atomic_t *rcuref) +{ + int ret; + unsigned long flags; + spin_lock_irqsave(RCUREF_HASH(rcuref), flags); + if (rcuref->counter) + ret = rcuref->counter++; + else + ret = 0; + spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags); + return ret; +} + + +#endif /* !__HAVE_ARCH_CMPXCHG */ + +#endif /* __KERNEL__ */ +#endif /* _RCUREF_H_ */ -- cgit v1.2.3 From badf16621c1f9d1ac753be056fce11b43d6e0be5 Mon Sep 17 00:00:00 2001 From: Dipankar Sarma Date: Fri, 9 Sep 2005 13:04:10 -0700 Subject: [PATCH] files: break up files struct In order for the RCU to work, the file table array, sets and their sizes must be updated atomically. Instead of ensuring this through too many memory barriers, we put the arrays and their sizes in a separate structure. This patch takes the first step of putting the file table elements in a separate structure fdtable that is embedded withing files_struct. It also changes all the users to refer to the file table using files_fdtable() macro. Subsequent applciation of RCU becomes easier after this. Signed-off-by: Dipankar Sarma Signed-Off-By: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/file.h | 23 +++++++++++++++-------- include/linux/init_task.h | 13 +++++++++---- 2 files changed, 24 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/file.h b/include/linux/file.h index 5206beb9a80e..db372230848e 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -16,23 +16,29 @@ */ #define NR_OPEN_DEFAULT BITS_PER_LONG +struct fdtable { + unsigned int max_fds; + int max_fdset; + int next_fd; + struct file ** fd; /* current fd array */ + fd_set *close_on_exec; + fd_set *open_fds; +}; + /* * Open file table structure */ struct files_struct { atomic_t count; spinlock_t file_lock; /* Protects all the below members. Nests inside tsk->alloc_lock */ - int max_fds; - int max_fdset; - int next_fd; - struct file ** fd; /* current fd array */ - fd_set *close_on_exec; - fd_set *open_fds; + struct fdtable fdtab; fd_set close_on_exec_init; fd_set open_fds_init; struct file * fd_array[NR_OPEN_DEFAULT]; }; +#define files_fdtable(files) (&(files)->fdtab) + extern void FASTCALL(__fput(struct file *)); extern void FASTCALL(fput(struct file *)); @@ -63,9 +69,10 @@ extern int expand_files(struct files_struct *, int nr); static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd) { struct file * file = NULL; + struct fdtable *fdt = files_fdtable(files); - if (fd < files->max_fds) - file = files->fd[fd]; + if (fd < fdt->max_fds) + file = fdt->fd[fd]; return file; } diff --git a/include/linux/init_task.h b/include/linux/init_task.h index c727c195a91a..94aefa54a1b5 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -3,16 +3,21 @@ #include -#define INIT_FILES \ -{ \ - .count = ATOMIC_INIT(1), \ - .file_lock = SPIN_LOCK_UNLOCKED, \ +#define INIT_FDTABLE \ +{ \ .max_fds = NR_OPEN_DEFAULT, \ .max_fdset = __FD_SETSIZE, \ .next_fd = 0, \ .fd = &init_files.fd_array[0], \ .close_on_exec = &init_files.close_on_exec_init, \ .open_fds = &init_files.open_fds_init, \ +} + +#define INIT_FILES \ +{ \ + .count = ATOMIC_INIT(1), \ + .file_lock = SPIN_LOCK_UNLOCKED, \ + .fdtab = INIT_FDTABLE, \ .close_on_exec_init = { { 0, } }, \ .open_fds_init = { { 0, } }, \ .fd_array = { NULL, } \ -- cgit v1.2.3 From ab2af1f5005069321c5d130f09cce577b03f43ef Mon Sep 17 00:00:00 2001 From: Dipankar Sarma Date: Fri, 9 Sep 2005 13:04:13 -0700 Subject: [PATCH] files: files struct with RCU Patch to eliminate struct files_struct.file_lock spinlock on the reader side and use rcu refcounting rcuref_xxx api for the f_count refcounter. The updates to the fdtable are done by allocating a new fdtable structure and setting files->fdt to point to the new structure. The fdtable structure is protected by RCU thereby allowing lock-free lookup. For fd arrays/sets that are vmalloced, we use keventd to free them since RCU callbacks can't sleep. A global list of fdtable to be freed is not scalable, so we use a per-cpu list. If keventd is already handling the current cpu's work, we use a timer to defer queueing of that work. Since the last publication, this patch has been re-written to avoid using explicit memory barriers and use rcu_assign_pointer(), rcu_dereference() premitives instead. This required that the fd information is kept in a separate structure (fdtable) and updated atomically. Signed-off-by: Dipankar Sarma Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/file.h | 11 +++++++++-- include/linux/fs.h | 4 +++- include/linux/init_task.h | 5 +++++ 3 files changed, 17 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/file.h b/include/linux/file.h index db372230848e..f5bbd4c508b3 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -9,6 +9,7 @@ #include #include #include +#include /* * The default fd array needs to be at least BITS_PER_LONG, @@ -23,6 +24,9 @@ struct fdtable { struct file ** fd; /* current fd array */ fd_set *close_on_exec; fd_set *open_fds; + struct rcu_head rcu; + struct files_struct *free_files; + struct fdtable *next; }; /* @@ -31,13 +35,14 @@ struct fdtable { struct files_struct { atomic_t count; spinlock_t file_lock; /* Protects all the below members. Nests inside tsk->alloc_lock */ + struct fdtable *fdt; struct fdtable fdtab; fd_set close_on_exec_init; fd_set open_fds_init; struct file * fd_array[NR_OPEN_DEFAULT]; }; -#define files_fdtable(files) (&(files)->fdtab) +#define files_fdtable(files) (rcu_dereference((files)->fdt)) extern void FASTCALL(__fput(struct file *)); extern void FASTCALL(fput(struct file *)); @@ -65,6 +70,8 @@ extern fd_set *alloc_fdset(int); extern void free_fdset(fd_set *, int); extern int expand_files(struct files_struct *, int nr); +extern void free_fdtable(struct fdtable *fdt); +extern void __init files_defer_init(void); static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd) { @@ -72,7 +79,7 @@ static inline struct file * fcheck_files(struct files_struct *files, unsigned in struct fdtable *fdt = files_fdtable(files); if (fd < fdt->max_fds) - file = fdt->fd[fd]; + file = rcu_dereference(fdt->fd[fd]); return file; } diff --git a/include/linux/fs.h b/include/linux/fs.h index fd93ab7da905..7f61227827d7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -9,6 +9,7 @@ #include #include #include +#include /* * It's silly to have NR_OPEN bigger than NR_FILE, but you can change @@ -597,12 +598,13 @@ struct file { spinlock_t f_ep_lock; #endif /* #ifdef CONFIG_EPOLL */ struct address_space *f_mapping; + struct rcu_head f_rcuhead; }; extern spinlock_t files_lock; #define file_list_lock() spin_lock(&files_lock); #define file_list_unlock() spin_unlock(&files_lock); -#define get_file(x) atomic_inc(&(x)->f_count) +#define get_file(x) rcuref_inc(&(x)->f_count) #define file_count(x) atomic_read(&(x)->f_count) #define MAX_NON_LFS ((1UL<<31) - 1) diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 94aefa54a1b5..68ab5f2ab9cd 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -2,6 +2,7 @@ #define _LINUX__INIT_TASK_H #include +#include #define INIT_FDTABLE \ { \ @@ -11,12 +12,16 @@ .fd = &init_files.fd_array[0], \ .close_on_exec = &init_files.close_on_exec_init, \ .open_fds = &init_files.open_fds_init, \ + .rcu = RCU_HEAD_INIT, \ + .free_files = NULL, \ + .next = NULL, \ } #define INIT_FILES \ { \ .count = ATOMIC_INIT(1), \ .file_lock = SPIN_LOCK_UNLOCKED, \ + .fdt = &init_files.fdtab, \ .fdtab = INIT_FDTABLE, \ .close_on_exec_init = { { 0, } }, \ .open_fds_init = { { 0, } }, \ -- cgit v1.2.3 From 7726e9e10fc6e026ed2dc00e48f4a3ffc1254ad2 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Fri, 9 Sep 2005 13:04:29 -0700 Subject: [PATCH] fbdev: Add fbset -a support Add capability to fbdev to listen to the FB_ACTIVATE_ALL flag. If set, it notifies fbcon that all consoles must be set to the current var. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fb.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fb.h b/include/linux/fb.h index bc24beeed971..70da819df0f5 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -495,6 +495,9 @@ struct fb_cursor_user { #define FB_EVENT_BLANK 0x08 /* Private modelist is to be replaced */ #define FB_EVENT_NEW_MODELIST 0x09 +/* The resolution of the passed in fb_info about to change and + all vc's should be changed */ +#define FB_EVENT_MODE_CHANGE_ALL 0x0A struct fb_event { struct fb_info *info; -- cgit v1.2.3 From d2d58384fc5d4c0fe2d8e34bc2d15a90a9bb372a Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Fri, 9 Sep 2005 13:04:31 -0700 Subject: [PATCH] vesafb: Add blanking support Add rudimentary support by manipulating the VGA registers. However, not all vesa modes are VGA compatible, so VGA compatiblity is checked first. Only 2 levels are supported, powerup and powerdown. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tty.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index 59ff42c629ec..1267f88ece6e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -74,7 +74,8 @@ struct screen_info { u16 vesapm_off; /* 0x30 */ u16 pages; /* 0x32 */ u16 vesa_attributes; /* 0x34 */ - /* 0x36 -- 0x3f reserved for future expansion */ + u32 capabilities; /* 0x36 */ + /* 0x3a -- 0x3f reserved for future expansion */ }; extern struct screen_info screen_info; -- cgit v1.2.3 From 5e518d7672dea4cd7c60871e40d0490c52f01d13 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Fri, 9 Sep 2005 13:04:34 -0700 Subject: [PATCH] fbdev: Resurrect hooks to get EDID from firmware For the i386, code is already present in video.S that gets the EDID from the video BIOS. Make this visible so drivers can also use this data as fallback when i2c does not work. To ensure that the EDID block is returned for the primary graphics adapter only, by check if the IORESOURCE_ROM_SHADOW flag is set. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fb.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fb.h b/include/linux/fb.h index 70da819df0f5..e3e16f43b1bb 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -859,7 +859,9 @@ extern int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, extern int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info); extern int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var); -extern void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs); +extern const unsigned char *fb_firmware_edid(struct device *device); +extern void fb_edid_to_monspecs(unsigned char *edid, + struct fb_monspecs *specs); extern void fb_destroy_modedb(struct fb_videomode *modedb); /* drivers/video/modedb.c */ -- cgit v1.2.3 From b8c909454f046b59065c6997b651fe20cd90c0f4 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Fri, 9 Sep 2005 13:04:37 -0700 Subject: [PATCH] fbdev: Fix greater than 1 bit monochrome color handling Currently, fbcon assumes that the visual FB_VISUAL_MONO* is always 1 bit. According to Geert, there are old hardware where it's possible to have monochrome at 8-bit, but has only 2 colors, black - 0x00 and white - 0xff. Fix color handlers (fb_get_color_depth, and get_color) for this special case. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fb.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fb.h b/include/linux/fb.h index e3e16f43b1bb..c71a7162e098 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -823,7 +823,8 @@ extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx, u32 height, u32 shift_high, u32 shift_low, u32 mod); extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height); extern void fb_set_suspend(struct fb_info *info, int state); -extern int fb_get_color_depth(struct fb_var_screeninfo *var); +extern int fb_get_color_depth(struct fb_var_screeninfo *var, + struct fb_fix_screeninfo *fix); extern int fb_get_options(char *name, char **option); extern int fb_new_modelist(struct fb_info *info); -- cgit v1.2.3 From 544393fe584d333480659a4bed30f5295355df11 Mon Sep 17 00:00:00 2001 From: Thomas Winischhofer Date: Fri, 9 Sep 2005 13:04:45 -0700 Subject: [PATCH] sisfb update This lifts sisfb from version 1.7.17 to version 1.8.9. Changes include: - Added support for XGI V3XT, V5, V8, Z7 chipsets, including POSTing of all of these chipsets. - Added support for latest SiS chipsets (761). - Added support for SiS76x memory "hybrid" mode. - Added support for new LCD resolutions (eg 1280x854, 856x480). - Fixed support for 320x240 STN panels (for embedded devices). - Fixed many HDTV modes (525p, 750p, 1080i). - Fixed PCI config register reading/writing to use proper kernel functions for this purpose. - Fixed PCI ROM handling to use the kernel's proper functions. - Removed lots of "typedef"s. - Removed lots of code which was for X.org/XFree86 only. - Fixed coding style in many places. - Removed lots of 2.4 cruft. - Reduced stack size by unifying two previously separate structs into one. - Added new hooks for memory allocation (for DRM). Now the driver can truly handle multiple cards, including memory management. - Fixed numerous minor bugs. Signed-off-by: Thomas Winischhofer Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fb.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fb.h b/include/linux/fb.h index c71a7162e098..34814a0b2378 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -107,6 +107,8 @@ #define FB_ACCEL_NV_20 44 /* nVidia Arch 20 */ #define FB_ACCEL_NV_30 45 /* nVidia Arch 30 */ #define FB_ACCEL_NV_40 46 /* nVidia Arch 40 */ +#define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari V3XT, V5, V8 */ +#define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */ #define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */ #define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */ #define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */ -- cgit v1.2.3 From cdb9b9f730eac4f947a2c552806a3a550bf019ef Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 6 Sep 2005 09:31:03 +1000 Subject: [PATCH] PCI: Small rearrangement of PCI probing code This patch makes some small rearrangements of the PCI probing code in order to make it possible for arch code to set up the PCI tree without needing to duplicate code from the PCI layer unnecessarily. PPC64 will use this to set up the PCI tree from the Open Firmware device tree, which we need to do on logically-partitioned pSeries systems. Signed-off-by: Paul Mackerras Signed-off-by: Greg Kroah-Hartman --- include/linux/pci.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 609499356e07..9c7aecf0c599 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -315,8 +315,11 @@ static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *s pci_bus_add_devices(root_bus); return root_bus; } +struct pci_bus *pci_create_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); +struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr); int pci_scan_slot(struct pci_bus *bus, int devfn); struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); +void pci_device_add(struct pci_dev *dev, struct pci_bus *bus); unsigned int pci_scan_child_bus(struct pci_bus *bus); void pci_bus_add_device(struct pci_dev *dev); void pci_read_bridge_bases(struct pci_bus *child); -- cgit v1.2.3 From 96fe6a2109db29cd15b90a093c16e6cb4b19371a Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Fri, 9 Sep 2005 13:09:58 -0700 Subject: [PATCH] fbdev: Add VESA Coordinated Video Timings (CVT) support The Coordinated Video Timings (CVT) is the latest standard approved by VESA concerning video timings generation. It addresses the limitation of GTF which is designed mainly for CRT displays. CRT's have a high blanking requirement (as much as 25% of the horizontal frame length) which artificially increases the pixelclock. Digital displays, on the other hand, needs to conserve the pixelclock as much as possible. The GTF also does not take into account the different aspect ratios in its calculation. The new function added is fb_find_mode_cvt(). It is called by fb_find_mode() if it recognizes a mode option string formatted for CVT. The format is: x[M][R][-][][i][m] The 'M' tells the function to calculate using CVT. On it's own, it will compute a timing for CRT displays at 60Hz. If the 'R' is specified, 'reduced blanking' computation will be used, best for flatpanels. The 'i' and the 'm' is for 'interlaced mode' and 'with margins' respectively. To determine if CVT was used, check for dmesg for something like this: CVT Mode - M[-R], ie: .480M3-R (800x600 reduced blanking) where: pix - product of xres and yres, in MB M - is a CVT mode n - the aspect ratio (3 - 4:3; 4 - 5:4; 9 - 16:9, 15:9; A - 16:10) -R - reduced blanking Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/fb.h b/include/linux/fb.h index 34814a0b2378..9a4f035e9fdc 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -866,6 +866,7 @@ extern const unsigned char *fb_firmware_edid(struct device *device); extern void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs); extern void fb_destroy_modedb(struct fb_videomode *modedb); +extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb); /* drivers/video/modedb.c */ #define VESA_MODEDB_SIZE 34 -- cgit v1.2.3 From 829e79b680210c4f4de435af6e1f90451922fc7d Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Fri, 9 Sep 2005 13:10:04 -0700 Subject: [PATCH] fbcon: Break up bit_putcs into its component functions The function bit_putcs() in drivers/video/console/bitblit.c is becoming large. Break it up into its component functions (bit_putcs_unaligned and bit_putcs_aligned). Incorporated fb_pad_aligned_buffer() optimization by Roman Zippel. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fb.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fb.h b/include/linux/fb.h index 9a4f035e9fdc..82e39cd0c4fb 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -833,6 +833,21 @@ extern int fb_new_modelist(struct fb_info *info); extern struct fb_info *registered_fb[FB_MAX]; extern int num_registered_fb; +static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, + u8 *src, u32 s_pitch, u32 height) +{ + int i, j; + + d_pitch -= s_pitch; + + for (i = height; i--; ) { + /* s_pitch is a few bytes at the most, memcpy is suboptimal */ + for (j = 0; j < s_pitch; j++) + *dst++ = *src++; + dst += d_pitch; + } +} + /* drivers/video/fbsysfs.c */ extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev); extern void framebuffer_release(struct fb_info *info); -- cgit v1.2.3 From d8a5ba45457e4a22aa39c939121efd7bb6c76672 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 9 Sep 2005 13:10:26 -0700 Subject: [PATCH] FUSE - core This patch adds FUSE core. This contains the following files: o inode.c - superblock operations (alloc_inode, destroy_inode, read_inode, clear_inode, put_super, show_options) - registers FUSE filesystem o fuse_i.h - private header file Requirements ============ The most important difference between orinary filesystems and FUSE is the fact, that the filesystem data/metadata is provided by a userspace process run with the privileges of the mount "owner" instead of the kernel, or some remote entity usually running with elevated privileges. The security implication of this is that a non-privileged user must not be able to use this capability to compromise the system. Obvious requirements arising from this are: - mount owner should not be able to get elevated privileges with the help of the mounted filesystem - mount owner should not be able to induce undesired behavior in other users' or the super user's processes - mount owner should not get illegitimate access to information from other users' and the super user's processes These are currently ensured with the following constraints: 1) mount is only allowed to directory or file which the mount owner can modify without limitation (write access + no sticky bit for directories) 2) nosuid,nodev mount options are forced 3) any process running with fsuid different from the owner is denied all access to the filesystem 1) and 2) are ensured by the "fusermount" mount utility which is a setuid root application doing the actual mount operation. 3) is ensured by a check in the permission() method in kernel I started thinking about doing 3) in a different way because Christoph H. made a big deal out of it, saying that FUSE is unacceptable into mainline in this form. The suggested use of private namespaces would be OK, but in their current form have many limitations that make their use impractical (as discussed in this thread). Suggested improvements that would address these limitations: - implement shared subtrees - allow a process to join an existing namespace (make namespaces first-class objects) - implement the namespace creation/joining in a PAM module With all that in place the check of owner against current->fsuid may be removed from the FUSE kernel module, without compromising the security requirements. Suid programs still interesting questions, since they get access even to the private namespace causing some information leak (exact order/timing of filesystem operations performed), giving some ptrace-like capabilities to unprivileged users. BTW this problem is not strictly limited to the namespace approach, since suid programs setting fsuid and accessing users' files will succeed with the current approach too. Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fuse.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 include/linux/fuse.h (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h new file mode 100644 index 000000000000..2b1f4ae01e9d --- /dev/null +++ b/include/linux/fuse.h @@ -0,0 +1,38 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2001-2005 Miklos Szeredi + + This program can be distributed under the terms of the GNU GPL. + See the file COPYING. +*/ + +/* This file defines the kernel interface of FUSE */ + +#include + +/** Version number of this interface */ +#define FUSE_KERNEL_VERSION 5 + +/** Minor version number of this interface */ +#define FUSE_KERNEL_MINOR_VERSION 1 + +/** The node ID of the root inode */ +#define FUSE_ROOT_ID 1 + +struct fuse_attr { + __u64 ino; + __u64 size; + __u64 blocks; + __u64 atime; + __u64 mtime; + __u64 ctime; + __u32 atimensec; + __u32 mtimensec; + __u32 ctimensec; + __u32 mode; + __u32 nlink; + __u32 uid; + __u32 gid; + __u32 rdev; +}; + -- cgit v1.2.3 From 334f485df85ac7736ebe14940bf0a059c5f26d7d Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 9 Sep 2005 13:10:27 -0700 Subject: [PATCH] FUSE - device functions This adds the FUSE device handling functions. This contains the following files: o dev.c - fuse device operations (read, write, release, poll) - registers misc device - support for sending requests to userspace Signed-off-by: Miklos Szeredi Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fuse.h | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 2b1f4ae01e9d..a1aebd7104c4 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -11,7 +11,7 @@ #include /** Version number of this interface */ -#define FUSE_KERNEL_VERSION 5 +#define FUSE_KERNEL_VERSION 6 /** Minor version number of this interface */ #define FUSE_KERNEL_MINOR_VERSION 1 @@ -19,6 +19,12 @@ /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 +/** The major number of the fuse character device */ +#define FUSE_MAJOR 10 + +/** The minor number of the fuse character device */ +#define FUSE_MINOR 229 + struct fuse_attr { __u64 ino; __u64 size; @@ -36,3 +42,31 @@ struct fuse_attr { __u32 rdev; }; +enum fuse_opcode { + FUSE_INIT = 26 +}; + +/* Conservative buffer size for the client */ +#define FUSE_MAX_IN 8192 + +struct fuse_init_in_out { + __u32 major; + __u32 minor; +}; + +struct fuse_in_header { + __u32 len; + __u32 opcode; + __u64 unique; + __u64 nodeid; + __u32 uid; + __u32 gid; + __u32 pid; +}; + +struct fuse_out_header { + __u32 len; + __s32 error; + __u64 unique; +}; + -- cgit v1.2.3 From e5e5558e923f35839108a12718494ecb73fb782f Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 9 Sep 2005 13:10:28 -0700 Subject: [PATCH] FUSE - read-only operations This patch adds the read-only filesystem operations of FUSE. This contains the following files: o dir.c - directory, symlink and file-inode operations The following operations are added: o lookup o getattr o readlink o follow_link o directory open o readdir o directory release o permission o dentry revalidate o statfs Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fuse.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h index a1aebd7104c4..21b9ba16f8d5 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -42,13 +42,61 @@ struct fuse_attr { __u32 rdev; }; +struct fuse_kstatfs { + __u64 blocks; + __u64 bfree; + __u64 bavail; + __u64 files; + __u64 ffree; + __u32 bsize; + __u32 namelen; +}; + enum fuse_opcode { + FUSE_LOOKUP = 1, + FUSE_FORGET = 2, /* no reply */ + FUSE_GETATTR = 3, + FUSE_READLINK = 5, + FUSE_GETDIR = 7, + FUSE_STATFS = 17, FUSE_INIT = 26 }; /* Conservative buffer size for the client */ #define FUSE_MAX_IN 8192 +#define FUSE_NAME_MAX 1024 + +struct fuse_entry_out { + __u64 nodeid; /* Inode ID */ + __u64 generation; /* Inode generation: nodeid:gen must + be unique for the fs's lifetime */ + __u64 entry_valid; /* Cache timeout for the name */ + __u64 attr_valid; /* Cache timeout for the attributes */ + __u32 entry_valid_nsec; + __u32 attr_valid_nsec; + struct fuse_attr attr; +}; + +struct fuse_forget_in { + __u64 version; +}; + +struct fuse_attr_out { + __u64 attr_valid; /* Cache timeout for the attributes */ + __u32 attr_valid_nsec; + __u32 dummy; + struct fuse_attr attr; +}; + +struct fuse_getdir_out { + __u32 fd; +}; + +struct fuse_statfs_out { + struct fuse_kstatfs st; +}; + struct fuse_init_in_out { __u32 major; __u32 minor; @@ -70,3 +118,15 @@ struct fuse_out_header { __u64 unique; }; +struct fuse_dirent { + __u64 ino; + __u64 off; + __u32 namelen; + __u32 type; + char name[0]; +}; + +#define FUSE_NAME_OFFSET ((unsigned) ((struct fuse_dirent *) 0)->name) +#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1)) +#define FUSE_DIRENT_SIZE(d) \ + FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) -- cgit v1.2.3 From 9e6268db496a2592e89457537ea54a496feabb77 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 9 Sep 2005 13:10:29 -0700 Subject: [PATCH] FUSE - read-write operations This patch adds the write filesystem operations of FUSE. The following operations are added: o setattr o symlink o mknod o mkdir o create o unlink o rmdir o rename o link Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fuse.h | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 21b9ba16f8d5..19d69a3e1623 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -11,7 +11,7 @@ #include /** Version number of this interface */ -#define FUSE_KERNEL_VERSION 6 +#define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ #define FUSE_KERNEL_MINOR_VERSION 1 @@ -52,12 +52,28 @@ struct fuse_kstatfs { __u32 namelen; }; +#define FATTR_MODE (1 << 0) +#define FATTR_UID (1 << 1) +#define FATTR_GID (1 << 2) +#define FATTR_SIZE (1 << 3) +#define FATTR_ATIME (1 << 4) +#define FATTR_MTIME (1 << 5) +#define FATTR_CTIME (1 << 6) + enum fuse_opcode { FUSE_LOOKUP = 1, FUSE_FORGET = 2, /* no reply */ FUSE_GETATTR = 3, + FUSE_SETATTR = 4, FUSE_READLINK = 5, + FUSE_SYMLINK = 6, FUSE_GETDIR = 7, + FUSE_MKNOD = 8, + FUSE_MKDIR = 9, + FUSE_UNLINK = 10, + FUSE_RMDIR = 11, + FUSE_RENAME = 12, + FUSE_LINK = 13, FUSE_STATFS = 17, FUSE_INIT = 26 }; @@ -66,6 +82,7 @@ enum fuse_opcode { #define FUSE_MAX_IN 8192 #define FUSE_NAME_MAX 1024 +#define FUSE_SYMLINK_MAX 4096 struct fuse_entry_out { __u64 nodeid; /* Inode ID */ @@ -79,7 +96,7 @@ struct fuse_entry_out { }; struct fuse_forget_in { - __u64 version; + __u64 nlookup; }; struct fuse_attr_out { @@ -93,6 +110,28 @@ struct fuse_getdir_out { __u32 fd; }; +struct fuse_mknod_in { + __u32 mode; + __u32 rdev; +}; + +struct fuse_mkdir_in { + __u32 mode; +}; + +struct fuse_rename_in { + __u64 newdir; +}; + +struct fuse_link_in { + __u64 oldnodeid; +}; + +struct fuse_setattr_in { + __u32 valid; + struct fuse_attr attr; +}; + struct fuse_statfs_out { struct fuse_kstatfs st; }; -- cgit v1.2.3 From b6aeadeda22a9aa322fdfcd3f4c69ccf0da5cbdd Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 9 Sep 2005 13:10:30 -0700 Subject: [PATCH] FUSE - file operations This patch adds the file operations of FUSE. The following operations are added: o open o flush o release o fsync o readpage o commit_write Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fuse.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 19d69a3e1623..61f34636ffbc 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -74,7 +74,13 @@ enum fuse_opcode { FUSE_RMDIR = 11, FUSE_RENAME = 12, FUSE_LINK = 13, + FUSE_OPEN = 14, + FUSE_READ = 15, + FUSE_WRITE = 16, FUSE_STATFS = 17, + FUSE_RELEASE = 18, + FUSE_FSYNC = 20, + FUSE_FLUSH = 25, FUSE_INIT = 26 }; @@ -132,10 +138,51 @@ struct fuse_setattr_in { struct fuse_attr attr; }; +struct fuse_open_in { + __u32 flags; +}; + +struct fuse_open_out { + __u64 fh; + __u32 open_flags; +}; + +struct fuse_release_in { + __u64 fh; + __u32 flags; +}; + +struct fuse_flush_in { + __u64 fh; + __u32 flush_flags; +}; + +struct fuse_read_in { + __u64 fh; + __u64 offset; + __u32 size; +}; + +struct fuse_write_in { + __u64 fh; + __u64 offset; + __u32 size; + __u32 write_flags; +}; + +struct fuse_write_out { + __u32 size; +}; + struct fuse_statfs_out { struct fuse_kstatfs st; }; +struct fuse_fsync_in { + __u64 fh; + __u32 fsync_flags; +}; + struct fuse_init_in_out { __u32 major; __u32 minor; -- cgit v1.2.3 From 92a8780e1136c5ca0c7ed940000d399943d1576e Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 9 Sep 2005 13:10:31 -0700 Subject: [PATCH] FUSE - extended attribute operations This patch adds the extended attribute operations to FUSE. The following operations are added: o getxattr o setxattr o listxattr o removexattr Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fuse.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 61f34636ffbc..bf564edf9905 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -80,6 +80,10 @@ enum fuse_opcode { FUSE_STATFS = 17, FUSE_RELEASE = 18, FUSE_FSYNC = 20, + FUSE_SETXATTR = 21, + FUSE_GETXATTR = 22, + FUSE_LISTXATTR = 23, + FUSE_REMOVEXATTR = 24, FUSE_FLUSH = 25, FUSE_INIT = 26 }; @@ -89,6 +93,7 @@ enum fuse_opcode { #define FUSE_NAME_MAX 1024 #define FUSE_SYMLINK_MAX 4096 +#define FUSE_XATTR_SIZE_MAX 4096 struct fuse_entry_out { __u64 nodeid; /* Inode ID */ @@ -183,6 +188,19 @@ struct fuse_fsync_in { __u32 fsync_flags; }; +struct fuse_setxattr_in { + __u32 size; + __u32 flags; +}; + +struct fuse_getxattr_in { + __u32 size; +}; + +struct fuse_getxattr_out { + __u32 size; +}; + struct fuse_init_in_out { __u32 major; __u32 minor; -- cgit v1.2.3 From 06663267b4b1e85ece73236ea720355668d4f736 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 9 Sep 2005 13:10:32 -0700 Subject: [PATCH] FUSE: add padding Add padding to structures to make sizes the same on 32bit and 64bit archs. Initial testing and test machine generously provided by Franco Broi. Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fuse.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h index bf564edf9905..e9b814e16c58 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -25,6 +25,9 @@ /** The minor number of the fuse character device */ #define FUSE_MINOR 229 +/* Make sure all structures are padded to 64bit boundary, so 32bit + userspace works under 64bit kernels */ + struct fuse_attr { __u64 ino; __u64 size; @@ -128,6 +131,7 @@ struct fuse_mknod_in { struct fuse_mkdir_in { __u32 mode; + __u32 padding; }; struct fuse_rename_in { @@ -140,32 +144,38 @@ struct fuse_link_in { struct fuse_setattr_in { __u32 valid; + __u32 padding; struct fuse_attr attr; }; struct fuse_open_in { __u32 flags; + __u32 padding; }; struct fuse_open_out { __u64 fh; __u32 open_flags; + __u32 padding; }; struct fuse_release_in { __u64 fh; __u32 flags; + __u32 padding; }; struct fuse_flush_in { __u64 fh; __u32 flush_flags; + __u32 padding; }; struct fuse_read_in { __u64 fh; __u64 offset; __u32 size; + __u32 padding; }; struct fuse_write_in { @@ -177,6 +187,7 @@ struct fuse_write_in { struct fuse_write_out { __u32 size; + __u32 padding; }; struct fuse_statfs_out { @@ -186,6 +197,7 @@ struct fuse_statfs_out { struct fuse_fsync_in { __u64 fh; __u32 fsync_flags; + __u32 padding; }; struct fuse_setxattr_in { @@ -195,10 +207,12 @@ struct fuse_setxattr_in { struct fuse_getxattr_in { __u32 size; + __u32 padding; }; struct fuse_getxattr_out { __u32 size; + __u32 padding; }; struct fuse_init_in_out { @@ -214,6 +228,7 @@ struct fuse_in_header { __u32 uid; __u32 gid; __u32 pid; + __u32 padding; }; struct fuse_out_header { -- cgit v1.2.3 From 04730fef1f9c7277e5c730b193e681ac095b0507 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 9 Sep 2005 13:10:36 -0700 Subject: [PATCH] fuse: transfer readdir data through device This patch removes a long lasting "hack" in FUSE, which used a separate channel (a file descriptor refering to a disk-file) to transfer directory contents from userspace to the kernel. The patch adds three new operations (OPENDIR, READDIR, RELEASEDIR), which have semantics and implementation exactly maching the respective file operations (OPEN, READ, RELEASE). This simplifies the directory reading code. Also disk space is not necessary, which can be important in embedded systems. Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fuse.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h index e9b814e16c58..cdfaa51b9018 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -70,7 +70,6 @@ enum fuse_opcode { FUSE_SETATTR = 4, FUSE_READLINK = 5, FUSE_SYMLINK = 6, - FUSE_GETDIR = 7, FUSE_MKNOD = 8, FUSE_MKDIR = 9, FUSE_UNLINK = 10, @@ -88,7 +87,10 @@ enum fuse_opcode { FUSE_LISTXATTR = 23, FUSE_REMOVEXATTR = 24, FUSE_FLUSH = 25, - FUSE_INIT = 26 + FUSE_INIT = 26, + FUSE_OPENDIR = 27, + FUSE_READDIR = 28, + FUSE_RELEASEDIR = 29 }; /* Conservative buffer size for the client */ @@ -120,10 +122,6 @@ struct fuse_attr_out { struct fuse_attr attr; }; -struct fuse_getdir_out { - __u32 fd; -}; - struct fuse_mknod_in { __u32 mode; __u32 rdev; -- cgit v1.2.3 From 45323fb76465a9576220c7427dbac7b1e7ad3caf Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 9 Sep 2005 13:10:37 -0700 Subject: [PATCH] fuse: more flexible caching Make data caching behavior selectable on a per-open basis instead of per-mount. Compatibility for the old mount options 'kernel_cache' and 'direct_io' is retained in the userspace library (version 2.4.0-pre1 or later). Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fuse.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h index cdfaa51b9018..c65124a213a1 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -14,7 +14,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 1 +#define FUSE_KERNEL_MINOR_VERSION 2 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -63,6 +63,15 @@ struct fuse_kstatfs { #define FATTR_MTIME (1 << 5) #define FATTR_CTIME (1 << 6) +/** + * Flags returned by the OPEN request + * + * FOPEN_DIRECT_IO: bypass page cache for this open file + * FOPEN_KEEP_CACHE: don't invalidate the data cache on open + */ +#define FOPEN_DIRECT_IO (1 << 0) +#define FOPEN_KEEP_CACHE (1 << 1) + enum fuse_opcode { FUSE_LOOKUP = 1, FUSE_FORGET = 2, /* no reply */ -- cgit v1.2.3 From 8254798199332966e2ab647380c990193af7e854 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 9 Sep 2005 13:10:38 -0700 Subject: [PATCH] FUSE: add fsync operation for directories This patch adds a new FSYNCDIR request, which is sent when fsync is called on directories. This operation is available in libfuse 2.3-pre1 or greater. Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fuse.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h index c65124a213a1..acbeb96a3353 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -99,7 +99,8 @@ enum fuse_opcode { FUSE_INIT = 26, FUSE_OPENDIR = 27, FUSE_READDIR = 28, - FUSE_RELEASEDIR = 29 + FUSE_RELEASEDIR = 29, + FUSE_FSYNCDIR = 30 }; /* Conservative buffer size for the client */ -- cgit v1.2.3 From 8d06afab73a75f40ae2864e6c296356bab1ab473 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 9 Sep 2005 13:10:40 -0700 Subject: [PATCH] timer initialization cleanup: DEFINE_TIMER Clean up timer initialization by introducing DEFINE_TIMER a'la DEFINE_SPINLOCK. Build and boot-tested on x86. A similar patch has been been in the -RT tree for some time. Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/timer.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/timer.h b/include/linux/timer.h index 221f81ac2002..3340f3bd135d 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -32,6 +32,10 @@ extern struct timer_base_s __init_timer_base; .magic = TIMER_MAGIC, \ } +#define DEFINE_TIMER(_name, _function, _expires, _data) \ + struct timer_list _name = \ + TIMER_INITIALIZER(_function, _expires, _data) + void fastcall init_timer(struct timer_list * timer); /*** -- cgit v1.2.3 From 9c8550ee25e26d14a8f0fe1b761a676e23fe3cf0 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 9 Sep 2005 15:43:46 -0700 Subject: Remove "must_check" attributes in PCI-land Don't just irritate all other kernel developers. Fix the users first, then you can re-introduce the must-check infrastructure to avoid new cases creeping in. Signed-off-by: Linus Torvalds --- include/linux/pci.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index e5e24e13a114..7349058ed778 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -380,16 +380,16 @@ static inline int pci_write_config_dword(struct pci_dev *dev, int where, u32 val return pci_bus_write_config_dword (dev->bus, dev->devfn, where, val); } -int __must_check pci_enable_device(struct pci_dev *dev); -int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask); +int pci_enable_device(struct pci_dev *dev); +int pci_enable_device_bars(struct pci_dev *dev, int mask); void pci_disable_device(struct pci_dev *dev); void pci_set_master(struct pci_dev *dev); #define HAVE_PCI_SET_MWI -int __must_check pci_set_mwi(struct pci_dev *dev); +int pci_set_mwi(struct pci_dev *dev); void pci_clear_mwi(struct pci_dev *dev); void pci_intx(struct pci_dev *dev, int enable); -int __must_check pci_set_dma_mask(struct pci_dev *dev, u64 mask); -int __must_check pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); +int pci_set_dma_mask(struct pci_dev *dev, u64 mask); +int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); int pci_assign_resource(struct pci_dev *dev, int i); void pci_restore_bars(struct pci_dev *dev); @@ -403,9 +403,9 @@ void pci_remove_rom(struct pci_dev *pdev); /* Power management related routines */ int pci_save_state(struct pci_dev *dev); int pci_restore_state(struct pci_dev *dev); -int __must_check pci_set_power_state(struct pci_dev *dev, pci_power_t state); -pci_power_t __must_check pci_choose_state(struct pci_dev *dev, pm_message_t state); -int __must_check pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); +int pci_set_power_state(struct pci_dev *dev, pci_power_t state); +pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); +int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ void pci_bus_assign_resources(struct pci_bus *bus); -- cgit v1.2.3 From 36fa30636fb84b209210299684e1be66d9e58217 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Sep 2005 16:23:45 -0700 Subject: [PATCH] md: all hot-add and hot-remove of md intent logging bitmaps Both file-bitmaps and superblock bitmaps are supported. If you add a bitmap file on the array device, you lose. This introduces a 'default_bitmap_offset' field in mddev, as the ioctl used for adding a superblock bitmap doesn't have room for giving an offset. Later, this value will be setable via sysfs. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/raid/md_k.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 8c14ba565a45..817062bf7352 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -278,6 +278,10 @@ struct mddev_s * start of bitmap. May be * negative, but not '0' */ + long default_bitmap_offset; /* this is the offset to use when + * hot-adding a bitmap. It should + * eventually be settable by sysfs. + */ struct list_head all_mddevs; }; @@ -314,6 +318,12 @@ struct mdk_personality_s int (*resize) (mddev_t *mddev, sector_t sectors); int (*reshape) (mddev_t *mddev, int raid_disks); int (*reconfig) (mddev_t *mddev, int layout, int chunk_size); + /* quiesce moves between quiescence states + * 0 - fully active + * 1 - no new requests allowed + * others - reserved + */ + void (*quiesce) (mddev_t *mddev, int state); }; -- cgit v1.2.3 From 8ddf9efe6708f3674f0ddfeb6425fd27bea109a2 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Sep 2005 16:23:45 -0700 Subject: [PATCH] md: support write-mostly device in raid1 This allows a device in a raid1 to be marked as "write mostly". Read requests will only be sent if there is no other option. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/raid/md_k.h | 3 +++ include/linux/raid/md_p.h | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 817062bf7352..7ef78e15ce04 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -181,6 +181,9 @@ struct mdk_rdev_s int faulty; /* if faulty do not issue IO requests */ int in_sync; /* device is a full member of the array */ + unsigned long flags; /* Should include faulty and in_sync here. */ +#define WriteMostly 4 /* Avoid reading if at all possible */ + int desc_nr; /* descriptor index in the superblock */ int raid_disk; /* role of device in array */ int saved_raid_disk; /* role that device used to have in the diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h index dc65cd435494..4f047f84fb1f 100644 --- a/include/linux/raid/md_p.h +++ b/include/linux/raid/md_p.h @@ -79,6 +79,11 @@ #define MD_DISK_SYNC 2 /* disk is in sync with the raid set */ #define MD_DISK_REMOVED 3 /* disk is in sync with the raid set */ +#define MD_DISK_WRITEMOSTLY 9 /* disk is "write-mostly" is RAID1 config. + * read requests will only be sent here in + * dire need + */ + typedef struct mdp_device_descriptor_s { __u32 number; /* 0 Device number in the entire set */ __u32 major; /* 1 Device major number */ @@ -193,7 +198,7 @@ struct mdp_superblock_1 { __u64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/ __u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */ - __u32 layout; /* only for raid5 currently */ + __u32 layout; /* only for raid5 and raid10 currently */ __u64 size; /* used size of component devices, in 512byte sectors */ __u32 chunksize; /* in 512byte sectors */ @@ -212,7 +217,9 @@ struct mdp_superblock_1 { __u32 dev_number; /* permanent identifier of this device - not role in raid */ __u32 cnt_corrected_read; /* number of read errors that were corrected by re-writing */ __u8 device_uuid[16]; /* user-space setable, ignored by kernel */ - __u8 pad2[64-56]; /* set to 0 when writing */ + __u8 devflags; /* per-device flags. Only one defined...*/ +#define WriteMostly1 1 /* mask for writemostly flag in above */ + __u8 pad2[64-57]; /* set to 0 when writing */ /* array state information - 64 bytes */ __u64 utime; /* 40 bits second, 24 btes microseconds */ -- cgit v1.2.3 From 4b6d287f627b5fb6a49f78f9e81649ff98c62bb7 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Sep 2005 16:23:47 -0700 Subject: [PATCH] md: add write-behind support for md/raid1 If a device is flagged 'WriteMostly' and the array has a bitmap, and the bitmap superblock indicates that write_behind is allowed, then write_behind is enabled for WriteMostly devices. Write requests will be acknowledges as complete to the caller (via b_end_io) when all non-WriteMostly devices have completed the write, but will not be cleared from the bitmap until all devices complete. This requires memory allocation to make a local copy of the data being written. If there is insufficient memory, then we fall-back on normal write semantics. Signed-Off-By: Paul Clements Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/raid/bitmap.h | 15 ++++++++++----- include/linux/raid/md_k.h | 3 +++ include/linux/raid/raid1.h | 13 +++++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index 4bf1659f8aa8..9de99198caf1 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h @@ -7,7 +7,7 @@ #define BITMAP_H 1 #define BITMAP_MAJOR 3 -#define BITMAP_MINOR 38 +#define BITMAP_MINOR 39 /* * in-memory bitmap: @@ -147,8 +147,9 @@ typedef struct bitmap_super_s { __u32 state; /* 48 bitmap state information */ __u32 chunksize; /* 52 the bitmap chunk size in bytes */ __u32 daemon_sleep; /* 56 seconds between disk flushes */ + __u32 write_behind; /* 60 number of outstanding write-behind writes */ - __u8 pad[256 - 60]; /* set to zero */ + __u8 pad[256 - 64]; /* set to zero */ } bitmap_super_t; /* notes: @@ -226,6 +227,9 @@ struct bitmap { unsigned long flags; + unsigned long max_write_behind; /* write-behind mode */ + atomic_t behind_writes; + /* * the bitmap daemon - periodically wakes up and sweeps the bitmap * file, cleaning up bits and flushing out pages to disk as necessary @@ -260,9 +264,10 @@ int bitmap_setallbits(struct bitmap *bitmap); void bitmap_write_all(struct bitmap *bitmap); /* these are exported */ -int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors); -void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, - int success); +int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, + unsigned long sectors, int behind); +void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, + unsigned long sectors, int success, int behind); int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded); void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted); void bitmap_close_sync(struct bitmap *bitmap); diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 7ef78e15ce04..2514e5fcda7f 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -275,6 +275,9 @@ struct mddev_s atomic_t writes_pending; request_queue_t *queue; /* for plugging ... */ + atomic_t write_behind; /* outstanding async IO */ + unsigned int max_write_behind; /* 0 = sync */ + struct bitmap *bitmap; /* the bitmap for the device */ struct file *bitmap_file; /* the bitmap file */ long bitmap_offset; /* offset from superblock of diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h index 9d93cf12e890..60e19b667548 100644 --- a/include/linux/raid/raid1.h +++ b/include/linux/raid/raid1.h @@ -80,6 +80,9 @@ struct r1bio_s { atomic_t remaining; /* 'have we finished' count, * used from IRQ handlers */ + atomic_t behind_remaining; /* number of write-behind ios remaining + * in this BehindIO request + */ sector_t sector; int sectors; unsigned long state; @@ -107,4 +110,14 @@ struct r1bio_s { #define R1BIO_Uptodate 0 #define R1BIO_IsSync 1 #define R1BIO_Degraded 2 +#define R1BIO_BehindIO 3 +/* For write-behind requests, we call bi_end_io when + * the last non-write-behind device completes, providing + * any write was successful. Otherwise we call when + * any write-behind write succeeds, otherwise we call + * with failure when last write completes (and all failed). + * Record that bi_end_io was called with this flag... + */ +#define R1BIO_Returned 4 + #endif -- cgit v1.2.3 From 15945fee6f09bff1f86b1a735b5888dc59cf38e3 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Sep 2005 16:23:47 -0700 Subject: [PATCH] md: support md/linear array with components greater than 2 terabytes. linear currently uses division by the size of the smallest componenet device to find which device a request goes to. If that smallest device is larger than 2 terabytes, then the division will not work on some systems. So we introduce a pre-shift, and take care not to make the hash table too large, much like the code in raid0. Also get rid of conf->nr_zones, which is not needed. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/raid/linear.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/raid/linear.h b/include/linux/raid/linear.h index e04c4fe45b53..7eaf290e10e7 100644 --- a/include/linux/raid/linear.h +++ b/include/linux/raid/linear.h @@ -14,8 +14,8 @@ typedef struct dev_info dev_info_t; struct linear_private_data { dev_info_t **hash_table; - dev_info_t *smallest; - int nr_zones; + sector_t hash_spacing; + int preshift; /* shift before dividing by hash_spacing */ dev_info_t disks[0]; }; -- cgit v1.2.3 From 71c0805cb48462c99fbe0e5fcc6c12d7b9929c09 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Sep 2005 16:23:51 -0700 Subject: [PATCH] md: allow md to load a superblock with feature-bit '1' set As this is used to flag an internal bitmap. Also, introduce symbolic names for feature bits. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/raid/md_p.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h index 4f047f84fb1f..c100fa5d4bfa 100644 --- a/include/linux/raid/md_p.h +++ b/include/linux/raid/md_p.h @@ -238,5 +238,10 @@ struct mdp_superblock_1 { __u16 dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */ }; +/* feature_map bits */ +#define MD_FEATURE_BITMAP_OFFSET 1 + +#define MD_FEATURE_ALL 1 + #endif -- cgit v1.2.3 From 773f7834425e83144c95fbbc553ced3c2b74b828 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Sep 2005 16:23:53 -0700 Subject: [PATCH] md: remove old cruft from md_k.h header file These inlines haven't been used for ages, they should go. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/raid/md_k.h | 64 ----------------------------------------------- 1 file changed, 64 deletions(-) (limited to 'include/linux') diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 2514e5fcda7f..8042f55dd323 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -85,70 +85,6 @@ typedef struct mdk_rdev_s mdk_rdev_t; #define MAX_CHUNK_SIZE (4096*1024) -/* - * default readahead - */ - -static inline int disk_faulty(mdp_disk_t * d) -{ - return d->state & (1 << MD_DISK_FAULTY); -} - -static inline int disk_active(mdp_disk_t * d) -{ - return d->state & (1 << MD_DISK_ACTIVE); -} - -static inline int disk_sync(mdp_disk_t * d) -{ - return d->state & (1 << MD_DISK_SYNC); -} - -static inline int disk_spare(mdp_disk_t * d) -{ - return !disk_sync(d) && !disk_active(d) && !disk_faulty(d); -} - -static inline int disk_removed(mdp_disk_t * d) -{ - return d->state & (1 << MD_DISK_REMOVED); -} - -static inline void mark_disk_faulty(mdp_disk_t * d) -{ - d->state |= (1 << MD_DISK_FAULTY); -} - -static inline void mark_disk_active(mdp_disk_t * d) -{ - d->state |= (1 << MD_DISK_ACTIVE); -} - -static inline void mark_disk_sync(mdp_disk_t * d) -{ - d->state |= (1 << MD_DISK_SYNC); -} - -static inline void mark_disk_spare(mdp_disk_t * d) -{ - d->state = 0; -} - -static inline void mark_disk_removed(mdp_disk_t * d) -{ - d->state = (1 << MD_DISK_FAULTY) | (1 << MD_DISK_REMOVED); -} - -static inline void mark_disk_inactive(mdp_disk_t * d) -{ - d->state &= ~(1 << MD_DISK_ACTIVE); -} - -static inline void mark_disk_nonsync(mdp_disk_t * d) -{ - d->state &= ~(1 << MD_DISK_SYNC); -} - /* * MD's 'extended' device */ -- cgit v1.2.3 From 0002b2718dd04da67c21f8a7830de8d95a9b0345 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Sep 2005 16:23:53 -0700 Subject: [PATCH] md: limit size of sb read/written to appropriate amount version-1 superblocks are not (normally) 4K long, and can be of variable size. Writing the full 4K can cause corruption (but only in non-default configurations). With this patch the super-block-flavour can choose a size to read, and set a size to write based on what it finds. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/raid/md_k.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 8042f55dd323..ebce949b1443 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -102,6 +102,7 @@ struct mdk_rdev_s int sb_loaded; sector_t data_offset; /* start of data in array */ sector_t sb_offset; + int sb_size; /* bytes in the superblock */ int preferred_minor; /* autorun support */ /* A device can be in one of three states based on two flags: -- cgit v1.2.3 From 72626685dc66d455742a7f215a0535c551628b9e Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Sep 2005 16:23:54 -0700 Subject: [PATCH] md: add write-intent-bitmap support to raid5 Most awkward part of this is delaying write requests until bitmap updates have been flushed. To achieve this, we have a sequence number (seq_flush) which is incremented each time the raid5 is unplugged. If the raid thread notices that this has changed, it flushes bitmap changes, and assigned the value of seq_flush to seq_write. When a write request arrives, it is given the number from seq_write, and that write request may not complete until seq_flush is larger than the saved seq number. We have a new queue for storing stripes which are waiting for a bitmap flush and an extra flag for stripes to record if the write was 'degraded' and so should not clear the a bit in the bitmap. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/raid/raid5.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h index d63ddcb4afad..176fc653c284 100644 --- a/include/linux/raid/raid5.h +++ b/include/linux/raid/raid5.h @@ -134,6 +134,7 @@ struct stripe_head { unsigned long state; /* state flags */ atomic_t count; /* nr of active thread/requests */ spinlock_t lock; + int bm_seq; /* sequence number for bitmap flushes */ struct r5dev { struct bio req; struct bio_vec vec; @@ -165,12 +166,13 @@ struct stripe_head { /* * Stripe state */ -#define STRIPE_ERROR 1 #define STRIPE_HANDLE 2 #define STRIPE_SYNCING 3 #define STRIPE_INSYNC 4 #define STRIPE_PREREAD_ACTIVE 5 #define STRIPE_DELAYED 6 +#define STRIPE_DEGRADED 7 +#define STRIPE_BIT_DELAY 8 /* * Plugging: @@ -210,10 +212,20 @@ struct raid5_private_data { struct list_head handle_list; /* stripes needing handling */ struct list_head delayed_list; /* stripes that have plugged requests */ + struct list_head bitmap_list; /* stripes delaying awaiting bitmap update */ atomic_t preread_active_stripes; /* stripes with scheduled io */ char cache_name[20]; kmem_cache_t *slab_cache; /* for allocating stripes */ + + int seq_flush, seq_write; + int quiesce; + + int fullsync; /* set to 1 if a full sync is needed, + * (fresh device added). + * Cleared when a sync completes. + */ + /* * Free stripes pool */ -- cgit v1.2.3 From 9928890c1f94da58bf753ede937b7324f6832866 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Sat, 10 Sep 2005 11:26:34 +0900 Subject: [IPV6]: rearrange constants for new advanced API to solve conflicts. 64, 65 are already used in ip6_tables. Pointed out by Patrick McHardy . Signed-off-by: YOSHIFUJI Hideaki --- include/linux/in6.h | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'include/linux') diff --git a/include/linux/in6.h b/include/linux/in6.h index bd32b79d6295..50cdc3ad61a7 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -198,27 +198,29 @@ struct in6_flowlabel_req * MCAST_MSFILTER 48 */ -/* RFC3542 advanced socket options (50-67) */ -#define IPV6_RECVPKTINFO 50 -#define IPV6_PKTINFO 51 -#if 0 -#define IPV6_RECVPATHMTU 52 -#define IPV6_PATHMTU 53 -#define IPV6_DONTFRAG 54 -#define IPV6_USE_MIN_MTU 55 -#endif -#define IPV6_RECVHOPOPTS 56 -#define IPV6_HOPOPTS 57 -#if 0 -#define IPV6_RECVRTHDRDSTOPTS 58 /* Unused, see net/ipv6/datagram.c */ +/* + * Advanced API (RFC3542) (1) + * + * Note: IPV6_RECVRTHDRDSTOPTS does not exist. see net/ipv6/datagram.c. + */ + +#define IPV6_RECVPKTINFO 49 +#define IPV6_PKTINFO 50 +#define IPV6_RECVHOPLIMIT 51 +#define IPV6_HOPLIMIT 52 +#define IPV6_RECVHOPOPTS 53 +#define IPV6_HOPOPTS 54 +#define IPV6_RTHDRDSTOPTS 55 +#define IPV6_RECVRTHDR 56 +#define IPV6_RTHDR 57 +#define IPV6_RECVDSTOPTS 58 +#define IPV6_DSTOPTS 59 +#if 0 /* not yet */ +#define IPV6_RECVPATHMTU 60 +#define IPV6_PATHMTU 61 +#define IPV6_DONTFRAG 62 +#define IPV6_USE_MIN_MTU 63 #endif -#define IPV6_RTHDRDSTOPTS 59 -#define IPV6_RECVRTHDR 60 -#define IPV6_RTHDR 61 -#define IPV6_RECVDSTOPTS 62 -#define IPV6_DSTOPTS 63 -#define IPV6_RECVHOPLIMIT 64 -#define IPV6_HOPLIMIT 65 #define IPV6_RECVTCLASS 66 #define IPV6_TCLASS 67 -- cgit v1.2.3 From dd27466df9924706ae34639ce3f4f837875d45c1 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Sat, 10 Sep 2005 11:32:45 +0900 Subject: [IPV6]: Note values allocated for ip6_tables. To avoid future conflicts, add a note values allocated for ip6_tables. Signed-off-by: YOSHIFUJI Hideaki --- include/linux/in6.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include/linux') diff --git a/include/linux/in6.h b/include/linux/in6.h index 50cdc3ad61a7..304aaedea305 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -221,6 +221,20 @@ struct in6_flowlabel_req #define IPV6_DONTFRAG 62 #define IPV6_USE_MIN_MTU 63 #endif + +/* + * Netfilter + * + * Following socket options are used in ip6_tables; + * see include/linux/netfilter_ipv6/ip6_tables.h. + * + * IP6T_SO_SET_REPLACE / IP6T_SO_GET_INFO 64 + * IP6T_SO_SET_ADD_COUNTERS / IP6T_SO_GET_ENTRIES 65 + */ + +/* + * Advanced API (RFC3542) (2) + */ #define IPV6_RECVTCLASS 66 #define IPV6_TCLASS 67 -- cgit v1.2.3 From e6df439b89dbf9eb977c2dc6f7b0644be3704df4 Mon Sep 17 00:00:00 2001 From: Brian Haley Date: Sat, 10 Sep 2005 00:15:06 -0700 Subject: [IPV6]: Bring Type 0 routing header in-line with rfc3542. Signed-off-by: Brian Haley Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/linux/ipv6.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 6c5f7b39a4b0..bb6f88e14061 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -68,7 +68,7 @@ struct ipv6_opt_hdr { struct rt0_hdr { struct ipv6_rt_hdr rt_hdr; - __u32 bitmap; /* strict/loose bit map */ + __u32 reserved; struct in6_addr addr[0]; #define rt0_type rt_hdr.type -- cgit v1.2.3 From fb1c8f93d869b34cacb8b8932e2b83d96a19d720 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 10 Sep 2005 00:25:56 -0700 Subject: [PATCH] spinlock consolidation This patch (written by me and also containing many suggestions of Arjan van de Ven) does a major cleanup of the spinlock code. It does the following things: - consolidates and enhances the spinlock/rwlock debugging code - simplifies the asm/spinlock.h files - encapsulates the raw spinlock type and moves generic spinlock features (such as ->break_lock) into the generic code. - cleans up the spinlock code hierarchy to get rid of the spaghetti. Most notably there's now only a single variant of the debugging code, located in lib/spinlock_debug.c. (previously we had one SMP debugging variant per architecture, plus a separate generic one for UP builds) Also, i've enhanced the rwlock debugging facility, it will now track write-owners. There is new spinlock-owner/CPU-tracking on SMP builds too. All locks have lockup detection now, which will work for both soft and hard spin/rwlock lockups. The arch-level include files now only contain the minimally necessary subset of the spinlock code - all the rest that can be generalized now lives in the generic headers: include/asm-i386/spinlock_types.h | 16 include/asm-x86_64/spinlock_types.h | 16 I have also split up the various spinlock variants into separate files, making it easier to see which does what. The new layout is: SMP | UP ----------------------------|----------------------------------- asm/spinlock_types_smp.h | linux/spinlock_types_up.h linux/spinlock_types.h | linux/spinlock_types.h asm/spinlock_smp.h | linux/spinlock_up.h linux/spinlock_api_smp.h | linux/spinlock_api_up.h linux/spinlock.h | linux/spinlock.h /* * here's the role of the various spinlock/rwlock related include files: * * on SMP builds: * * asm/spinlock_types.h: contains the raw_spinlock_t/raw_rwlock_t and the * initializers * * linux/spinlock_types.h: * defines the generic type and initializers * * asm/spinlock.h: contains the __raw_spin_*()/etc. lowlevel * implementations, mostly inline assembly code * * (also included on UP-debug builds:) * * linux/spinlock_api_smp.h: * contains the prototypes for the _spin_*() APIs. * * linux/spinlock.h: builds the final spin_*() APIs. * * on UP builds: * * linux/spinlock_type_up.h: * contains the generic, simplified UP spinlock type. * (which is an empty structure on non-debug builds) * * linux/spinlock_types.h: * defines the generic type and initializers * * linux/spinlock_up.h: * contains the __raw_spin_*()/etc. version of UP * builds. (which are NOPs on non-debug, non-preempt * builds) * * (included on UP-non-debug builds:) * * linux/spinlock_api_up.h: * builds the _spin_*() APIs. * * linux/spinlock.h: builds the final spin_*() APIs. */ All SMP and UP architectures are converted by this patch. arm, i386, ia64, ppc, ppc64, s390/s390x, x64 was build-tested via crosscompilers. m32r, mips, sh, sparc, have not been tested yet, but should be mostly fine. From: Grant Grundler Booted and lightly tested on a500-44 (64-bit, SMP kernel, dual CPU). Builds 32-bit SMP kernel (not booted or tested). I did not try to build non-SMP kernels. That should be trivial to fix up later if necessary. I converted bit ops atomic_hash lock to raw_spinlock_t. Doing so avoids some ugly nesting of linux/*.h and asm/*.h files. Those particular locks are well tested and contained entirely inside arch specific code. I do NOT expect any new issues to arise with them. If someone does ever need to use debug/metrics with them, then they will need to unravel this hairball between spinlocks, atomic ops, and bit ops that exist only because parisc has exactly one atomic instruction: LDCW (load and clear word). From: "Luck, Tony" ia64 fix Signed-off-by: Ingo Molnar Signed-off-by: Arjan van de Ven Signed-off-by: Grant Grundler Cc: Matthew Wilcox Signed-off-by: Hirokazu Takata Signed-off-by: Mikael Pettersson Signed-off-by: Benoit Boissinot Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bit_spinlock.h | 77 +++++ include/linux/jbd.h | 1 + include/linux/spinlock.h | 627 ++++++++------------------------------ include/linux/spinlock_api_smp.h | 57 ++++ include/linux/spinlock_api_up.h | 80 +++++ include/linux/spinlock_types.h | 67 ++++ include/linux/spinlock_types_up.h | 51 ++++ include/linux/spinlock_up.h | 74 +++++ 8 files changed, 532 insertions(+), 502 deletions(-) create mode 100644 include/linux/bit_spinlock.h create mode 100644 include/linux/spinlock_api_smp.h create mode 100644 include/linux/spinlock_api_up.h create mode 100644 include/linux/spinlock_types.h create mode 100644 include/linux/spinlock_types_up.h create mode 100644 include/linux/spinlock_up.h (limited to 'include/linux') diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h new file mode 100644 index 000000000000..6b20af0bbb79 --- /dev/null +++ b/include/linux/bit_spinlock.h @@ -0,0 +1,77 @@ +#ifndef __LINUX_BIT_SPINLOCK_H +#define __LINUX_BIT_SPINLOCK_H + +/* + * bit-based spin_lock() + * + * Don't use this unless you really need to: spin_lock() and spin_unlock() + * are significantly faster. + */ +static inline void bit_spin_lock(int bitnum, unsigned long *addr) +{ + /* + * Assuming the lock is uncontended, this never enters + * the body of the outer loop. If it is contended, then + * within the inner loop a non-atomic test is used to + * busywait with less bus contention for a good time to + * attempt to acquire the lock bit. + */ + preempt_disable(); +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) + while (test_and_set_bit(bitnum, addr)) { + while (test_bit(bitnum, addr)) { + preempt_enable(); + cpu_relax(); + preempt_disable(); + } + } +#endif + __acquire(bitlock); +} + +/* + * Return true if it was acquired + */ +static inline int bit_spin_trylock(int bitnum, unsigned long *addr) +{ + preempt_disable(); +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) + if (test_and_set_bit(bitnum, addr)) { + preempt_enable(); + return 0; + } +#endif + __acquire(bitlock); + return 1; +} + +/* + * bit-based spin_unlock() + */ +static inline void bit_spin_unlock(int bitnum, unsigned long *addr) +{ +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) + BUG_ON(!test_bit(bitnum, addr)); + smp_mb__before_clear_bit(); + clear_bit(bitnum, addr); +#endif + preempt_enable(); + __release(bitlock); +} + +/* + * Return true if the lock is held. + */ +static inline int bit_spin_is_locked(int bitnum, unsigned long *addr) +{ +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) + return test_bit(bitnum, addr); +#elif defined CONFIG_PREEMPT + return preempt_count(); +#else + return 1; +#endif +} + +#endif /* __LINUX_BIT_SPINLOCK_H */ + diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 84321a4cac93..de097269bd7f 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #endif diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index d6ba068719b6..cdc99a27840d 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -2,7 +2,48 @@ #define __LINUX_SPINLOCK_H /* - * include/linux/spinlock.h - generic locking declarations + * include/linux/spinlock.h - generic spinlock/rwlock declarations + * + * here's the role of the various spinlock/rwlock related include files: + * + * on SMP builds: + * + * asm/spinlock_types.h: contains the raw_spinlock_t/raw_rwlock_t and the + * initializers + * + * linux/spinlock_types.h: + * defines the generic type and initializers + * + * asm/spinlock.h: contains the __raw_spin_*()/etc. lowlevel + * implementations, mostly inline assembly code + * + * (also included on UP-debug builds:) + * + * linux/spinlock_api_smp.h: + * contains the prototypes for the _spin_*() APIs. + * + * linux/spinlock.h: builds the final spin_*() APIs. + * + * on UP builds: + * + * linux/spinlock_type_up.h: + * contains the generic, simplified UP spinlock type. + * (which is an empty structure on non-debug builds) + * + * linux/spinlock_types.h: + * defines the generic type and initializers + * + * linux/spinlock_up.h: + * contains the __raw_spin_*()/etc. version of UP + * builds. (which are NOPs on non-debug, non-preempt + * builds) + * + * (included on UP-non-debug builds:) + * + * linux/spinlock_api_up.h: + * builds the _spin_*() APIs. + * + * linux/spinlock.h: builds the final spin_*() APIs. */ #include @@ -13,7 +54,6 @@ #include #include -#include /* for cpu relax */ #include /* @@ -35,423 +75,84 @@ #define __lockfunc fastcall __attribute__((section(".spinlock.text"))) /* - * If CONFIG_SMP is set, pull in the _raw_* definitions + * Pull the raw_spinlock_t and raw_rwlock_t definitions: */ -#ifdef CONFIG_SMP - -#define assert_spin_locked(x) BUG_ON(!spin_is_locked(x)) -#include - -int __lockfunc _spin_trylock(spinlock_t *lock); -int __lockfunc _read_trylock(rwlock_t *lock); -int __lockfunc _write_trylock(rwlock_t *lock); - -void __lockfunc _spin_lock(spinlock_t *lock) __acquires(spinlock_t); -void __lockfunc _read_lock(rwlock_t *lock) __acquires(rwlock_t); -void __lockfunc _write_lock(rwlock_t *lock) __acquires(rwlock_t); - -void __lockfunc _spin_unlock(spinlock_t *lock) __releases(spinlock_t); -void __lockfunc _read_unlock(rwlock_t *lock) __releases(rwlock_t); -void __lockfunc _write_unlock(rwlock_t *lock) __releases(rwlock_t); - -unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock) __acquires(spinlock_t); -unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) __acquires(rwlock_t); -unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) __acquires(rwlock_t); - -void __lockfunc _spin_lock_irq(spinlock_t *lock) __acquires(spinlock_t); -void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(spinlock_t); -void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(rwlock_t); -void __lockfunc _read_lock_bh(rwlock_t *lock) __acquires(rwlock_t); -void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(rwlock_t); -void __lockfunc _write_lock_bh(rwlock_t *lock) __acquires(rwlock_t); - -void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) __releases(spinlock_t); -void __lockfunc _spin_unlock_irq(spinlock_t *lock) __releases(spinlock_t); -void __lockfunc _spin_unlock_bh(spinlock_t *lock) __releases(spinlock_t); -void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) __releases(rwlock_t); -void __lockfunc _read_unlock_irq(rwlock_t *lock) __releases(rwlock_t); -void __lockfunc _read_unlock_bh(rwlock_t *lock) __releases(rwlock_t); -void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) __releases(rwlock_t); -void __lockfunc _write_unlock_irq(rwlock_t *lock) __releases(rwlock_t); -void __lockfunc _write_unlock_bh(rwlock_t *lock) __releases(rwlock_t); - -int __lockfunc _spin_trylock_bh(spinlock_t *lock); -int __lockfunc generic_raw_read_trylock(rwlock_t *lock); -int in_lock_functions(unsigned long addr); - -#else +#include -#define in_lock_functions(ADDR) 0 +extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock); -#if !defined(CONFIG_PREEMPT) && !defined(CONFIG_DEBUG_SPINLOCK) -# define _atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic) -# define ATOMIC_DEC_AND_LOCK -#endif - -#ifdef CONFIG_DEBUG_SPINLOCK - -#define SPINLOCK_MAGIC 0x1D244B3C -typedef struct { - unsigned long magic; - volatile unsigned long lock; - volatile unsigned int babble; - const char *module; - char *owner; - int oline; -} spinlock_t; -#define SPIN_LOCK_UNLOCKED (spinlock_t) { SPINLOCK_MAGIC, 0, 10, __FILE__ , NULL, 0} - -#define spin_lock_init(x) \ - do { \ - (x)->magic = SPINLOCK_MAGIC; \ - (x)->lock = 0; \ - (x)->babble = 5; \ - (x)->module = __FILE__; \ - (x)->owner = NULL; \ - (x)->oline = 0; \ - } while (0) - -#define CHECK_LOCK(x) \ - do { \ - if ((x)->magic != SPINLOCK_MAGIC) { \ - printk(KERN_ERR "%s:%d: spin_is_locked on uninitialized spinlock %p.\n", \ - __FILE__, __LINE__, (x)); \ - } \ - } while(0) - -#define _raw_spin_lock(x) \ - do { \ - CHECK_LOCK(x); \ - if ((x)->lock&&(x)->babble) { \ - (x)->babble--; \ - printk("%s:%d: spin_lock(%s:%p) already locked by %s/%d\n", \ - __FILE__,__LINE__, (x)->module, \ - (x), (x)->owner, (x)->oline); \ - } \ - (x)->lock = 1; \ - (x)->owner = __FILE__; \ - (x)->oline = __LINE__; \ - } while (0) - -/* without debugging, spin_is_locked on UP always says - * FALSE. --> printk if already locked. */ -#define spin_is_locked(x) \ - ({ \ - CHECK_LOCK(x); \ - if ((x)->lock&&(x)->babble) { \ - (x)->babble--; \ - printk("%s:%d: spin_is_locked(%s:%p) already locked by %s/%d\n", \ - __FILE__,__LINE__, (x)->module, \ - (x), (x)->owner, (x)->oline); \ - } \ - 0; \ - }) - -/* with debugging, assert_spin_locked() on UP does check - * the lock value properly */ -#define assert_spin_locked(x) \ - ({ \ - CHECK_LOCK(x); \ - BUG_ON(!(x)->lock); \ - }) - -/* without debugging, spin_trylock on UP always says - * TRUE. --> printk if already locked. */ -#define _raw_spin_trylock(x) \ - ({ \ - CHECK_LOCK(x); \ - if ((x)->lock&&(x)->babble) { \ - (x)->babble--; \ - printk("%s:%d: spin_trylock(%s:%p) already locked by %s/%d\n", \ - __FILE__,__LINE__, (x)->module, \ - (x), (x)->owner, (x)->oline); \ - } \ - (x)->lock = 1; \ - (x)->owner = __FILE__; \ - (x)->oline = __LINE__; \ - 1; \ - }) - -#define spin_unlock_wait(x) \ - do { \ - CHECK_LOCK(x); \ - if ((x)->lock&&(x)->babble) { \ - (x)->babble--; \ - printk("%s:%d: spin_unlock_wait(%s:%p) owned by %s/%d\n", \ - __FILE__,__LINE__, (x)->module, (x), \ - (x)->owner, (x)->oline); \ - }\ - } while (0) - -#define _raw_spin_unlock(x) \ - do { \ - CHECK_LOCK(x); \ - if (!(x)->lock&&(x)->babble) { \ - (x)->babble--; \ - printk("%s:%d: spin_unlock(%s:%p) not locked\n", \ - __FILE__,__LINE__, (x)->module, (x));\ - } \ - (x)->lock = 0; \ - } while (0) -#else /* - * gcc versions before ~2.95 have a nasty bug with empty initializers. + * Pull the __raw*() functions/declarations (UP-nondebug doesnt need them): */ -#if (__GNUC__ > 2) - typedef struct { } spinlock_t; - #define SPIN_LOCK_UNLOCKED (spinlock_t) { } +#if defined(CONFIG_SMP) +# include #else - typedef struct { int gcc_is_buggy; } spinlock_t; - #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } +# include #endif +#define spin_lock_init(lock) do { *(lock) = SPIN_LOCK_UNLOCKED; } while (0) +#define rwlock_init(lock) do { *(lock) = RW_LOCK_UNLOCKED; } while (0) + +#define spin_is_locked(lock) __raw_spin_is_locked(&(lock)->raw_lock) + +/** + * spin_unlock_wait - wait until the spinlock gets unlocked + * @lock: the spinlock in question. + */ +#define spin_unlock_wait(lock) __raw_spin_unlock_wait(&(lock)->raw_lock) + /* - * If CONFIG_SMP is unset, declare the _raw_* definitions as nops + * Pull the _spin_*()/_read_*()/_write_*() functions/declarations: */ -#define spin_lock_init(lock) do { (void)(lock); } while(0) -#define _raw_spin_lock(lock) do { (void)(lock); } while(0) -#define spin_is_locked(lock) ((void)(lock), 0) -#define assert_spin_locked(lock) do { (void)(lock); } while(0) -#define _raw_spin_trylock(lock) (((void)(lock), 1)) -#define spin_unlock_wait(lock) (void)(lock) -#define _raw_spin_unlock(lock) do { (void)(lock); } while(0) -#endif /* CONFIG_DEBUG_SPINLOCK */ - -/* RW spinlocks: No debug version */ - -#if (__GNUC__ > 2) - typedef struct { } rwlock_t; - #define RW_LOCK_UNLOCKED (rwlock_t) { } +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) +# include #else - typedef struct { int gcc_is_buggy; } rwlock_t; - #define RW_LOCK_UNLOCKED (rwlock_t) { 0 } +# include #endif -#define rwlock_init(lock) do { (void)(lock); } while(0) -#define _raw_read_lock(lock) do { (void)(lock); } while(0) -#define _raw_read_unlock(lock) do { (void)(lock); } while(0) -#define _raw_write_lock(lock) do { (void)(lock); } while(0) -#define _raw_write_unlock(lock) do { (void)(lock); } while(0) -#define read_can_lock(lock) (((void)(lock), 1)) -#define write_can_lock(lock) (((void)(lock), 1)) -#define _raw_read_trylock(lock) ({ (void)(lock); (1); }) -#define _raw_write_trylock(lock) ({ (void)(lock); (1); }) - -#define _spin_trylock(lock) ({preempt_disable(); _raw_spin_trylock(lock) ? \ - 1 : ({preempt_enable(); 0;});}) - -#define _read_trylock(lock) ({preempt_disable();_raw_read_trylock(lock) ? \ - 1 : ({preempt_enable(); 0;});}) - -#define _write_trylock(lock) ({preempt_disable(); _raw_write_trylock(lock) ? \ - 1 : ({preempt_enable(); 0;});}) - -#define _spin_trylock_bh(lock) ({preempt_disable(); local_bh_disable(); \ - _raw_spin_trylock(lock) ? \ - 1 : ({preempt_enable_no_resched(); local_bh_enable(); 0;});}) - -#define _spin_lock(lock) \ -do { \ - preempt_disable(); \ - _raw_spin_lock(lock); \ - __acquire(lock); \ -} while(0) - -#define _write_lock(lock) \ -do { \ - preempt_disable(); \ - _raw_write_lock(lock); \ - __acquire(lock); \ -} while(0) - -#define _read_lock(lock) \ -do { \ - preempt_disable(); \ - _raw_read_lock(lock); \ - __acquire(lock); \ -} while(0) - -#define _spin_unlock(lock) \ -do { \ - _raw_spin_unlock(lock); \ - preempt_enable(); \ - __release(lock); \ -} while (0) - -#define _write_unlock(lock) \ -do { \ - _raw_write_unlock(lock); \ - preempt_enable(); \ - __release(lock); \ -} while(0) - -#define _read_unlock(lock) \ -do { \ - _raw_read_unlock(lock); \ - preempt_enable(); \ - __release(lock); \ -} while(0) - -#define _spin_lock_irqsave(lock, flags) \ -do { \ - local_irq_save(flags); \ - preempt_disable(); \ - _raw_spin_lock(lock); \ - __acquire(lock); \ -} while (0) - -#define _spin_lock_irq(lock) \ -do { \ - local_irq_disable(); \ - preempt_disable(); \ - _raw_spin_lock(lock); \ - __acquire(lock); \ -} while (0) - -#define _spin_lock_bh(lock) \ -do { \ - local_bh_disable(); \ - preempt_disable(); \ - _raw_spin_lock(lock); \ - __acquire(lock); \ -} while (0) - -#define _read_lock_irqsave(lock, flags) \ -do { \ - local_irq_save(flags); \ - preempt_disable(); \ - _raw_read_lock(lock); \ - __acquire(lock); \ -} while (0) - -#define _read_lock_irq(lock) \ -do { \ - local_irq_disable(); \ - preempt_disable(); \ - _raw_read_lock(lock); \ - __acquire(lock); \ -} while (0) - -#define _read_lock_bh(lock) \ -do { \ - local_bh_disable(); \ - preempt_disable(); \ - _raw_read_lock(lock); \ - __acquire(lock); \ -} while (0) - -#define _write_lock_irqsave(lock, flags) \ -do { \ - local_irq_save(flags); \ - preempt_disable(); \ - _raw_write_lock(lock); \ - __acquire(lock); \ -} while (0) +#ifdef CONFIG_DEBUG_SPINLOCK + extern void _raw_spin_lock(spinlock_t *lock); +#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) + extern int _raw_spin_trylock(spinlock_t *lock); + extern void _raw_spin_unlock(spinlock_t *lock); + + extern void _raw_read_lock(rwlock_t *lock); + extern int _raw_read_trylock(rwlock_t *lock); + extern void _raw_read_unlock(rwlock_t *lock); + extern void _raw_write_lock(rwlock_t *lock); + extern int _raw_write_trylock(rwlock_t *lock); + extern void _raw_write_unlock(rwlock_t *lock); +#else +# define _raw_spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock) +# define _raw_spin_trylock(lock) __raw_spin_trylock(&(lock)->raw_lock) +# define _raw_spin_lock(lock) __raw_spin_lock(&(lock)->raw_lock) +# define _raw_spin_lock_flags(lock, flags) \ + __raw_spin_lock_flags(&(lock)->raw_lock, *(flags)) +# define _raw_read_lock(rwlock) __raw_read_lock(&(rwlock)->raw_lock) +# define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock) +# define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock) +# define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock) +# define _raw_read_trylock(rwlock) __raw_read_trylock(&(rwlock)->raw_lock) +# define _raw_write_trylock(rwlock) __raw_write_trylock(&(rwlock)->raw_lock) +#endif -#define _write_lock_irq(lock) \ -do { \ - local_irq_disable(); \ - preempt_disable(); \ - _raw_write_lock(lock); \ - __acquire(lock); \ -} while (0) - -#define _write_lock_bh(lock) \ -do { \ - local_bh_disable(); \ - preempt_disable(); \ - _raw_write_lock(lock); \ - __acquire(lock); \ -} while (0) - -#define _spin_unlock_irqrestore(lock, flags) \ -do { \ - _raw_spin_unlock(lock); \ - local_irq_restore(flags); \ - preempt_enable(); \ - __release(lock); \ -} while (0) - -#define _spin_unlock_irq(lock) \ -do { \ - _raw_spin_unlock(lock); \ - local_irq_enable(); \ - preempt_enable(); \ - __release(lock); \ -} while (0) - -#define _spin_unlock_bh(lock) \ -do { \ - _raw_spin_unlock(lock); \ - preempt_enable_no_resched(); \ - local_bh_enable(); \ - __release(lock); \ -} while (0) - -#define _write_unlock_bh(lock) \ -do { \ - _raw_write_unlock(lock); \ - preempt_enable_no_resched(); \ - local_bh_enable(); \ - __release(lock); \ -} while (0) - -#define _read_unlock_irqrestore(lock, flags) \ -do { \ - _raw_read_unlock(lock); \ - local_irq_restore(flags); \ - preempt_enable(); \ - __release(lock); \ -} while (0) - -#define _write_unlock_irqrestore(lock, flags) \ -do { \ - _raw_write_unlock(lock); \ - local_irq_restore(flags); \ - preempt_enable(); \ - __release(lock); \ -} while (0) - -#define _read_unlock_irq(lock) \ -do { \ - _raw_read_unlock(lock); \ - local_irq_enable(); \ - preempt_enable(); \ - __release(lock); \ -} while (0) - -#define _read_unlock_bh(lock) \ -do { \ - _raw_read_unlock(lock); \ - preempt_enable_no_resched(); \ - local_bh_enable(); \ - __release(lock); \ -} while (0) - -#define _write_unlock_irq(lock) \ -do { \ - _raw_write_unlock(lock); \ - local_irq_enable(); \ - preempt_enable(); \ - __release(lock); \ -} while (0) - -#endif /* !SMP */ +#define read_can_lock(rwlock) __raw_read_can_lock(&(rwlock)->raw_lock) +#define write_can_lock(rwlock) __raw_write_can_lock(&(rwlock)->raw_lock) /* * Define the various spin_lock and rw_lock methods. Note we define these * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various * methods are defined as nops in the case they are not required. */ -#define spin_trylock(lock) __cond_lock(_spin_trylock(lock)) -#define read_trylock(lock) __cond_lock(_read_trylock(lock)) -#define write_trylock(lock) __cond_lock(_write_trylock(lock)) +#define spin_trylock(lock) __cond_lock(_spin_trylock(lock)) +#define read_trylock(lock) __cond_lock(_read_trylock(lock)) +#define write_trylock(lock) __cond_lock(_write_trylock(lock)) -#define spin_lock(lock) _spin_lock(lock) -#define write_lock(lock) _write_lock(lock) -#define read_lock(lock) _read_lock(lock) +#define spin_lock(lock) _spin_lock(lock) +#define write_lock(lock) _write_lock(lock) +#define read_lock(lock) _read_lock(lock) -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) #define spin_lock_irqsave(lock, flags) flags = _spin_lock_irqsave(lock) #define read_lock_irqsave(lock, flags) flags = _read_lock_irqsave(lock) #define write_lock_irqsave(lock, flags) flags = _write_lock_irqsave(lock) @@ -470,137 +171,59 @@ do { \ #define write_lock_irq(lock) _write_lock_irq(lock) #define write_lock_bh(lock) _write_lock_bh(lock) -#define spin_unlock(lock) _spin_unlock(lock) -#define write_unlock(lock) _write_unlock(lock) -#define read_unlock(lock) _read_unlock(lock) +#define spin_unlock(lock) _spin_unlock(lock) +#define write_unlock(lock) _write_unlock(lock) +#define read_unlock(lock) _read_unlock(lock) -#define spin_unlock_irqrestore(lock, flags) _spin_unlock_irqrestore(lock, flags) +#define spin_unlock_irqrestore(lock, flags) \ + _spin_unlock_irqrestore(lock, flags) #define spin_unlock_irq(lock) _spin_unlock_irq(lock) #define spin_unlock_bh(lock) _spin_unlock_bh(lock) -#define read_unlock_irqrestore(lock, flags) _read_unlock_irqrestore(lock, flags) -#define read_unlock_irq(lock) _read_unlock_irq(lock) -#define read_unlock_bh(lock) _read_unlock_bh(lock) +#define read_unlock_irqrestore(lock, flags) \ + _read_unlock_irqrestore(lock, flags) +#define read_unlock_irq(lock) _read_unlock_irq(lock) +#define read_unlock_bh(lock) _read_unlock_bh(lock) -#define write_unlock_irqrestore(lock, flags) _write_unlock_irqrestore(lock, flags) -#define write_unlock_irq(lock) _write_unlock_irq(lock) -#define write_unlock_bh(lock) _write_unlock_bh(lock) +#define write_unlock_irqrestore(lock, flags) \ + _write_unlock_irqrestore(lock, flags) +#define write_unlock_irq(lock) _write_unlock_irq(lock) +#define write_unlock_bh(lock) _write_unlock_bh(lock) -#define spin_trylock_bh(lock) __cond_lock(_spin_trylock_bh(lock)) +#define spin_trylock_bh(lock) __cond_lock(_spin_trylock_bh(lock)) #define spin_trylock_irq(lock) \ ({ \ local_irq_disable(); \ _spin_trylock(lock) ? \ - 1 : ({local_irq_enable(); 0; }); \ + 1 : ({ local_irq_enable(); 0; }); \ }) #define spin_trylock_irqsave(lock, flags) \ ({ \ local_irq_save(flags); \ _spin_trylock(lock) ? \ - 1 : ({local_irq_restore(flags); 0;}); \ + 1 : ({ local_irq_restore(flags); 0; }); \ }) -#ifdef CONFIG_LOCKMETER -extern void _metered_spin_lock (spinlock_t *lock); -extern void _metered_spin_unlock (spinlock_t *lock); -extern int _metered_spin_trylock(spinlock_t *lock); -extern void _metered_read_lock (rwlock_t *lock); -extern void _metered_read_unlock (rwlock_t *lock); -extern void _metered_write_lock (rwlock_t *lock); -extern void _metered_write_unlock (rwlock_t *lock); -extern int _metered_read_trylock (rwlock_t *lock); -extern int _metered_write_trylock(rwlock_t *lock); -#endif - -/* "lock on reference count zero" */ -#ifndef ATOMIC_DEC_AND_LOCK -#include -extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); -#endif - -#define atomic_dec_and_lock(atomic,lock) __cond_lock(_atomic_dec_and_lock(atomic,lock)) - -/* - * bit-based spin_lock() - * - * Don't use this unless you really need to: spin_lock() and spin_unlock() - * are significantly faster. - */ -static inline void bit_spin_lock(int bitnum, unsigned long *addr) -{ - /* - * Assuming the lock is uncontended, this never enters - * the body of the outer loop. If it is contended, then - * within the inner loop a non-atomic test is used to - * busywait with less bus contention for a good time to - * attempt to acquire the lock bit. - */ - preempt_disable(); -#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) - while (test_and_set_bit(bitnum, addr)) { - while (test_bit(bitnum, addr)) { - preempt_enable(); - cpu_relax(); - preempt_disable(); - } - } -#endif - __acquire(bitlock); -} - /* - * Return true if it was acquired + * Pull the atomic_t declaration: + * (asm-mips/atomic.h needs above definitions) */ -static inline int bit_spin_trylock(int bitnum, unsigned long *addr) -{ - preempt_disable(); -#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) - if (test_and_set_bit(bitnum, addr)) { - preempt_enable(); - return 0; - } -#endif - __acquire(bitlock); - return 1; -} - -/* - * bit-based spin_unlock() - */ -static inline void bit_spin_unlock(int bitnum, unsigned long *addr) -{ -#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) - BUG_ON(!test_bit(bitnum, addr)); - smp_mb__before_clear_bit(); - clear_bit(bitnum, addr); -#endif - preempt_enable(); - __release(bitlock); -} - -/* - * Return true if the lock is held. +#include +/** + * atomic_dec_and_lock - lock on reaching reference count zero + * @atomic: the atomic counter + * @lock: the spinlock in question */ -static inline int bit_spin_is_locked(int bitnum, unsigned long *addr) -{ -#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) - return test_bit(bitnum, addr); -#elif defined CONFIG_PREEMPT - return preempt_count(); -#else - return 1; -#endif -} - -#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED -#define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED +extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); +#define atomic_dec_and_lock(atomic, lock) \ + __cond_lock(_atomic_dec_and_lock(atomic, lock)) /** * spin_can_lock - would spin_trylock() succeed? * @lock: the spinlock in question. */ -#define spin_can_lock(lock) (!spin_is_locked(lock)) +#define spin_can_lock(lock) (!spin_is_locked(lock)) #endif /* __LINUX_SPINLOCK_H */ diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h new file mode 100644 index 000000000000..78e6989ffb54 --- /dev/null +++ b/include/linux/spinlock_api_smp.h @@ -0,0 +1,57 @@ +#ifndef __LINUX_SPINLOCK_API_SMP_H +#define __LINUX_SPINLOCK_API_SMP_H + +#ifndef __LINUX_SPINLOCK_H +# error "please don't include this file directly" +#endif + +/* + * include/linux/spinlock_api_smp.h + * + * spinlock API declarations on SMP (and debug) + * (implemented in kernel/spinlock.c) + * + * portions Copyright 2005, Red Hat, Inc., Ingo Molnar + * Released under the General Public License (GPL). + */ + +int in_lock_functions(unsigned long addr); + +#define assert_spin_locked(x) BUG_ON(!spin_is_locked(x)) + +void __lockfunc _spin_lock(spinlock_t *lock) __acquires(spinlock_t); +void __lockfunc _read_lock(rwlock_t *lock) __acquires(rwlock_t); +void __lockfunc _write_lock(rwlock_t *lock) __acquires(rwlock_t); +void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(spinlock_t); +void __lockfunc _read_lock_bh(rwlock_t *lock) __acquires(rwlock_t); +void __lockfunc _write_lock_bh(rwlock_t *lock) __acquires(rwlock_t); +void __lockfunc _spin_lock_irq(spinlock_t *lock) __acquires(spinlock_t); +void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(rwlock_t); +void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(rwlock_t); +unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock) + __acquires(spinlock_t); +unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) + __acquires(rwlock_t); +unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) + __acquires(rwlock_t); +int __lockfunc _spin_trylock(spinlock_t *lock); +int __lockfunc _read_trylock(rwlock_t *lock); +int __lockfunc _write_trylock(rwlock_t *lock); +int __lockfunc _spin_trylock_bh(spinlock_t *lock); +void __lockfunc _spin_unlock(spinlock_t *lock) __releases(spinlock_t); +void __lockfunc _read_unlock(rwlock_t *lock) __releases(rwlock_t); +void __lockfunc _write_unlock(rwlock_t *lock) __releases(rwlock_t); +void __lockfunc _spin_unlock_bh(spinlock_t *lock) __releases(spinlock_t); +void __lockfunc _read_unlock_bh(rwlock_t *lock) __releases(rwlock_t); +void __lockfunc _write_unlock_bh(rwlock_t *lock) __releases(rwlock_t); +void __lockfunc _spin_unlock_irq(spinlock_t *lock) __releases(spinlock_t); +void __lockfunc _read_unlock_irq(rwlock_t *lock) __releases(rwlock_t); +void __lockfunc _write_unlock_irq(rwlock_t *lock) __releases(rwlock_t); +void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) + __releases(spinlock_t); +void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) + __releases(rwlock_t); +void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) + __releases(rwlock_t); + +#endif /* __LINUX_SPINLOCK_API_SMP_H */ diff --git a/include/linux/spinlock_api_up.h b/include/linux/spinlock_api_up.h new file mode 100644 index 000000000000..cd81cee566f4 --- /dev/null +++ b/include/linux/spinlock_api_up.h @@ -0,0 +1,80 @@ +#ifndef __LINUX_SPINLOCK_API_UP_H +#define __LINUX_SPINLOCK_API_UP_H + +#ifndef __LINUX_SPINLOCK_H +# error "please don't include this file directly" +#endif + +/* + * include/linux/spinlock_api_up.h + * + * spinlock API implementation on UP-nondebug (inlined implementation) + * + * portions Copyright 2005, Red Hat, Inc., Ingo Molnar + * Released under the General Public License (GPL). + */ + +#define in_lock_functions(ADDR) 0 + +#define assert_spin_locked(lock) do { (void)(lock); } while (0) + +/* + * In the UP-nondebug case there's no real locking going on, so the + * only thing we have to do is to keep the preempt counts and irq + * flags straight, to supress compiler warnings of unused lock + * variables, and to add the proper checker annotations: + */ +#define __LOCK(lock) \ + do { preempt_disable(); __acquire(lock); (void)(lock); } while (0) + +#define __LOCK_BH(lock) \ + do { local_bh_disable(); __LOCK(lock); } while (0) + +#define __LOCK_IRQ(lock) \ + do { local_irq_disable(); __LOCK(lock); } while (0) + +#define __LOCK_IRQSAVE(lock, flags) \ + do { local_irq_save(flags); __LOCK(lock); } while (0) + +#define __UNLOCK(lock) \ + do { preempt_enable(); __release(lock); (void)(lock); } while (0) + +#define __UNLOCK_BH(lock) \ + do { preempt_enable_no_resched(); local_bh_enable(); __release(lock); (void)(lock); } while (0) + +#define __UNLOCK_IRQ(lock) \ + do { local_irq_enable(); __UNLOCK(lock); } while (0) + +#define __UNLOCK_IRQRESTORE(lock, flags) \ + do { local_irq_restore(flags); __UNLOCK(lock); } while (0) + +#define _spin_lock(lock) __LOCK(lock) +#define _read_lock(lock) __LOCK(lock) +#define _write_lock(lock) __LOCK(lock) +#define _spin_lock_bh(lock) __LOCK_BH(lock) +#define _read_lock_bh(lock) __LOCK_BH(lock) +#define _write_lock_bh(lock) __LOCK_BH(lock) +#define _spin_lock_irq(lock) __LOCK_IRQ(lock) +#define _read_lock_irq(lock) __LOCK_IRQ(lock) +#define _write_lock_irq(lock) __LOCK_IRQ(lock) +#define _spin_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) +#define _read_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) +#define _write_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) +#define _spin_trylock(lock) ({ __LOCK(lock); 1; }) +#define _read_trylock(lock) ({ __LOCK(lock); 1; }) +#define _write_trylock(lock) ({ __LOCK(lock); 1; }) +#define _spin_trylock_bh(lock) ({ __LOCK_BH(lock); 1; }) +#define _spin_unlock(lock) __UNLOCK(lock) +#define _read_unlock(lock) __UNLOCK(lock) +#define _write_unlock(lock) __UNLOCK(lock) +#define _spin_unlock_bh(lock) __UNLOCK_BH(lock) +#define _write_unlock_bh(lock) __UNLOCK_BH(lock) +#define _read_unlock_bh(lock) __UNLOCK_BH(lock) +#define _spin_unlock_irq(lock) __UNLOCK_IRQ(lock) +#define _read_unlock_irq(lock) __UNLOCK_IRQ(lock) +#define _write_unlock_irq(lock) __UNLOCK_IRQ(lock) +#define _spin_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags) +#define _read_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags) +#define _write_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags) + +#endif /* __LINUX_SPINLOCK_API_UP_H */ diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h new file mode 100644 index 000000000000..9cb51e070390 --- /dev/null +++ b/include/linux/spinlock_types.h @@ -0,0 +1,67 @@ +#ifndef __LINUX_SPINLOCK_TYPES_H +#define __LINUX_SPINLOCK_TYPES_H + +/* + * include/linux/spinlock_types.h - generic spinlock type definitions + * and initializers + * + * portions Copyright 2005, Red Hat, Inc., Ingo Molnar + * Released under the General Public License (GPL). + */ + +#if defined(CONFIG_SMP) +# include +#else +# include +#endif + +typedef struct { + raw_spinlock_t raw_lock; +#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP) + unsigned int break_lock; +#endif +#ifdef CONFIG_DEBUG_SPINLOCK + unsigned int magic, owner_cpu; + void *owner; +#endif +} spinlock_t; + +#define SPINLOCK_MAGIC 0xdead4ead + +typedef struct { + raw_rwlock_t raw_lock; +#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP) + unsigned int break_lock; +#endif +#ifdef CONFIG_DEBUG_SPINLOCK + unsigned int magic, owner_cpu; + void *owner; +#endif +} rwlock_t; + +#define RWLOCK_MAGIC 0xdeaf1eed + +#define SPINLOCK_OWNER_INIT ((void *)-1L) + +#ifdef CONFIG_DEBUG_SPINLOCK +# define SPIN_LOCK_UNLOCKED \ + (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \ + .magic = SPINLOCK_MAGIC, \ + .owner = SPINLOCK_OWNER_INIT, \ + .owner_cpu = -1 } +#define RW_LOCK_UNLOCKED \ + (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ + .magic = RWLOCK_MAGIC, \ + .owner = SPINLOCK_OWNER_INIT, \ + .owner_cpu = -1 } +#else +# define SPIN_LOCK_UNLOCKED \ + (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED } +#define RW_LOCK_UNLOCKED \ + (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED } +#endif + +#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED +#define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED + +#endif /* __LINUX_SPINLOCK_TYPES_H */ diff --git a/include/linux/spinlock_types_up.h b/include/linux/spinlock_types_up.h new file mode 100644 index 000000000000..def2d173a8db --- /dev/null +++ b/include/linux/spinlock_types_up.h @@ -0,0 +1,51 @@ +#ifndef __LINUX_SPINLOCK_TYPES_UP_H +#define __LINUX_SPINLOCK_TYPES_UP_H + +#ifndef __LINUX_SPINLOCK_TYPES_H +# error "please don't include this file directly" +#endif + +/* + * include/linux/spinlock_types_up.h - spinlock type definitions for UP + * + * portions Copyright 2005, Red Hat, Inc., Ingo Molnar + * Released under the General Public License (GPL). + */ + +#ifdef CONFIG_DEBUG_SPINLOCK + +typedef struct { + volatile unsigned int slock; +} raw_spinlock_t; + +#define __RAW_SPIN_LOCK_UNLOCKED { 1 } + +#else + +/* + * All gcc 2.95 versions and early versions of 2.96 have a nasty bug + * with empty initializers. + */ +#if (__GNUC__ > 2) +typedef struct { } raw_spinlock_t; + +#define __RAW_SPIN_LOCK_UNLOCKED { } +#else +typedef struct { int gcc_is_buggy; } raw_spinlock_t; +#define __RAW_SPIN_LOCK_UNLOCKED (raw_spinlock_t) { 0 } +#endif + +#endif + +#if (__GNUC__ > 2) +typedef struct { + /* no debug version on UP */ +} raw_rwlock_t; + +#define __RAW_RW_LOCK_UNLOCKED { } +#else +typedef struct { int gcc_is_buggy; } raw_rwlock_t; +#define __RAW_RW_LOCK_UNLOCKED (raw_rwlock_t) { 0 } +#endif + +#endif /* __LINUX_SPINLOCK_TYPES_UP_H */ diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h new file mode 100644 index 000000000000..31accf2f0b13 --- /dev/null +++ b/include/linux/spinlock_up.h @@ -0,0 +1,74 @@ +#ifndef __LINUX_SPINLOCK_UP_H +#define __LINUX_SPINLOCK_UP_H + +#ifndef __LINUX_SPINLOCK_H +# error "please don't include this file directly" +#endif + +/* + * include/linux/spinlock_up.h - UP-debug version of spinlocks. + * + * portions Copyright 2005, Red Hat, Inc., Ingo Molnar + * Released under the General Public License (GPL). + * + * In the debug case, 1 means unlocked, 0 means locked. (the values + * are inverted, to catch initialization bugs) + * + * No atomicity anywhere, we are on UP. + */ + +#ifdef CONFIG_DEBUG_SPINLOCK + +#define __raw_spin_is_locked(x) ((x)->slock == 0) + +static inline void __raw_spin_lock(raw_spinlock_t *lock) +{ + lock->slock = 0; +} + +static inline void +__raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) +{ + local_irq_save(flags); + lock->slock = 0; +} + +static inline int __raw_spin_trylock(raw_spinlock_t *lock) +{ + char oldval = lock->slock; + + lock->slock = 0; + + return oldval > 0; +} + +static inline void __raw_spin_unlock(raw_spinlock_t *lock) +{ + lock->slock = 1; +} + +/* + * Read-write spinlocks. No debug version. + */ +#define __raw_read_lock(lock) do { (void)(lock); } while (0) +#define __raw_write_lock(lock) do { (void)(lock); } while (0) +#define __raw_read_trylock(lock) ({ (void)(lock); 1; }) +#define __raw_write_trylock(lock) ({ (void)(lock); 1; }) +#define __raw_read_unlock(lock) do { (void)(lock); } while (0) +#define __raw_write_unlock(lock) do { (void)(lock); } while (0) + +#else /* DEBUG_SPINLOCK */ +#define __raw_spin_is_locked(lock) ((void)(lock), 0) +/* for sched.c and kernel_lock.c: */ +# define __raw_spin_lock(lock) do { (void)(lock); } while (0) +# define __raw_spin_unlock(lock) do { (void)(lock); } while (0) +# define __raw_spin_trylock(lock) ({ (void)(lock); 1; }) +#endif /* DEBUG_SPINLOCK */ + +#define __raw_read_can_lock(lock) (((void)(lock), 1)) +#define __raw_write_can_lock(lock) (((void)(lock), 1)) + +#define __raw_spin_unlock_wait(lock) \ + do { cpu_relax(); } while (__raw_spin_is_locked(lock)) + +#endif /* __LINUX_SPINLOCK_UP_H */ -- cgit v1.2.3 From 4247bdc60048018b98f71228b45cfbc5f5270c86 Mon Sep 17 00:00:00 2001 From: Paul Jackson Date: Sat, 10 Sep 2005 00:26:06 -0700 Subject: [PATCH] cpuset semaphore depth check deadlock fix The cpusets-formalize-intermediate-gfp_kernel-containment patch has a deadlock problem. This patch was part of a set of four patches to make more extensive use of the cpuset 'mem_exclusive' attribute to manage kernel GFP_KERNEL memory allocations and to constrain the out-of-memory (oom) killer. A task that is changing cpusets in particular ways on a system when it is very short of free memory could double trip over the global cpuset_sem semaphore (get the lock and then deadlock trying to get it again). The second attempt to get cpuset_sem would be in the routine cpuset_zone_allowed(). This was discovered by code inspection. I can not reproduce the problem except with an artifically hacked kernel and a specialized stress test. In real life you cannot hit this unless you are manipulating cpusets, and are very unlikely to hit it unless you are rapidly modifying cpusets on a memory tight system. Even then it would be a rare occurence. If you did hit it, the task double tripping over cpuset_sem would deadlock in the kernel, and any other task also trying to manipulate cpusets would deadlock there too, on cpuset_sem. Your batch manager would be wedged solid (if it was cpuset savvy), but classic Unix shells and utilities would work well enough to reboot the system. The unusual condition that led to this bug is that unlike most semaphores, cpuset_sem _can_ be acquired while in the page allocation code, when __alloc_pages() calls cpuset_zone_allowed. So it easy to mistakenly perform the following sequence: 1) task makes system call to alter a cpuset 2) take cpuset_sem 3) try to allocate memory 4) memory allocator, via cpuset_zone_allowed, trys to take cpuset_sem 5) deadlock The reason that this is not a serious bug for most users is that almost all calls to allocate memory don't require taking cpuset_sem. Only some code paths off the beaten track require taking cpuset_sem -- which is good. Taking a global semaphore on the main code path for allocating memory would not scale well. This patch fixes this deadlock by wrapping the up() and down() calls on cpuset_sem in kernel/cpuset.c with code that tracks the nesting depth of the current task on that semaphore, and only does the real down() if the task doesn't hold the lock already, and only does the real up() if the nesting depth (number of unmatched downs) is exactly one. The previous required use of refresh_mems(), anytime that the cpuset_sem semaphore was acquired and the code executed while holding that semaphore might try to allocate memory, is no longer required. Two refresh_mems() calls were removed thanks to this. This is a good change, as failing to get all the necessary refresh_mems() calls placed was a primary source of bugs in this cpuset code. The only remaining call to refresh_mems() is made while doing a memory allocation, if certain task memory placement data needs to be updated from its cpuset, due to the cpuset having been changed behind the tasks back. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sched.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index c551e6a1447e..8a1fcfe80fc7 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -782,6 +782,7 @@ struct task_struct { short il_next; #endif #ifdef CONFIG_CPUSETS + short cpuset_sem_nest_depth; struct cpuset *cpuset; nodemask_t mems_allowed; int cpuset_mems_generation; -- cgit v1.2.3 From d79fc0fc6645b0cf5cd980da76942ca6d6300fa4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 10 Sep 2005 00:26:12 -0700 Subject: [PATCH] sched: TASK_NONINTERACTIVE This patch implements a task state bit (TASK_NONINTERACTIVE), which can be used by blocking points to mark the task's wait as "non-interactive". This does not mean the task will be considered a CPU-hog - the wait will simply not have an effect on the waiting task's priority - positive or negative alike. Right now only pipe_wait() will make use of it, because it's a common source of not-so-interactive waits (kernel compilation jobs, etc.). Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sched.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 8a1fcfe80fc7..ac70f845b5b1 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -114,6 +114,7 @@ extern unsigned long nr_iowait(void); #define TASK_TRACED 8 #define EXIT_ZOMBIE 16 #define EXIT_DEAD 32 +#define TASK_NONINTERACTIVE 64 #define __set_task_state(tsk, state_value) \ do { (tsk)->state = (state_value); } while (0) -- cgit v1.2.3 From 5ce7852cdf07ab903fb1c72d0915ac492c6e07c7 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 10 Sep 2005 00:26:28 -0700 Subject: [PATCH] mm/filemap.c: make two functions static With Nick Piggin Give some things static scope. Signed-off-by: Adrian Bunk Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fs.h | 2 -- include/linux/writeback.h | 2 -- 2 files changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 7f61227827d7..e0b77c5af9a0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1509,8 +1509,6 @@ extern void do_generic_mapping_read(struct address_space *mapping, loff_t *, read_descriptor_t *, read_actor_t); extern void file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); -extern ssize_t generic_file_direct_IO(int rw, struct kiocb *iocb, - const struct iovec *iov, loff_t offset, unsigned long nr_segs); extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *ppos); ssize_t generic_file_writev(struct file *filp, const struct iovec *iov, diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 542dbaee6512..343d883d69c5 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -109,8 +109,6 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0); int do_writepages(struct address_space *mapping, struct writeback_control *wbc); int sync_page_range(struct inode *inode, struct address_space *mapping, loff_t pos, size_t count); -int sync_page_range_nolock(struct inode *inode, struct address_space - *mapping, loff_t pos, size_t count); /* pdflush.c */ extern int nr_pdflush_threads; /* Global so it can be exported to sysctl -- cgit v1.2.3 From b2d550736f8b2186b8ef7e206d0bfbfec2238ae8 Mon Sep 17 00:00:00 2001 From: Victor Fusco Date: Sat, 10 Sep 2005 00:26:36 -0700 Subject: [PATCH] mm/slab: fix sparse warnings Fix the sparse warning "implicit cast to nocast type" Signed-off-by: Victor Fusco Signed-off-by: Domen Puncer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/slab.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/slab.h b/include/linux/slab.h index 42a6bea58af3..1f356f3bbc64 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -118,7 +118,8 @@ extern void kfree(const void *); extern unsigned int ksize(const void *); #ifdef CONFIG_NUMA -extern void *kmem_cache_alloc_node(kmem_cache_t *, int flags, int node); +extern void *kmem_cache_alloc_node(kmem_cache_t *, + unsigned int __nocast flags, int node); extern void *kmalloc_node(size_t size, unsigned int __nocast flags, int node); #else static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int node) -- cgit v1.2.3 From 00b61f51922e432fd92a482ba1e0b5f8f326ef46 Mon Sep 17 00:00:00 2001 From: Victor Fusco Date: Sat, 10 Sep 2005 00:26:48 -0700 Subject: [PATCH] lib/radix-tree: Fix "nocast type" warnings Fix the sparse warning "implicit cast to nocast type" Signed-off-by: Victor Fusco Signed-off-by: Domen Puncer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/radix-tree.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 8081a281fa5e..9c51917b1cce 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -24,7 +24,7 @@ struct radix_tree_root { unsigned int height; - int gfp_mask; + unsigned int gfp_mask; struct radix_tree_node *rnode; }; @@ -50,7 +50,7 @@ void *radix_tree_delete(struct radix_tree_root *, unsigned long); unsigned int radix_tree_gang_lookup(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items); -int radix_tree_preload(int gfp_mask); +int radix_tree_preload(unsigned int __nocast gfp_mask); void radix_tree_init(void); void *radix_tree_tag_set(struct radix_tree_root *root, unsigned long index, int tag); -- cgit v1.2.3 From 3a11ec5e502cb61ee31095008318f9c107d9db60 Mon Sep 17 00:00:00 2001 From: Victor Fusco Date: Sat, 10 Sep 2005 00:26:49 -0700 Subject: [PATCH] dmapool: Fix "nocast type" warnings Fix the sparse warning "implicit cast to nocast type" Signed-off-by: Victor Fusco Signed-off-by: Domen Puncer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/dmapool.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dmapool.h b/include/linux/dmapool.h index e60bfdac348d..4932ee5c77f0 100644 --- a/include/linux/dmapool.h +++ b/include/linux/dmapool.h @@ -19,7 +19,8 @@ struct dma_pool *dma_pool_create(const char *name, struct device *dev, void dma_pool_destroy(struct dma_pool *pool); -void *dma_pool_alloc(struct dma_pool *pool, int mem_flags, dma_addr_t *handle); +void *dma_pool_alloc(struct dma_pool *pool, unsigned int __nocast mem_flags, + dma_addr_t *handle); void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t addr); -- cgit v1.2.3 From 2befb9e36dc52d715c3a67a9dbad36ac1edc376f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 10 Sep 2005 00:27:17 -0700 Subject: [PATCH] include/linux/blkdev.h: "extern inline" -> "static inline" "extern inline" doesn't make much sense. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/blkdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index aefa26fbae8a..efdc9b5bc05c 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -728,7 +728,7 @@ static inline unsigned int blksize_bits(unsigned int size) return bits; } -extern inline unsigned int block_size(struct block_device *bdev) +static inline unsigned int block_size(struct block_device *bdev) { return bdev->bd_block_size; } -- cgit v1.2.3 From 9adeb1b409e832c31d93106ce52482a5f0078439 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 10 Sep 2005 00:27:18 -0700 Subject: [PATCH] "extern inline" -> "static inline" "extern inline" doesn't make much sense. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/reiserfs_fs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 17e458e17e2b..af00b10294cd 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -2097,7 +2097,7 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th, struct inode *, b_blocknr_t, int for_unformatted); int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *, b_blocknr_t *, int, int); -extern inline int reiserfs_new_form_blocknrs(struct tree_balance *tb, +static inline int reiserfs_new_form_blocknrs(struct tree_balance *tb, b_blocknr_t * new_blocknrs, int amount_needed) { @@ -2113,7 +2113,7 @@ extern inline int reiserfs_new_form_blocknrs(struct tree_balance *tb, 0); } -extern inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle +static inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle *th, struct inode *inode, b_blocknr_t * new_blocknrs, struct path *path, long block) @@ -2130,7 +2130,7 @@ extern inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle } #ifdef REISERFS_PREALLOCATE -extern inline int reiserfs_new_unf_blocknrs2(struct reiserfs_transaction_handle +static inline int reiserfs_new_unf_blocknrs2(struct reiserfs_transaction_handle *th, struct inode *inode, b_blocknr_t * new_blocknrs, struct path *path, long block) -- cgit v1.2.3 From c2d08dade7743bd3a28cc5f68163e71c00a2a908 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 10 Sep 2005 00:27:18 -0700 Subject: [PATCH] include/linux/bio.h: "extern inline" -> "static inline" "extern inline" doesn't make much sense. Signed-off-by: Adrian Bunk Acked-by: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bio.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index cdaf03a14a51..6e1c79c8b6bf 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -314,9 +314,8 @@ void zero_fill_bio(struct bio *bio); * bvec_kmap_irq and bvec_kunmap_irq!! * * This function MUST be inlined - it plays with the CPU interrupt flags. - * Hence the `extern inline'. */ -extern inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags) +static inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags) { unsigned long addr; @@ -332,7 +331,7 @@ extern inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags) return (char *) addr + bvec->bv_offset; } -extern inline void bvec_kunmap_irq(char *buffer, unsigned long *flags) +static inline void bvec_kunmap_irq(char *buffer, unsigned long *flags) { unsigned long ptr = (unsigned long) buffer & PAGE_MASK; @@ -345,7 +344,7 @@ extern inline void bvec_kunmap_irq(char *buffer, unsigned long *flags) #define bvec_kunmap_irq(buf, flags) do { *(flags) = 0; } while (0) #endif -extern inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx, +static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx, unsigned long *flags) { return bvec_kmap_irq(bio_iovec_idx(bio, idx), flags); -- cgit v1.2.3 From 64ed93a268bc18fa6f72f61420d0e0022c5e38d1 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Sat, 10 Sep 2005 00:27:21 -0700 Subject: [PATCH] add schedule_timeout_{,un}interruptible() interfaces Add schedule_timeout_{,un}interruptible() interfaces so that schedule_timeout() callers don't have to worry about forgetting to add the set_current_state() call beforehand. Signed-off-by: Nishanth Aravamudan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sched.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index ac70f845b5b1..4b83cb230006 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -203,6 +203,8 @@ extern int in_sched_functions(unsigned long addr); #define MAX_SCHEDULE_TIMEOUT LONG_MAX extern signed long FASTCALL(schedule_timeout(signed long timeout)); +extern signed long schedule_timeout_interruptible(signed long timeout); +extern signed long schedule_timeout_uninterruptible(signed long timeout); asmlinkage void schedule(void); struct namespace; -- cgit v1.2.3 From 84f902c0903a98a315b45a4fba3d2ac0de388256 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Sat, 10 Sep 2005 00:27:22 -0700 Subject: [PATCH] include: update jiffies/{m,u}secs conversion functions Clarify the human-time units to jiffies conversion functions by using the constants in time.h. This makes many of the subsequent patches direct copies of the current code. Signed-off-by: Nishanth Aravamudan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/jiffies.h | 40 ++++++++++++++++++++-------------------- include/linux/time.h | 2 ++ 2 files changed, 22 insertions(+), 20 deletions(-) (limited to 'include/linux') diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index d7a2555a886c..6acfdbba734b 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h @@ -254,23 +254,23 @@ static inline u64 get_jiffies_64(void) */ static inline unsigned int jiffies_to_msecs(const unsigned long j) { -#if HZ <= 1000 && !(1000 % HZ) - return (1000 / HZ) * j; -#elif HZ > 1000 && !(HZ % 1000) - return (j + (HZ / 1000) - 1)/(HZ / 1000); +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) + return (MSEC_PER_SEC / HZ) * j; +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) + return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC); #else - return (j * 1000) / HZ; + return (j * MSEC_PER_SEC) / HZ; #endif } static inline unsigned int jiffies_to_usecs(const unsigned long j) { -#if HZ <= 1000000 && !(1000000 % HZ) - return (1000000 / HZ) * j; -#elif HZ > 1000000 && !(HZ % 1000000) - return (j + (HZ / 1000000) - 1)/(HZ / 1000000); +#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) + return (USEC_PER_SEC / HZ) * j; +#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) + return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC); #else - return (j * 1000000) / HZ; + return (j * USEC_PER_SEC) / HZ; #endif } @@ -278,12 +278,12 @@ static inline unsigned long msecs_to_jiffies(const unsigned int m) { if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) return MAX_JIFFY_OFFSET; -#if HZ <= 1000 && !(1000 % HZ) - return (m + (1000 / HZ) - 1) / (1000 / HZ); -#elif HZ > 1000 && !(HZ % 1000) - return m * (HZ / 1000); +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) + return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ); +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) + return m * (HZ / MSEC_PER_SEC); #else - return (m * HZ + 999) / 1000; + return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC; #endif } @@ -291,12 +291,12 @@ static inline unsigned long usecs_to_jiffies(const unsigned int u) { if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET)) return MAX_JIFFY_OFFSET; -#if HZ <= 1000000 && !(1000000 % HZ) - return (u + (1000000 / HZ) - 1) / (1000000 / HZ); -#elif HZ > 1000000 && !(HZ % 1000000) - return u * (HZ / 1000000); +#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) + return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ); +#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) + return u * (HZ / USEC_PER_SEC); #else - return (u * HZ + 999999) / 1000000; + return (u * HZ + USEC_PER_SEC - 1) / USEC_PER_SEC; #endif } diff --git a/include/linux/time.h b/include/linux/time.h index c10d4c21c183..36fb2ef13cff 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -28,6 +28,8 @@ struct timezone { #ifdef __KERNEL__ /* Parameters used to convert the timespec values */ +#define MSEC_PER_SEC (1000L) + #ifndef USEC_PER_SEC #define USEC_PER_SEC (1000000L) #endif -- cgit v1.2.3 From 373016e9e1353f2af871993d27d00768f08cc883 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 10 Sep 2005 00:27:23 -0700 Subject: [PATCH] time.h: remove ifdefs Remove these ifdefs - there's no need to have more than one definition of these multipliers anywhere. Cc: Nishanth Aravamudan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/time.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/time.h b/include/linux/time.h index 36fb2ef13cff..8e83f4e778bb 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -29,18 +29,9 @@ struct timezone { /* Parameters used to convert the timespec values */ #define MSEC_PER_SEC (1000L) - -#ifndef USEC_PER_SEC #define USEC_PER_SEC (1000000L) -#endif - -#ifndef NSEC_PER_SEC #define NSEC_PER_SEC (1000000000L) -#endif - -#ifndef NSEC_PER_USEC #define NSEC_PER_USEC (1000L) -#endif static __inline__ int timespec_equal(struct timespec *a, struct timespec *b) { -- cgit v1.2.3 From fe08ac3178243fbed61f24878ffcf5cfb53fceb1 Mon Sep 17 00:00:00 2001 From: "viro@ZenIV.linux.org.uk" Date: Fri, 9 Sep 2005 22:03:44 +0100 Subject: [PATCH] __user annotations (scsi/ch) Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- include/linux/chio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/chio.h b/include/linux/chio.h index 63035ae67e63..a404c111c937 100644 --- a/include/linux/chio.h +++ b/include/linux/chio.h @@ -96,7 +96,7 @@ struct changer_position { */ struct changer_element_status { int ces_type; - unsigned char *ces_data; + unsigned char __user *ces_data; }; #define CESTATUS_FULL 0x01 /* full */ #define CESTATUS_IMPEXP 0x02 /* media was imported (inserted by sysop) */ -- cgit v1.2.3 From a2a979821b6ab75a4f143cfaa1c4672cc259ec10 Mon Sep 17 00:00:00 2001 From: Keith Owens Date: Sun, 11 Sep 2005 17:19:06 +1000 Subject: [PATCH] MCA/INIT: scheduler hooks Scheduler hooks to see/change which process is deemed to be on a cpu. Signed-off-by: Keith Owens Signed-off-by: Tony Luck --- include/linux/sched.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 4b83cb230006..ed3bb19d1337 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -904,6 +904,8 @@ extern int task_curr(const task_t *p); extern int idle_cpu(int cpu); extern int sched_setscheduler(struct task_struct *, int, struct sched_param *); extern task_t *idle_task(int cpu); +extern task_t *curr_task(int cpu); +extern void set_curr_task(int cpu, task_t *p); void yield(void); -- cgit v1.2.3 From f24ec7f6c6278c0ea4c00efe96d50b1e66796c44 Mon Sep 17 00:00:00 2001 From: Evgeniy Polyakov Date: Mon, 12 Sep 2005 17:12:43 +0400 Subject: [PATCH] crc16: remove w1 specific comments. Remove w1 comments from crc16.h and move specific constants into w1_ds2433.c where they are used. Replace %d with %zd. Signed-off-by: Evgeniy Polyakov Signed-off-by: Linus Torvalds --- include/linux/crc16.h | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'include/linux') diff --git a/include/linux/crc16.h b/include/linux/crc16.h index bdedf825b04a..9443c084f881 100644 --- a/include/linux/crc16.h +++ b/include/linux/crc16.h @@ -1,22 +1,11 @@ /* * crc16.h - CRC-16 routine * - * Implements the standard CRC-16, as used with 1-wire devices: + * Implements the standard CRC-16: * Width 16 * Poly 0x8005 (x^16 + x^15 + x^2 + 1) * Init 0 * - * For 1-wire devices, the CRC is stored inverted, LSB-first - * - * Example buffer with the CRC attached: - * 31 32 33 34 35 36 37 38 39 C2 44 - * - * The CRC over a buffer with the CRC attached is 0xB001. - * So, if (crc16(0, buf, size) == 0xB001) then the buffer is valid. - * - * Refer to "Application Note 937: Book of iButton Standards" for details. - * http://www.maxim-ic.com/appnotes.cfm/appnote_number/937 - * * Copyright (c) 2005 Ben Gardner * * This source code is licensed under the GNU General Public License, @@ -28,9 +17,6 @@ #include -#define CRC16_INIT 0 -#define CRC16_VALID 0xb001 - extern u16 const crc16_table[256]; extern u16 crc16(u16 crc, const u8 *buffer, size_t len); -- cgit v1.2.3 From b3426599af9524104be6938bcb1fcaab314781c7 Mon Sep 17 00:00:00 2001 From: Paul Jackson Date: Mon, 12 Sep 2005 04:30:30 -0700 Subject: [PATCH] cpuset semaphore depth check optimize Optimize the deadlock avoidance check on the global cpuset semaphore cpuset_sem. Instead of adding a depth counter to the task struct of each task, rather just two words are enough, one to store the depth and the other the current cpuset_sem holder. Thanks to Nikita Danilov for the idea. Signed-off-by: Paul Jackson [ We may want to change this further, but at least it's now a totally internal decision to the cpusets code ] Signed-off-by: Linus Torvalds --- include/linux/sched.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index ed3bb19d1337..38c8654aaa96 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -785,7 +785,6 @@ struct task_struct { short il_next; #endif #ifdef CONFIG_CPUSETS - short cpuset_sem_nest_depth; struct cpuset *cpuset; nodemask_t mems_allowed; int cpuset_mems_generation; -- cgit v1.2.3 From 3f74478b5fd7263e9311cdb320923d599c73a792 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 12 Sep 2005 18:49:24 +0200 Subject: [PATCH] x86-64: Some cleanup and optimization to the processor data area. - Remove unused irqrsp field - Remove pda->me - Optimize set_softirq_pending slightly Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds --- include/linux/interrupt.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index d99e7aeb7d33..0a90205184b0 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -57,6 +57,11 @@ extern void disable_irq(unsigned int irq); extern void enable_irq(unsigned int irq); #endif +#ifndef __ARCH_SET_SOFTIRQ_PENDING +#define set_softirq_pending(x) (local_softirq_pending() = (x)) +#define or_softirq_pending(x) (local_softirq_pending() |= (x)) +#endif + /* * Temporary defines for UP kernels, until all code gets fixed. */ @@ -123,7 +128,7 @@ struct softirq_action asmlinkage void do_softirq(void); extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data); extern void softirq_init(void); -#define __raise_softirq_irqoff(nr) do { local_softirq_pending() |= 1UL << (nr); } while (0) +#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0) extern void FASTCALL(raise_softirq_irqoff(unsigned int nr)); extern void FASTCALL(raise_softirq(unsigned int nr)); -- cgit v1.2.3 From c47a3167d0454c0af5fb0a0322b01a0e3487798e Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 12 Sep 2005 18:49:25 +0200 Subject: [PATCH] x86-64: Make dmi_find_device for !DMI case inline Otherwise it will generate warnings and be generated many times. Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds --- include/linux/dmi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dmi.h b/include/linux/dmi.h index c30175e8dec6..a415f1d93e9a 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -70,7 +70,7 @@ extern struct dmi_device * dmi_find_device(int type, const char *name, static inline int dmi_check_system(struct dmi_system_id *list) { return 0; } static inline char * dmi_get_system_info(int field) { return NULL; } -static struct dmi_device * dmi_find_device(int type, const char *name, +static inline struct dmi_device * dmi_find_device(int type, const char *name, struct dmi_device *from) { return NULL; } #endif -- cgit v1.2.3