- Merge SLE11-SP3 rpm-3.0.76-0.11-167-g92d1972

- Fix LOCK_STAT build bug while here.
- patches.rt/0349-fs-dentry-use-seqlock.patch

suse-commit: 82ddc307ddc3fad0d5612522a290b606788ce5d1
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index b7edde3..608fc2e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -904,11 +904,11 @@
 		return NULL;
 
 	if (pt->misc & DRM_EDID_PT_STEREO) {
-		printk(KERN_WARNING "stereo mode not supported\n");
+		DRM_DEBUG_KMS("stereo mode not supported\n");
 		return NULL;
 	}
 	if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) {
-		printk(KERN_WARNING "composite sync not supported\n");
+		DRM_DEBUG_KMS("composite sync not supported\n");
 	}
 
 	/* it is incorrect if hsync/vsync width is zero */
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 18d80cc..42cccce 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -16994,10 +16994,13 @@
 	tg3_full_unlock(tp);
 
 done:
-	if (state == pci_channel_io_perm_failure)
+	if (state == pci_channel_io_perm_failure) {
+		tg3_napi_enable(tp);
+		dev_close(netdev);
 		err = PCI_ERS_RESULT_DISCONNECT;
-	else
+	} else {
 		pci_disable_device(pdev);
+	}
 
 	rtnl_unlock();
 
@@ -17043,6 +17046,10 @@
 	rc = PCI_ERS_RESULT_RECOVERED;
 
 done:
+	if (rc != PCI_ERS_RESULT_RECOVERED && netif_running(netdev)) {
+		tg3_napi_enable(tp);
+		dev_close(netdev);
+	}
 	rtnl_unlock();
 
 	return rc;
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 23e7503..84d3a6b 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -356,14 +356,14 @@
 		/* HP Probook 445 */
 		.ident = "HP ProBook 445",
 		.matches = {
-			DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 445 G1 Notebook PC"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 445 G1"),
 		},
 	},
 	{
 		/* HP Probook 455 */
 		.ident = "HP ProBook 455",
 		.matches = {
-			DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 455 G1 Notebook PC"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 455 G1"),
 		},
 	},
 	{} /* terminating entry */
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index acf4eac..dbfc0e1 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -876,6 +876,8 @@
 		return SCSI_DH_RETRY;
 	}
 	switch (pg->state) {
+	case TPGS_STATE_OPTIMIZED:
+		return SCSI_DH_OK;
 	case TPGS_STATE_NONOPTIMIZED:
 		if ((pg->flags & ALUA_OPTIMIZE_STPG) &&
 		    (!pg->pref) &&
@@ -890,10 +892,11 @@
 		break;
 	case TPGS_STATE_TRANSITIONING:
 		return SCSI_DH_RETRY;
-		break;
 	default:
+		sdev_printk(KERN_INFO, sdev,
+			    "%s: stpg failed, unhandled TPGS state %d",
+			    ALUA_DH_NAME, pg->state);
 		return SCSI_DH_NOSYS;
-		break;
 	}
 	retval = submit_stpg(sdev, pg->group_id, sense);
 
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index e33741a..74ef935 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -571,6 +571,20 @@
 		},
 		.driver_data = (void *)64,
 	},
+	{
+		/* HP EliteBook 8580 */
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8580w"),
+		},
+		.driver_data = (void *)64,
+	},
+        {
+                /* HP EliteBook 8780 */
+                .matches = {
+                        DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8780w"),
+                },
+                .driver_data = (void *)64,
+        },
 	{ }
 };
 
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index c9d9421..e38f37e 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -85,25 +85,21 @@
 {
 	struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb);
 	struct list_head *next;
-	struct dentry *p, *q;
+	struct dentry *q;
 
 	spin_lock(&sbi->lookup_lock);
+	seq_spin_lock(&root->d_lock);
 
