]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 Mar 2014 17:58:10 +0000 (10:58 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 Mar 2014 17:58:10 +0000 (10:58 -0700)
Pull drm fixes from Dave Airlie:
 "I didn't want these to wait for stable cycle.

  The nouveau and radeon ones are the same problem, where the runtime pm
  stuff broke non-runtime pm managed secondary GPUs.

  The udl fix is for an oops on unplug, and the i915 fix is for a
  regression on Sandybridge even though it may break haswell (regression
  wins)"

Daniel Vetter comments:
 "My apologies for the i915 regression fumble, that thing somehow fell
  through the cracks here for almost half a year :( Imo that's more than
  enough flailing to just go ahead with the revert, and the re-broken
  hsw should get peoples attention ..."

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/i915: Undo gtt scratch pte unmapping again
  drm/radeon: fix runtime suspend breaking secondary GPUs
  drm/nouveau: fail runtime pm properly.
  drm/udl: take reference to device struct for dma-bufs

arch/x86/include/asm/pgtable.h
arch/x86/xen/mmu.c
drivers/i2c/busses/i2c-cpm.c
drivers/xen/balloon.c
fs/anon_inodes.c
fs/dcache.c
fs/file.c
fs/namei.c
fs/nfsd/vfs.c
fs/read_write.c
kernel/trace/trace.c

index 5ad38ad07890fc4ca8698aae41c6e60e48a451f4..bbc8b12fa443d47ee9a8faa59b36767e7aec866c 100644 (file)
@@ -445,20 +445,10 @@ static inline int pte_same(pte_t a, pte_t b)
        return a.pte == b.pte;
 }
 
-static inline int pteval_present(pteval_t pteval)
-{
-       /*
-        * Yes Linus, _PAGE_PROTNONE == _PAGE_NUMA. Expressing it this
-        * way clearly states that the intent is that protnone and numa
-        * hinting ptes are considered present for the purposes of
-        * pagetable operations like zapping, protection changes, gup etc.
-        */
-       return pteval & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_NUMA);
-}
-
 static inline int pte_present(pte_t a)
 {
-       return pteval_present(pte_flags(a));
+       return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE |
+                              _PAGE_NUMA);
 }
 
 #define pte_accessible pte_accessible
