From 2001f006114949c25277bc2ff0bde2da211dd481 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 2 Nov 2007 15:14:28 -0500 Subject: [PATCH] --- yaml --- r: 74310 b: refs/heads/master c: bf164410d08dc83df416e3a6a43ab29bf88890ed h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/Makefile | 2 +- trunk/Documentation/DocBook/uio-howto.tmpl | 90 ++++++++++++++-------- trunk/drivers/base/core.c | 4 +- trunk/drivers/base/power/Makefile | 3 +- trunk/drivers/base/power/main.c | 8 +- trunk/drivers/base/power/power.h | 28 ++----- trunk/drivers/char/Kconfig | 2 +- trunk/drivers/pci/pcie/portdrv_pci.c | 2 +- trunk/fs/exec.c | 6 -- trunk/fs/sysfs/file.c | 6 +- trunk/include/linux/sched.h | 4 - trunk/kernel/sched.c | 5 +- trunk/kernel/sched_debug.c | 8 +- trunk/kernel/sched_stats.h | 3 +- trunk/kernel/time/tick-sched.c | 2 - trunk/lib/kobject.c | 4 +- trunk/mm/page_alloc.c | 1 + trunk/mm/shmem.c | 5 +- 19 files changed, 92 insertions(+), 93 deletions(-) diff --git a/[refs] b/[refs] index 19b8979f3ae7..13ae32019b44 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cae2f9c46d69edb1aee565917735d79aba3a3267 +refs/heads/master: bf164410d08dc83df416e3a6a43ab29bf88890ed diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile index 4953bc258729..054a7ecf64c6 100644 --- a/trunk/Documentation/DocBook/Makefile +++ b/trunk/Documentation/DocBook/Makefile @@ -11,7 +11,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ procfs-guide.xml writing_usb_driver.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ - genericirq.xml s390-drivers.xml uio-howto.xml + genericirq.xml s390-drivers.xml ### # The build process is as follows (targets): diff --git a/trunk/Documentation/DocBook/uio-howto.tmpl b/trunk/Documentation/DocBook/uio-howto.tmpl index fdd7f4f887b7..c119484258b8 100644 --- a/trunk/Documentation/DocBook/uio-howto.tmpl +++ b/trunk/Documentation/DocBook/uio-howto.tmpl @@ -29,12 +29,6 @@ - - 0.4 - 2007-11-26 - hjk - Removed section about uio_dummy. - 0.3 2007-04-29 @@ -100,26 +94,6 @@ interested in translating it, please email me user space. This simplifies development and reduces the risk of serious bugs within a kernel module. - - Please note that UIO is not an universal driver interface. Devices - that are already handled well by other kernel subsystems (like - networking or serial or USB) are no candidates for an UIO driver. - Hardware that is ideally suited for an UIO driver fulfills all of - the following: - - - - The device has memory that can be mapped. The device can be - controlled completely by writing to this memory. - - - The device usually generates interrupts. - - - The device does not fit into one of the standard kernel - subsystems. - - @@ -200,9 +174,8 @@ interested in translating it, please email me For cards that don't generate interrupts but need to be polled, there is the possibility to set up a timer that triggers the interrupt handler at configurable time intervals. - This interrupt simulation is done by calling - uio_event_notify() - from the timer's event handler. + See drivers/uio/uio_dummy.c for an + example of this technique. @@ -290,11 +263,63 @@ offset = N * getpagesize(); + + +Using uio_dummy + + Well, there is no real use for uio_dummy. Its only purpose is + to test most parts of the UIO system (everything except + hardware interrupts), and to serve as an example for the + kernel module that you will have to write yourself. + + + +What uio_dummy does + + The kernel module uio_dummy.ko creates a + device that uses a timer to generate periodic interrupts. The + interrupt handler does nothing but increment a counter. The + driver adds two custom attributes, count + and freq, that appear under + /sys/devices/platform/uio_dummy/. + + + + The attribute count can be read and + written. The associated file + /sys/devices/platform/uio_dummy/count + appears as a normal text file and contains the total number of + timer interrupts. If you look at it (e.g. using + cat), you'll notice it is slowly counting + up. + + + + The attribute freq can be read and written. + The content of + /sys/devices/platform/uio_dummy/freq + represents the number of system timer ticks between two timer + interrupts. The default value of freq is + the value of the kernel variable HZ, which + gives you an interval of one second. Lower values will + increase the frequency. Try the following: + + +cd /sys/devices/platform/uio_dummy/ +echo 100 > freq + + + Use cat count to see how the interrupt + frequency changes. + + + + Writing your own kernel module - Please have a look at uio_cif.c as an + Please have a look at uio_dummy.c as an example. The following paragraphs explain the different sections of this file. @@ -329,8 +354,9 @@ See the description below for details. interrupt, it's your modules task to determine the irq number during initialization. If you don't have a hardware generated interrupt but want to trigger the interrupt handler in some other way, set -irq to UIO_IRQ_CUSTOM. -If you had no interrupt at all, you could set +irq to UIO_IRQ_CUSTOM. The +uio_dummy module does this as it triggers the event mechanism in a timer +routine. If you had no interrupt at all, you could set irq to UIO_IRQ_NONE, though this rarely makes sense. diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index 2683eac30c68..3f4d6aa13990 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -770,10 +770,9 @@ int device_add(struct device *dev) error = device_add_attrs(dev); if (error) goto AttrsError; - error = dpm_sysfs_add(dev); + error = device_pm_add(dev); if (error) goto PMError; - device_pm_add(dev); error = bus_add_device(dev); if (error) goto BusError; @@ -798,7 +797,6 @@ int device_add(struct device *dev) return error; BusError: device_pm_remove(dev); - dpm_sysfs_remove(dev); PMError: if (dev->bus) blocking_notifier_call_chain(&dev->bus->bus_notifier, diff --git a/trunk/drivers/base/power/Makefile b/trunk/drivers/base/power/Makefile index 44504e6618fb..a803733c839e 100644 --- a/trunk/drivers/base/power/Makefile +++ b/trunk/drivers/base/power/Makefile @@ -1,6 +1,5 @@ obj-y := shutdown.o -obj-$(CONFIG_PM) += sysfs.o -obj-$(CONFIG_PM_SLEEP) += main.o +obj-$(CONFIG_PM_SLEEP) += main.o sysfs.o obj-$(CONFIG_PM_TRACE) += trace.o ifeq ($(CONFIG_DEBUG_DRIVER),y) diff --git a/trunk/drivers/base/power/main.c b/trunk/drivers/base/power/main.c index 691ffb64cc37..0ab4ab21f564 100644 --- a/trunk/drivers/base/power/main.c +++ b/trunk/drivers/base/power/main.c @@ -38,14 +38,20 @@ static DEFINE_MUTEX(dpm_list_mtx); int (*platform_enable_wakeup)(struct device *dev, int is_on); -void device_pm_add(struct device *dev) +int device_pm_add(struct device *dev) { + int error; + pr_debug("PM: Adding info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", kobject_name(&dev->kobj)); mutex_lock(&dpm_list_mtx); list_add_tail(&dev->power.entry, &dpm_active); + error = dpm_sysfs_add(dev); + if (error) + list_del(&dev->power.entry); mutex_unlock(&dpm_list_mtx); + return error; } void device_pm_remove(struct device *dev) diff --git a/trunk/drivers/base/power/power.h b/trunk/drivers/base/power/power.h index 379da4e958e0..5c4efd493fa5 100644 --- a/trunk/drivers/base/power/power.h +++ b/trunk/drivers/base/power/power.h @@ -13,29 +13,14 @@ extern void device_shutdown(void); extern struct list_head dpm_active; /* The active device list */ -static inline struct device *to_device(struct list_head *entry) +static inline struct device * to_device(struct list_head * entry) { return container_of(entry, struct device, power.entry); } -extern void device_pm_add(struct device *); +extern int device_pm_add(struct device *); extern void device_pm_remove(struct device *); -#else /* CONFIG_PM_SLEEP */ - - -static inline void device_pm_add(struct device *dev) -{ -} - -static inline void device_pm_remove(struct device *dev) -{ -} - -#endif - -#ifdef CONFIG_PM - /* * sysfs.c */ @@ -43,15 +28,16 @@ static inline void device_pm_remove(struct device *dev) extern int dpm_sysfs_add(struct device *); extern void dpm_sysfs_remove(struct device *); -#else /* CONFIG_PM */ +#else /* CONFIG_PM_SLEEP */ + -static inline int dpm_sysfs_add(struct device *dev) +static inline int device_pm_add(struct device * dev) { return 0; } - -static inline void dpm_sysfs_remove(struct device *dev) +static inline void device_pm_remove(struct device * dev) { + } #endif diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index a509b8d79781..bf18d757b876 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -457,7 +457,7 @@ config LEGACY_PTYS config LEGACY_PTY_COUNT int "Maximum number of legacy PTY in use" depends on LEGACY_PTYS - range 0 256 + range 1 256 default "256" ---help--- The maximum number of legacy PTYs that can be used at any one time. diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index df383645e366..26057f98f72e 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -217,7 +217,7 @@ static int slot_reset_iter(struct device *device, void *data) static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) { - pci_ers_result_t status; + pci_ers_result_t status = PCI_ERS_RESULT_NONE; int retval; /* If fatal, restore cfg space for possible link reset at upstream */ diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 282240afe99e..4ccaaa4b13b2 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -1780,12 +1780,6 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) but keep the previous behaviour for now. */ if (!ispipe && !S_ISREG(inode->i_mode)) goto close_fail; - /* - * Dont allow local users get cute and trick others to coredump - * into their pre-created files: - */ - if (inode->i_uid != current->fsuid) - goto close_fail; if (!file->f_op) goto close_fail; if (!file->f_op->write) diff --git a/trunk/fs/sysfs/file.c b/trunk/fs/sysfs/file.c index 4045bdcc4b33..27d1785b7644 100644 --- a/trunk/fs/sysfs/file.c +++ b/trunk/fs/sysfs/file.c @@ -119,11 +119,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer sysfs_put_active_two(attr_sd); - /* - * The code works fine with PAGE_SIZE return but it's likely to - * indicate truncated result or overflow in normal use cases. - */ - BUG_ON(count >= (ssize_t)PAGE_SIZE); + BUG_ON(count > (ssize_t)PAGE_SIZE); if (count >= 0) { buffer->needs_read_fill = 0; buffer->count = count; diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index ac3d496fbd20..ee800e7a70de 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -282,10 +282,6 @@ static inline void touch_all_softlockup_watchdogs(void) /* Attach to any functions which should be ignored in wchan output. */ #define __sched __attribute__((__section__(".sched.text"))) - -/* Linker adds these: start and end of __sched functions */ -extern char __sched_text_start[], __sched_text_end[]; - /* Is this address in the __sched functions? */ extern int in_sched_functions(unsigned long addr); diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 98dcdf272db3..38933cafea8a 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -5466,7 +5466,7 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd) return table; } -static ctl_table *sd_alloc_ctl_cpu_table(int cpu) +static ctl_table * sd_alloc_ctl_cpu_table(int cpu) { struct ctl_table *entry, *table; struct sched_domain *sd; @@ -6708,6 +6708,9 @@ void __init sched_init_smp(void) int in_sched_functions(unsigned long addr) { + /* Linker adds these: start and end of __sched functions */ + extern char __sched_text_start[], __sched_text_end[]; + return in_lock_functions(addr) || (addr >= (unsigned long)__sched_text_start && addr < (unsigned long)__sched_text_end); diff --git a/trunk/kernel/sched_debug.c b/trunk/kernel/sched_debug.c index d30467b47ddd..5d0d623a5465 100644 --- a/trunk/kernel/sched_debug.c +++ b/trunk/kernel/sched_debug.c @@ -327,12 +327,10 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m) avg_atom = -1LL; avg_per_cpu = p->se.sum_exec_runtime; - if (p->se.nr_migrations) { - avg_per_cpu = div64_64(avg_per_cpu, - p->se.nr_migrations); - } else { + if (p->se.nr_migrations) + avg_per_cpu = div64_64(avg_per_cpu, p->se.nr_migrations); + else avg_per_cpu = -1LL; - } __PN(avg_atom); __PN(avg_per_cpu); diff --git a/trunk/kernel/sched_stats.h b/trunk/kernel/sched_stats.h index 5b32433e7ee5..630178e53bb6 100644 --- a/trunk/kernel/sched_stats.h +++ b/trunk/kernel/sched_stats.h @@ -52,8 +52,7 @@ static int show_schedstat(struct seq_file *seq, void *v) sd->lb_nobusyq[itype], sd->lb_nobusyg[itype]); } - seq_printf(seq, - " %u %u %u %u %u %u %u %u %u %u %u %u\n", + seq_printf(seq, " %u %u %u %u %u %u %u %u %u %u %u %u\n", sd->alb_count, sd->alb_failed, sd->alb_pushed, sd->sbe_count, sd->sbe_balanced, sd->sbe_pushed, sd->sbf_count, sd->sbf_balanced, sd->sbf_pushed, diff --git a/trunk/kernel/time/tick-sched.c b/trunk/kernel/time/tick-sched.c index cb89fa8db110..27a2338deb4a 100644 --- a/trunk/kernel/time/tick-sched.c +++ b/trunk/kernel/time/tick-sched.c @@ -133,8 +133,6 @@ void tick_nohz_update_jiffies(void) if (!ts->tick_stopped) return; - touch_softlockup_watchdog(); - cpu_clear(cpu, nohz_cpu_mask); now = ktime_get(); diff --git a/trunk/lib/kobject.c b/trunk/lib/kobject.c index b52e9f4ef371..a7e3bf4d3c70 100644 --- a/trunk/lib/kobject.c +++ b/trunk/lib/kobject.c @@ -313,8 +313,8 @@ int kobject_rename(struct kobject * kobj, const char *new_name) struct kobject *temp_kobj; temp_kobj = kset_find_obj(kobj->kset, new_name); if (temp_kobj) { - printk(KERN_WARNING "kobject '%s' cannot be renamed " - "to '%s' as '%s' is already in existence.\n", + printk(KERN_WARNING "kobject '%s' can not be renamed " + "to '%s' as '%s' is already in existance.\n", kobject_name(kobj), new_name, new_name); kobject_put(temp_kobj); return -EINVAL; diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 4ffed1cd158b..12376ae3f733 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -305,6 +305,7 @@ static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags) { int i; + VM_BUG_ON((gfp_flags & (__GFP_WAIT | __GFP_HIGHMEM)) == __GFP_HIGHMEM); /* * clear_highpage() will use KM_USER0, so it's a bug to use __GFP_ZERO * and __GFP_HIGHMEM from hard or soft interrupt context. diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index 51b3d6ccddab..253d205914ba 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -1072,7 +1072,7 @@ shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info, pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx); pvma.vm_pgoff = idx; pvma.vm_end = PAGE_SIZE; - page = alloc_page_vma(gfp, &pvma, 0); + page = alloc_page_vma(gfp | __GFP_ZERO, &pvma, 0); mpol_free(pvma.vm_policy); return page; } @@ -1093,7 +1093,7 @@ shmem_swapin(struct shmem_inode_info *info,swp_entry_t entry,unsigned long idx) static inline struct page * shmem_alloc_page(gfp_t gfp,struct shmem_inode_info *info, unsigned long idx) { - return alloc_page(gfp); + return alloc_page(gfp | __GFP_ZERO); } #endif @@ -1306,7 +1306,6 @@ static int shmem_getpage(struct inode *inode, unsigned long idx, info->alloced++; spin_unlock(&info->lock); - clear_highpage(filepage); flush_dcache_page(filepage); SetPageUptodate(filepage); }