-	if (prev == NULL) {
-		seq_spin_lock(&root->d_lock);
+	if (prev)
+		next = prev->d_u.d_child.next;
+	else {
 		prev = dget_dlock(root);
 		next = prev->d_subdirs.next;
-		p = prev;
-		goto start;
 	}
 
-	p = prev;
-	seq_spin_lock(&p->d_lock);
-again:
-	next = p->d_u.d_child.next;
-start:
+cont:
 	if (next == &root->d_subdirs) {
-		seq_spin_unlock(&p->d_lock);
+		seq_spin_unlock(&root->d_lock);
 		spin_unlock(&sbi->lookup_lock);
 		dput(prev);
 		return NULL;
@@ -112,16 +108,15 @@
 	q = list_entry(next, struct dentry, d_u.d_child);
 
 	seq_spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED);
-	/* Negative dentry - try next */
-	if (!simple_positive(q)) {
-		seq_spin_unlock(&p->d_lock);
-		lock_set_subclass(&q->d_lock.dep_map, 0, _RET_IP_);
-		p = q;
-		goto again;
+	/* Already gone or negative dentry (under construction) - try next */
+	if (q->d_count == 0 || !simple_positive(q)) {
+		seq_spin_unlock(&q->d_lock);
+		next = q->d_u.d_child.next;
+		goto cont;
 	}
 	dget_dlock(q);
 	seq_spin_unlock(&q->d_lock);
-	seq_spin_unlock(&p->d_lock);
+	seq_spin_unlock(&root->d_lock);
 	spin_unlock(&sbi->lookup_lock);
 
 	dput(prev);
@@ -178,7 +173,7 @@
 	/* Negative dentry - try next */
 	if (!simple_positive(ret)) {
 		seq_spin_unlock(&p->d_lock);
-		lock_set_subclass(&ret->d_lock.dep_map, 0, _RET_IP_);
+		lock_set_subclass(&ret->d_lock.lock.dep_map, 0, _RET_IP_);
 		p = ret;
 		goto again;
 	}
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 2ee75c7..918048e 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1441,7 +1441,6 @@
 	int do_barriers;
 	int closing;
 	int log_root_recovering;
-	int enospc_unlink;
 	int trans_no_join;
 
 	u64 total_pinned;
@@ -3090,6 +3089,9 @@
 int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
 			    struct btrfs_block_rsv *dst_rsv,
 			    u64 num_bytes);
+int btrfs_cond_migrate_bytes(struct btrfs_fs_info *fs_info,
+			     struct btrfs_block_rsv *dest, u64 num_bytes,
+			     int min_factor);
 void btrfs_block_rsv_release(struct btrfs_root *root,
 			     struct btrfs_block_rsv *block_rsv,
 			     u64 num_bytes);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index c55ef57..c6efd22 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4234,6 +4234,31 @@
 	spin_unlock(&block_rsv->lock);
 }
 
+int btrfs_cond_migrate_bytes(struct btrfs_fs_info *fs_info,
+			     struct btrfs_block_rsv *dest, u64 num_bytes,
+			     int min_factor)
+{
+	struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
+	u64 min_bytes;
+
+	if (global_rsv->space_info != dest->space_info)
+		return -ENOSPC;
+
+	spin_lock(&global_rsv->lock);
+	min_bytes = div_factor(global_rsv->size, min_factor);
+	if (global_rsv->reserved < min_bytes + num_bytes) {
+		spin_unlock(&global_rsv->lock);
+		return -ENOSPC;
+	}
+	global_rsv->reserved -= num_bytes;
+	if (global_rsv->reserved < global_rsv->size)
+		global_rsv->full = 0;
+	spin_unlock(&global_rsv->lock);
+
+	block_rsv_add_bytes(dest, num_bytes, 1);
+	return 0;
+}
+
 static void block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
 				    struct btrfs_block_rsv *block_rsv,
 				    struct btrfs_block_rsv *dest, u64 num_bytes)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index ded94b2..5d9357b 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3642,53 +3642,20 @@
 	}
 	return ret;
 }
-		
-
-/* helper to check if there is any shared block in the path */
-static int check_path_shared(struct btrfs_root *root,
-			     struct btrfs_path *path)
-{
-	struct extent_buffer *eb;
-	int level;
-	u64 refs = 1;
-
-	for (level = 0; level < BTRFS_MAX_LEVEL; level++) {
-		int ret;
-
-		if (!path->nodes[level])
-			break;
-		eb = path->nodes[level];
-		if (!btrfs_block_can_be_shared(root, eb))
-			continue;
-		ret = btrfs_lookup_extent_info(NULL, root, eb->start, eb->len,
-					       &refs, NULL);
-		if (refs > 1)
-			return 1;
-	}
-	return 0;
-}
 
 /*
  * helper to start transaction for unlink and rmdir.
  *
- * unlink and rmdir are special in btrfs, they do not always free space.
- * so in enospc case, we should make sure they will free space before
- * allowing them to use the global metadata reservation.
+ * unlink and rmdir are special in btrfs, they do not always free space, so
+ * if we cannot make our reservations the normal way try and see if there is
+ * plenty of slack room in the global reserve to migrate, otherwise we cannot
+ * allow the unlink to occur.
  */