index 256282e7888b118b02e61d657f78ae8490bf0fe4..2423ef04ffea596fd43eeb918f290003277fbb21 100644 (file)
@@ -365,7 +365,7 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
 /* Assume pteval_t is equivalent to all the other *val_t types. */
 static pteval_t pte_mfn_to_pfn(pteval_t val)
 {
-       if (pteval_present(val)) {
+       if (val & _PAGE_PRESENT) {
                unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
                unsigned long pfn = mfn_to_pfn(mfn);
 
@@ -381,7 +381,7 @@ static pteval_t pte_mfn_to_pfn(pteval_t val)
 
 static pteval_t pte_pfn_to_mfn(pteval_t val)
 {
-       if (pteval_present(val)) {
+       if (val & _PAGE_PRESENT) {
                unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
                pteval_t flags = val & PTE_FLAGS_MASK;
                unsigned long mfn;
index be7f0a20d634d1107a7bb3147b32edf0256546ed..f3b89a4698b6192a24d031bab358796e51fbb767 100644 (file)
@@ -39,7 +39,9 @@
 #include <linux/i2c.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
+#include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <sysdev/fsl_soc.h>
 #include <asm/cpm.h>
index 37d06ea624aa953d40448bcd2a2d4943baf79fa9..61a6ac8fa8fc7ab00dcc7c33cea47981f2509d4b 100644 (file)
@@ -399,11 +399,25 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
                        state = BP_EAGAIN;
                        break;
                }
+               scrub_page(page);
 
-               pfn = page_to_pfn(page);
-               frame_list[i] = pfn_to_mfn(pfn);
+               frame_list[i] = page_to_pfn(page);
+       }
 
-               scrub_page(page);
+       /*
+        * Ensure that ballooned highmem pages don't have kmaps.
+        *
+        * Do this before changing the p2m as kmap_flush_unused()
+        * reads PTEs to obtain pages (and hence needs the original
+        * p2m entry).
+        */
+       kmap_flush_unused();
+
+       /* Update direct mapping, invalidate P2M, and add to balloon. */
+       for (i = 0; i < nr_pages; i++) {
+               pfn = frame_list[i];
+               frame_list[i] = pfn_to_mfn(pfn);
+               page = pfn_to_page(pfn);
 
 #ifdef CONFIG_XEN_HAVE_PVMMU
                /*
@@ -429,11 +443,9 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
                }
 #endif
 
-               balloon_append(pfn_to_page(pfn));
+               balloon_append(page);
        }
 
-       /* Ensure that ballooned highmem pages don't have kmaps. */
-       kmap_flush_unused();
        flush_tlb_all();
 
        set_xen_guest_handle(reservation.extent_start, frame_list);
index 24084732b1d0b264b5c3262796f1ec3dd5fc505f..80ef38c73e5a16af0f9443d94bec3aae700370df 100644 (file)
@@ -41,19 +41,8 @@ static const struct dentry_operations anon_inodefs_dentry_operations = {
 static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
                                int flags, const char *dev_name, void *data)
 {
-       struct dentry *root;
-       root = mount_pseudo(fs_type, "anon_inode:", NULL,
+       return mount_pseudo(fs_type, "anon_inode:", NULL,
                        &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC);
-       if (!IS_ERR(root)) {
-               struct super_block *s = root->d_sb;
-               anon_inode_inode = alloc_anon_inode(s);
-               if (IS_ERR(anon_inode_inode)) {
-                       dput(root);
-                       deactivate_locked_super(s);
-                       root = ERR_CAST(anon_inode_inode);
-               }
-       }
-       return root;
 }
 
 static struct file_system_type anon_inode_fs_type = {
@@ -175,22 +164,15 @@ EXPORT_SYMBOL_GPL(anon_inode_getfd);
 
 static int __init anon_inode_init(void)
 {
-       int error;
-
-       error = register_filesystem(&anon_inode_fs_type);
-       if (error)
-               goto err_exit;
        anon_inode_mnt = kern_mount(&anon_inode_fs_type);
-       if (IS_ERR(anon_inode_mnt)) {
-               error = PTR_ERR(anon_inode_mnt);
-               goto err_unregister_filesystem;
-       }
-       return 0;
+       if (IS_ERR(anon_inode_mnt))
+               panic("anon_inode_init() kernel mount failed (%ld)\n", PTR_ERR(anon_inode_mnt));
 
-err_unregister_filesystem:
-       unregister_filesystem(&anon_inode_fs_type);
-err_exit:
-       panic(KERN_ERR "anon_inode_init() failed (%d)\n", error);
+       anon_inode_inode = alloc_anon_inode(anon_inode_mnt->mnt_sb);
+       if (IS_ERR(anon_inode_inode))
+               panic("anon_inode_init() inode allocation failed (%ld)\n", PTR_ERR(anon_inode_inode));
+
+       return 0;
 }
 
 fs_initcall(anon_inode_init);
index 265e0ce9769c70db65d5f9df11c4365f44c6dd29..ca02c13a84aa24d55b18bbced577ece923605665 100644 (file)
@@ -2833,9 +2833,9 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name)
        u32 dlen = ACCESS_ONCE(name->len);
        char *p;
 
-       if (*buflen < dlen + 1)
-               return -ENAMETOOLONG;
        *buflen -= dlen + 1;
+       if (*buflen < 0)
+               return -ENAMETOOLONG;
        p = *buffer -= dlen + 1;
        *p++ = '/';
        while (dlen--) {
index 60a45e9f53231379c87b9ee75cb64eb8d6d71979..eb56a13dab3ed5561a9521b2b2d1a6000a7158a3 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -713,27 +713,16 @@ unsigned long __fdget_raw(unsigned int fd)
 
 unsigned long __fdget_pos(unsigned int fd)
 {
-       struct files_struct *files = current->files;
-       struct file *file;
-       unsigned long v;
-
-       if (atomic_read(&files->count) == 1) {
-               file = __fcheck_files(files, fd);
-               v = 0;
-       } else {
-               file = __fget(fd, 0);
-               v = FDPUT_FPUT;
-       }
-       if (!file)
-               return 0;
+       unsigned long v = __fdget(fd);
+       struct file *file = (struct file *)(v & ~3);
 
-       if (file->f_mode & FMODE_ATOMIC_POS) {
+       if (file && (file->f_mode & FMODE_ATOMIC_POS)) {
                if (file_count(file) > 1) {
                        v |= FDPUT_POS_UNLOCK;
                        mutex_lock(&file->f_pos_lock);
                }
        }
-       return v | (unsigned long)file;
+       return v;
 }
 
 /*
index 2f730ef9b4b3da78afd6a830c13c7ba13c706ffe..4b491b4319905b2dd6698d3f58aae1d0d0141499 100644 (file)
@@ -1109,7 +1109,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
                        return false;
 
                if (!d_mountpoint(path->dentry))
-                       break;
+                       return true;
 
                mounted = __lookup_mnt(path->mnt, path->dentry);
                if (!mounted)
@@ -1125,20 +1125,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
                 */
                *inode = path->dentry->d_inode;
        }
-       return true;
-}
-
-static void follow_mount_rcu(struct nameidata *nd)
-{
-       while (d_mountpoint(nd->path.dentry)) {
-               struct mount *mounted;
-               mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry);
-               if (!mounted)
-                       break;
-               nd->path.mnt = &mounted->mnt;
-               nd->path.dentry = mounted->mnt.mnt_root;
-               nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
-       }
+       return read_seqretry(&mount_lock, nd->m_seq);
 }
 
 static int follow_dotdot_rcu(struct nameidata *nd)
@@ -1166,7 +1153,17 @@ static int follow_dotdot_rcu(struct nameidata *nd)
                        break;
                nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
        }
-       follow_mount_rcu(nd);
+       while (d_mountpoint(nd->path.dentry)) {
+               struct mount *mounted;
+               mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry);
+               if (!mounted)
+                       break;
+               nd->path.mnt = &mounted->mnt;
+               nd->path.dentry = mounted->mnt.mnt_root;
+               nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
+               if (!read_seqretry(&mount_lock, nd->m_seq))
+                       goto failed;
+       }
        nd->inode = nd->path.dentry->d_inode;
        return 0;
 
index 017d3cb5e99b4391027fe37b7c56c23966754e2d..6d7be3f8035631cb207a5733c71dbfc2f800fa4c 100644 (file)
@@ -449,6 +449,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
        fh_lock(fhp);
        host_err = notify_change(dentry, iap, NULL);
        fh_unlock(fhp);
+       err = nfserrno(host_err);
 
 out_put_write_access:
        if (size_change)
index 54e19b9392dc74381fec154fe3f0ceab32ce9bd8..28cc9c810744a748d3a071b536c36547be87aa14 100644 (file)
@@ -307,7 +307,7 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
                unsigned int, whence)
 {
        int retval;
-       struct fd f = fdget(fd);
+       struct fd f = fdget_pos(fd);
        loff_t offset;
 
        if (!f.file)
@@ -327,7 +327,7 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
                        retval = 0;
        }
 out_putf:
-       fdput(f);
+       fdput_pos(f);
        return retval;
 }
 #endif
index 815c878f409bd94e08777d1b9f83b1553f4a2e24..24c1f23825579df4f2bf46e2dca98e6af8fb4abd 100644 (file)
@@ -1600,15 +1600,31 @@ void trace_buffer_unlock_commit(struct ring_buffer *buffer,
 }
 EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit);
 