-static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
-						       struct dentry *dentry)
+static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir)
 {
 	struct btrfs_trans_handle *trans;
 	struct btrfs_root *root = BTRFS_I(dir)->root;
-	struct btrfs_path *path;
-	struct btrfs_dir_item *di;
-	struct inode *inode = dentry->d_inode;
-	u64 index;
-	int check_link = 1;
-	int err = -ENOSPC;
 	int ret;
-	u64 ino = btrfs_ino(inode);
-	u64 dir_ino = btrfs_ino(dir);
 
 	/*
 	 * 1 for the possible orphan item
@@ -3701,158 +3668,23 @@
 	if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC)
 		return trans;
 
-	if (ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)
-		return ERR_PTR(-ENOSPC);
+	if (PTR_ERR(trans) == -ENOSPC) {
+		u64 num_bytes = btrfs_calc_trans_metadata_size(root, 5);
 
-	/* check if there is someone else holds reference */
-	if (S_ISDIR(inode->i_mode) && atomic_read(&inode->i_count) > 1)
-		return ERR_PTR(-ENOSPC);
-
-	if (atomic_read(&inode->i_count) > 2)
-		return ERR_PTR(-ENOSPC);
-
-	if (xchg(&root->fs_info->enospc_unlink, 1))
-		return ERR_PTR(-ENOSPC);
-
-	path = btrfs_alloc_path();
-	if (!path) {
-		root->fs_info->enospc_unlink = 0;
-		return ERR_PTR(-ENOMEM);
-	}
-
-	/* 1 for the orphan item */
-	trans = btrfs_start_transaction(root, 1);
-	if (IS_ERR(trans)) {
-		btrfs_free_path(path);
-		root->fs_info->enospc_unlink = 0;
-		return trans;
-	}
-
-	path->skip_locking = 1;
-	path->search_commit_root = 1;
-
-	ret = btrfs_lookup_inode(trans, root, path,
-				&BTRFS_I(dir)->location, 0);
-	if (ret < 0) {
-		err = ret;
-		goto out;
-	}
-	if (ret == 0) {
-		if (check_path_shared(root, path))
-			goto out;
-	} else {
-		check_link = 0;
-	}
-	btrfs_release_path(path);
-
-	ret = btrfs_lookup_inode(trans, root, path,
-				&BTRFS_I(inode)->location, 0);
-	if (ret < 0) {
-		err = ret;
-		goto out;
-	}
-	if (ret == 0) {
-		if (check_path_shared(root, path))
-			goto out;
-	} else {
-		check_link = 0;
-	}
-	btrfs_release_path(path);
-
-	if (ret == 0 && S_ISREG(inode->i_mode)) {
-		ret = btrfs_lookup_file_extent(trans, root, path,
-					       ino, (u64)-1, 0);
-		if (ret < 0) {
-			err = ret;
-			goto out;
+		trans = btrfs_start_transaction(root, 0);
+		if (IS_ERR(trans))
+			return trans;
+		ret = btrfs_cond_migrate_bytes(root->fs_info,
+					       &root->fs_info->trans_block_rsv,
+					       num_bytes, 5);
+		if (ret) {
+			btrfs_end_transaction(trans, root);
+			return ERR_PTR(ret);
 		}
-		BUG_ON(ret == 0); /* Corruption */
-		if (check_path_shared(root, path))
-			goto out;
-		btrfs_release_path(path);
-	}
-
-	if (!check_link) {
-		err = 0;
-		goto out;
-	}
-
-	di = btrfs_lookup_dir_item(trans, root, path, dir_ino,
-				dentry->d_name.name, dentry->d_name.len, 0);
-	if (IS_ERR(di)) {
-		err = PTR_ERR(di);
-		goto out;
-	}
-	if (di) {
-		if (check_path_shared(root, path))
-			goto out;
-	} else {
-		err = 0;
-		goto out;
-	}
-	btrfs_release_path(path);
-
-	ret = btrfs_get_inode_ref_index(trans, root, path, dentry->d_name.name,
-					dentry->d_name.len, ino, dir_ino, 0,
-					&index);
-	if (ret) {
-		err = ret;
-		goto out;
-	}
-
-	if (check_path_shared(root, path))
-		goto out;
-
-	btrfs_release_path(path);
-
-	/*
-	 * This is a commit root search, if we can lookup inode item and other
-	 * relative items in the commit root, it means the transaction of
-	 * dir/file creation has been committed, and the dir index item that we
-	 * delay to insert has also been inserted into the commit root. So
-	 * we needn't worry about the delayed insertion of the dir index item
-	 * here.
-	 */
-	di = btrfs_lookup_dir_index_item(trans, root, path, dir_ino, index,
-				dentry->d_name.name, dentry->d_name.len, 0);
-	if (IS_ERR(di)) {
-		err = PTR_ERR(di);
-		goto out;
-	}
-	BUG_ON(ret == -ENOENT);
-	if (check_path_shared(root, path))
-		goto out;
-
-	err = 0;
-out:
-	btrfs_free_path(path);
-	/* Migrate the orphan reservation over */
-	if (!err)
-		err = btrfs_block_rsv_migrate(trans->block_rsv,
-				&root->fs_info->global_block_rsv,
-				trans->bytes_reserved);
-
-	if (err) {
-		btrfs_end_transaction(trans, root);
-		root->fs_info->enospc_unlink = 0;
-		return ERR_PTR(err);
-	}
-
-	trans->block_rsv = &root->fs_info->global_block_rsv;
-	return trans;
-}
-
-static void __unlink_end_trans(struct btrfs_trans_handle *trans,
-			       struct btrfs_root *root)
-{
-	if (trans->block_rsv->type == BTRFS_BLOCK_RSV_GLOBAL) {
-		btrfs_block_rsv_release(root, trans->block_rsv,
-					trans->bytes_reserved);
 		trans->block_rsv = &root->fs_info->trans_block_rsv;
-		BUG_ON(!root->fs_info->enospc_unlink);
-		root->fs_info->enospc_unlink = 0;
+		trans->bytes_reserved = num_bytes;
 	}
-	btrfs_end_transaction(trans, root);
+	return trans;
 }
 
 static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
@@ -3862,7 +3694,7 @@
 	struct inode *inode = dentry->d_inode;
 	int ret;
 
-	trans = __unlink_start_trans(dir, dentry);
+	trans = __unlink_start_trans(dir);
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
@@ -3880,7 +3712,7 @@
 	}
 
 out:
-	__unlink_end_trans(trans, root);
+	btrfs_end_transaction(trans, root);
 	btrfs_btree_balance_dirty(root);
 	return ret;
 }
@@ -3977,7 +3809,7 @@
 	if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID)
 		return -EPERM;
 
-	trans = __unlink_start_trans(dir, dentry);
+	trans = __unlink_start_trans(dir);
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
@@ -3999,7 +3831,7 @@
 	if (!err)
 		btrfs_i_size_write(inode, 0);
 out:
-	__unlink_end_trans(trans, root);
+	btrfs_end_transaction(trans, root);
 	btrfs_btree_balance_dirty(root);
 
 	return err;
diff --git a/fs/exec.c b/fs/exec.c
index a215e7a..e60a029 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -56,6 +56,8 @@
 #include <linux/oom.h>
 #include <linux/compat.h>
 
+#include <trace/events/fs-open.h>
+
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/tlb.h>
@@ -140,6 +142,8 @@
 
 	fsnotify_open(file);
 
+	trace_uselib(file);
+
 	error = -ENOEXEC;
 	if(file->f_op) {
 		struct linux_binfmt * fmt;
@@ -789,6 +793,8 @@
 
 	fsnotify_open(file);
 
+	trace_open_exec(file);
+
 	if (file->f_op && file->f_op->open_exec) {
 		err = file->f_op->open_exec(file->f_path.dentry->d_inode);
 		if (err)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 72a226f..15e9afd 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -245,6 +245,8 @@
 	return ret;
 }
 
+extern struct super_block *blockdev_superblock;
+
 /*
  * Move expired dirty inodes from @delaying_queue to @dispatch_queue.
  */
@@ -263,10 +265,12 @@
 		if (older_than_this &&
 		    inode_dirtied_after(inode, *older_than_this))
 			break;
+		list_move(&inode->i_wb_list, &tmp);
+		if (inode->i_sb == blockdev_superblock)
+			continue;
 		if (sb && sb != inode->i_sb)
 			do_sb_sort = 1;
 		sb = inode->i_sb;
-		list_move(&inode->i_wb_list, &tmp);
 	}
 
 	/* just one sb in list, splice to dispatch_queue and we're done */
@@ -301,7 +305,14 @@
 {
 	assert_spin_locked(&wb->list_lock);
 	list_splice_init(&wb->b_more_io, &wb->b_io);
-	move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this);
+	/*
+	 * If we want all inodes and we don't have to sort superblocks, just
+	 * splice the list
+	 */
+	if (!older_than_this && !test_bit(BDI_multiple_sb, &wb->bdi->state))
+		list_splice_init(&wb->b_dirty, &wb->b_io);
+	else
+		move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this);
 }
 
 static int write_inode(struct inode *inode, struct writeback_control *wbc)
@@ -517,6 +528,15 @@
 		struct inode *inode = wb_inode(wb->b_io.prev);
 
 		if (inode->i_sb != sb) {
+			/*
+			 * Really two different filesystem superblocks? Mark
+			 * the bdi as such so that we sort inodes by sb from
+			 * now on.
+			 */
+			if (inode->i_sb != blockdev_superblock &&
+			    sb != blockdev_superblock &&
+			    !test_bit(BDI_multiple_sb, &wb->bdi->state))
+				set_bit(BDI_multiple_sb, &wb->bdi->state);
 			if (only_this_sb) {
 				/*
 				 * We only want to write back data for this
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
index a3385b6..7d927cd 100644
--- a/fs/ocfs2/journal.h
+++ b/fs/ocfs2/journal.h
@@ -538,7 +538,7 @@
 	extent_blocks = 1 + 1 + le16_to_cpu(root_el->l_tree_depth);
 
 	return bitmap_blocks + sysfile_bitmap_blocks + extent_blocks +
-	       ocfs2_quota_trans_credits(sb);
+	       ocfs2_quota_trans_credits(sb) + bits_wanted;
 }
 
 static inline int ocfs2_calc_symlink_credits(struct super_block *sb)
diff --git a/fs/open.c b/fs/open.c
index bf00a86..9c72cfa 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -33,6 +33,9 @@
 
 #include "internal.h"
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/fs-open.h>
+
 int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
 	struct file *filp)
 {
@@ -1006,6 +1009,7 @@
 			} else {
 				fsnotify_open(f);
 				fd_install(fd, f);
+				trace_do_sys_open(f, flags, mode);
 			}
 		}
 		putname(tmp);
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 304af69..c1f07a8 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -32,6 +32,7 @@
 	BDI_sync_congested,	/* The sync queue is getting full */
 	BDI_registered,		/* bdi_register() was done */
 	BDI_writeback_running,	/* Writeback is in progress */
+	BDI_multiple_sb,	/* Multiple superblocks belong to this bdi */
 	BDI_unused,		/* Available bits start here */
 };
 
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 94cd46c..e60c821 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -256,6 +256,10 @@
 
 int trace_set_clr_event(const char *system, const char *event, int set);
 
+/* file pointer helpers */
+extern int  ftrace_file_name_len (const struct file *f);
+extern void ftrace_assign_file   (char *dest, int dest_len, const struct file *f);
+
 /*
  * The double __builtin_constant_p is because gcc will give us an error
  * if we try to allocate the static variable to fmt if it is not a
diff --git a/include/trace/events/fs-open.h b/include/trace/events/fs-open.h
new file mode 100644
index 0000000..32633e5
--- /dev/null
+++ b/include/trace/events/fs-open.h
@@ -0,0 +1,66 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM fs-open
+
+#if !defined(_TRACE_FS_OPEN_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_FS_OPEN_H
+
+#include <linux/fs.h>
+#include <linux/tracepoint.h>
+
+/*
+ * Here we have a problem; the __string macro uses __dynamic_array,
+ * which requires the ability to know it's own length before we
+ * allocate the buffer - in the get_offsets_ call - which does not
+ * know the length of the resulting path we create in TP_fast_assign.
+ * So - give up and use a fixed length.
+ */
+TRACE_EVENT(do_sys_open,
+
+	TP_PROTO(struct file *filp, int flags, int mode),
+
+	TP_ARGS(filp, flags, mode),
+
+	TP_STRUCT__entry(
+		__file_p(	filename, filp			)
+		__field(	int, flags			)
+		__field(	int, mode			)
+	),
+
+	TP_fast_assign(
+		__assign_file_p(filename, filp);
+		__entry->flags = flags;
+		__entry->mode = mode;
+	),
+
+	TP_printk("\"%s\" %x %o", __get_str(filename),
+		  __entry->flags, __entry->mode)
+);
+
+TRACE_EVENT(uselib,
+	TP_PROTO(struct file *filp),
+	TP_ARGS(filp),
+	TP_STRUCT__entry(
+		__file_p(filename, filp)
+	),
+	TP_fast_assign(
+		__assign_file_p(filename, filp);
+	),
+	TP_printk("\"%s\"", __get_str(filename))
+);
+
+TRACE_EVENT(open_exec,
+	TP_PROTO(struct file *filp),
+	TP_ARGS(filp),
+	TP_STRUCT__entry(
+		__file_p(filename, filp)
+	),
+	TP_fast_assign(
+		__assign_file_p(filename, filp);
+	),
+	TP_printk("\"%s\"", __get_str(filename))
+);
+
+#endif /* _TRACE_FS_OPEN_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index db14daf..bd38f7d 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -53,6 +53,9 @@
 #undef __string
 #define __string(item, src) __dynamic_array(char, item, -1)
 
+#undef __file_p
+#define __file_p(item, src) __dynamic_array(char, item, -1)
+
 #undef TP_STRUCT__entry
 #define TP_STRUCT__entry(args...) args
 
@@ -120,6 +123,10 @@
 #undef __string
 #define __string(item, src) __dynamic_array(char, item, -1)
 
+#undef __file_p
+#define __file_p(item, src)			int item; \
+						int item##__size;
+
 #undef DECLARE_EVENT_CLASS
 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
 	struct ftrace_data_offsets_##call {				\
@@ -333,6 +340,9 @@
 #undef __string
 #define __string(item, src) __dynamic_array(char, item, -1)
 
+#undef __file_p
+#define __file_p(item, src) __dynamic_array(char, item, -1)
+
 #undef DECLARE_EVENT_CLASS
 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print)	\
 static int notrace							\