+static struct ring_buffer *temp_buffer;
+
 struct ring_buffer_event *
 trace_event_buffer_lock_reserve(struct ring_buffer **current_rb,
                          struct ftrace_event_file *ftrace_file,
                          int type, unsigned long len,
                          unsigned long flags, int pc)
 {
+       struct ring_buffer_event *entry;
+
        *current_rb = ftrace_file->tr->trace_buffer.buffer;
-       return trace_buffer_lock_reserve(*current_rb,
+       entry = trace_buffer_lock_reserve(*current_rb,
                                         type, len, flags, pc);
+       /*
+        * If tracing is off, but we have triggers enabled
+        * we still need to look at the event data. Use the temp_buffer
+        * to store the trace event for the tigger to use. It's recusive
+        * safe and will not be recorded anywhere.
+        */
+       if (!entry && ftrace_file->flags & FTRACE_EVENT_FL_TRIGGER_COND) {
+               *current_rb = temp_buffer;
+               entry = trace_buffer_lock_reserve(*current_rb,
+                                                 type, len, flags, pc);
+       }
+       return entry;
 }
 EXPORT_SYMBOL_GPL(trace_event_buffer_lock_reserve);
 
@@ -6494,11 +6510,16 @@ __init static int tracer_alloc_buffers(void)
 
        raw_spin_lock_init(&global_trace.start_lock);
 
+       /* Used for event triggers */
+       temp_buffer = ring_buffer_alloc(PAGE_SIZE, RB_FL_OVERWRITE);
+       if (!temp_buffer)
+               goto out_free_cpumask;
+
        /* TODO: make the number of buffers hot pluggable with CPUS */
        if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) {
                printk(KERN_ERR "tracer: failed to allocate ring buffer!\n");
                WARN_ON(1);
-               goto out_free_cpumask;
+               goto out_free_temp_buffer;
        }
 
        if (global_trace.buffer_disabled)
@@ -6540,6 +6561,8 @@ __init static int tracer_alloc_buffers(void)
 
        return 0;
 
+out_free_temp_buffer:
+       ring_buffer_free(temp_buffer);
 out_free_cpumask:
        free_percpu(global_trace.trace_buffer.data);
 #ifdef CONFIG_TRACER_MAX_TRACE