@@ -381,6 +391,13 @@
 #undef __string
 #define __string(item, src) __dynamic_array(char, item, strlen(src) + 1)
 
+#undef __file_p
+#define __file_p(item, src)						\
+	__data_offsets->item = __data_size +				\
+			       offsetof(typeof(*entry), __data);	\
+	__data_offsets->item##__size = ftrace_file_name_len(src);	\
+	__data_size += __data_offsets->item##__size;
+
 #undef DECLARE_EVENT_CLASS
 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
 static inline notrace int ftrace_get_offsets_##call(			\
@@ -502,10 +519,17 @@
 #undef __string
 #define __string(item, src) __dynamic_array(char, item, -1)       	\
 
+#undef __file_p
+#define __file_p(item, src) __dynamic_array(char, item, -1)       	\
+
 #undef __assign_str
 #define __assign_str(dst, src)						\
 	strcpy(__get_str(dst), src);
 
+#undef __assign_file_p
+#define __assign_file_p(dst, src)					\
+	ftrace_assign_file(__get_str (dst), __data_offsets.dst##__size, src);
+
 #undef TP_fast_assign
 #define TP_fast_assign(args...) args
 
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 87b1996..66071dc 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -1313,6 +1313,38 @@
 	     (unsigned long)event < (unsigned long)end;		\
 	     event++)
 
+/* file pointer helpers */
+int ftrace_file_name_len (const struct file *f)
+{
+	/* This performs pretty terribly - obviously */
+	int len = 1;
+	char *buf, *fname;
+
+	if (!(buf = kzalloc(PAGE_SIZE, GFP_KERNEL)))
+		return len;
+	fname = d_path(&f->f_path, buf, PAGE_SIZE);
+	if (!IS_ERR (fname))
+		len += strlen (fname);
+	kfree(buf);
+	return len;
+}
+
+void ftrace_assign_file (char *dest, int dest_len, const struct file *f)
+{
+	char *buf, *fname;
+
+	dest[0] = '\0';
+	if (!(buf = kzalloc(PAGE_SIZE, GFP_KERNEL)))
+		return;
+
+	/* it would be nicer to write this directly into the
+	 * allocated buffer, but d_path doesn't like that */
+	fname = d_path(&f->f_path, buf, PAGE_SIZE);
+	if (!IS_ERR (fname))
+		strncpy (dest, fname, dest_len);
+	kfree(buf);
+}
+
 #ifdef CONFIG_MODULES
 
 static LIST_HEAD(ftrace_module_file_list);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index a15de5c..89813a3 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -299,11 +299,17 @@
  *
  * Note: If the task is ASYNC, this must be called with
  * the spinlock held to protect the wait queue operation.
+ * Note the ordering of rpc_test_and_set_running() and rpc_clear_queued(),
+ * which is needed to ensure that __rpc_execute() doesn't loop (due to the
+ * lockless RPC_IS_QUEUED() test) before we've had a chance to test
+ * the RPC_TASK_RUNNING flag.
  */
 static void rpc_make_runnable(struct rpc_task *task)
 {
+	bool need_wakeup = !rpc_test_and_set_running(task);
+
 	rpc_clear_queued(task);
-	if (rpc_test_and_set_running(task))
+	if (!need_wakeup)
 		return;
 	if (RPC_IS_ASYNC(task)) {
 		INIT_WORK(&task->u.tk_work, rpc_async_schedule);
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 72125fe..3cff132 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -855,10 +855,19 @@
 		hdmi_non_intrinsic_event(codec, res);
 }
 
-static void haswell_verify_pin_D0(struct hda_codec *codec, hda_nid_t nid)
+static void haswell_verify_pin_D0(struct hda_codec *codec,
+		hda_nid_t cvt_nid, hda_nid_t nid)
 {
 	int pwr, lamp, ramp;
 
+	/* For Haswell, the converter 1/2 may keep in D3 state after bootup,
+	 * thus pins could only choose converter 0 for use. Make sure the
+	 * converters are in correct power state */
+	pwr = snd_hda_codec_read(codec, cvt_nid, 0, AC_VERB_GET_POWER_STATE, 0);
+	pwr = (pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT;
+	if (pwr != AC_PWRST_D0)
+		snd_hda_codec_write(codec, cvt_nid, 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+
 	pwr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0);
 	pwr = (pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT;
 	if (pwr != AC_PWRST_D0) {
@@ -905,7 +914,7 @@
 	int new_pinctl = 0;
 
 	if (codec->vendor_id == 0x80862807)
-		haswell_verify_pin_D0(codec, pin_nid);
+		haswell_verify_pin_D0(codec, cvt_nid, pin_nid);
 
 	if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) {
 		pinctl = snd_hda_codec_read(codec, pin_nid, 0,
@@ -938,26 +947,15 @@
 	return 0;
 }
 
-/*
- * HDA PCM callbacks
- */
-static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
-			 struct hda_codec *codec,
-			 struct snd_pcm_substream *substream)
+static int hdmi_choose_cvt(struct hda_codec *codec,
+			int pin_idx, int *cvt_id, int *mux_id)
 {
 	struct hdmi_spec *spec = codec->spec;
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	int pin_idx, cvt_idx, mux_idx = 0;
 	struct hdmi_spec_per_pin *per_pin;
-	struct hdmi_eld *eld;
 	struct hdmi_spec_per_cvt *per_cvt = NULL;
+	int cvt_idx, mux_idx = 0;
 
-	/* Validate hinfo */
-	pin_idx = hinfo_to_pin_index(spec, hinfo);
-	if (snd_BUG_ON(pin_idx < 0))
-		return -EINVAL;
 	per_pin = &spec->pins[pin_idx];
-	eld = &per_pin->sink_eld;
 
 	/* Dynamically assign converter to stream */
 	for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
@@ -975,17 +973,89 @@
 			continue;
 		break;
 	}
+
 	/* No free converters */
 	if (cvt_idx == spec->num_cvts)
 		return -ENODEV;
 
+	if (cvt_id)
+		*cvt_id = cvt_idx;
+	if (mux_id)
+		*mux_id = mux_idx;
+
+	return 0;
+}
+
+static void haswell_config_cvts(struct hda_codec *codec,
+			int pin_id, int mux_id)
+{
+	struct hdmi_spec *spec = codec->spec;
+	struct hdmi_spec_per_pin *per_pin;
+	int pin_idx, mux_idx;
+	int curr;
+	int err;
+
+	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
+		per_pin = &spec->pins[pin_idx];
+
+		if (pin_idx == pin_id)
+			continue;
+
+		curr = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
+					  AC_VERB_GET_CONNECT_SEL, 0);
+
+		/* Choose another unused converter */
+		if (curr == mux_id) {
+			err = hdmi_choose_cvt(codec, pin_idx, NULL, &mux_idx);
+			if (err < 0)
+				return;
+			snd_printdd("HDMI: choose converter %d for pin %d\n", mux_idx, pin_idx);
+			snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
+					    AC_VERB_SET_CONNECT_SEL,
+					    mux_idx);
+		}
+	}
+}
+
+/*
+ * HDA PCM callbacks
+ */
+static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
+			 struct hda_codec *codec,
+			 struct snd_pcm_substream *substream)
+{
+	struct hdmi_spec *spec = codec->spec;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int pin_idx, cvt_idx, mux_idx = 0;
+	struct hdmi_spec_per_pin *per_pin;
+	struct hdmi_eld *eld;
+	struct hdmi_spec_per_cvt *per_cvt = NULL;
+	int err;
+
+	/* Validate hinfo */
+	pin_idx = hinfo_to_pin_index(spec, hinfo);
+	if (snd_BUG_ON(pin_idx < 0))
+		return -EINVAL;
+	per_pin = &spec->pins[pin_idx];
+	eld = &per_pin->sink_eld;
+
+	err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, &mux_idx);
+	if (err < 0)
+		return err;
+
+	per_cvt = &spec->cvts[cvt_idx];
 	/* Claim converter */
 	per_cvt->assigned = 1;
 	hinfo->nid = per_cvt->cvt_nid;
 
-	snd_hda_codec_write(codec, per_pin->pin_nid, 0,
+	snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
 			    AC_VERB_SET_CONNECT_SEL,
 			    mux_idx);
+
+	/* configure unused pins to choose other converters */
+	if (codec->vendor_id == 0x80862807)
+		haswell_config_cvts(codec, pin_idx, mux_idx);
+
 	snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
 
 	/* Initially set the converter's capabilities */
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 6bfef26..72d4caf 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -217,6 +217,7 @@
 	int hp_work_active;
 	int vt1708_jack_detect;
 	int vt1708_hp_present;
+	bool mute_via_amp;
 
 	void (*set_widgets_power_state)(struct hda_codec *codec);
 
@@ -1643,7 +1644,7 @@
 }
 
 /* mute/unmute outputs */
-static void toggle_output_mutes(struct hda_codec *codec, int num_pins,
+static void toggle_output_mutes_via_pin(struct hda_codec *codec, int num_pins,
 				hda_nid_t *pins, bool mute)
 {
 	int i;
@@ -1660,6 +1661,30 @@
 	}
 }
 
+static void toggle_output_mutes_via_amp(struct hda_codec *codec, int num_pins,
+				hda_nid_t *pins, bool mute)
+{
+	int i, ch;
+	for (i = 0; i < num_pins; i++) {
+		for (ch = 0; ch < 2; ch++) {
+			snd_hda_codec_amp_update(codec, pins[i], ch,
+						 HDA_OUTPUT, 0, 0x80,
+						 mute ? 0x80 : 0x00);
+		}
+	}
+}
+
+static void toggle_output_mutes(struct hda_codec *codec, int num_pins,
+				hda_nid_t *pins, bool mute)
+{
+	struct via_spec *spec = codec->spec;
+
+	if (spec->mute_via_amp)
+		toggle_output_mutes_via_amp(codec, num_pins, pins, mute);
+	else
+		toggle_output_mutes_via_pin(codec, num_pins, pins, mute);
+}
+
 /* mute internal speaker if line-out is plugged */
 static void via_line_automute(struct hda_codec *codec, int present)
 {
@@ -1860,7 +1885,8 @@
 }
 
 static int create_ch_ctls(struct hda_codec *codec, const char *pfx,
-			  int chs, bool check_dac, struct nid_path *path)
+			  int chs, bool check_dac, struct nid_path *path,
+			  bool check_mute_via_amp)
 {
 	struct via_spec *spec = codec->spec;
 	char name[32];
@@ -1888,6 +1914,9 @@
 		path->vol_ctl = nid;
 	}
 
+	if (check_mute_via_amp && spec->mute_via_amp)
+		return 0; /* no mute */
+
 	if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_MUTE))
 		nid = dac;
 	else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_MUTE))
@@ -1985,10 +2014,10 @@
 			continue;
 		path = spec->out_path + i;
 		if (i == HDA_CLFE) {
-			err = create_ch_ctls(codec, "Center", 1, true, path);
+			err = create_ch_ctls(codec, "Center", 1, true, path, true);
 			if (err < 0)
 				return err;
-			err = create_ch_ctls(codec, "LFE", 2, true, path);
+			err = create_ch_ctls(codec, "LFE", 2, true, path, true);
 			if (err < 0)
 				return err;
 		} else {
@@ -1996,7 +2025,7 @@
 			if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
 			    cfg->line_outs == 1)
 				pfx = "Speaker";
-			err = create_ch_ctls(codec, pfx, 3, true, path);
+			err = create_ch_ctls(codec, pfx, 3, true, path, true);
 			if (err < 0)
 				return err;
 		}
@@ -2075,7 +2104,7 @@
 		path = &spec->hp_mix_path;
 		check_dac = false;
 	}
-	err = create_ch_ctls(codec, "Headphone", 3, check_dac, path);
+	err = create_ch_ctls(codec, "Headphone", 3, check_dac, path, false);
 	if (err < 0)
 		return err;
 	if (check_dac)
@@ -2126,7 +2155,7 @@
 		path = &spec->speaker_mix_path;
 		check_dac = false;
 	}
-	err = create_ch_ctls(codec, "Speaker", 3, check_dac, path);
+	err = create_ch_ctls(codec, "Speaker", 3, check_dac, path, true);
 	if (err < 0)
 		return err;
 	if (check_dac)
@@ -2844,6 +2873,7 @@
 
 	codec->jackpoll = 1;
 	spec->vt1708_jack_detect = 1;
+	spec->mute_via_amp = 1;
 
 	/* Add HP and CD pin config connect bit re-config action */
 	vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);