All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <a.p.zijlstra@chello.nl>
To: Oleg Nesterov <oleg@redhat.com>
Cc: eranian@gmail.com, Ingo Molnar <mingo@elte.hu>,
	LKML <linux-kernel@vger.kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Robert Richter <robert.richter@amd.com>,
	Paul Mackerras <paulus@samba.org>,
	Andi Kleen <andi@firstfloor.org>,
	Maynard Johnson <mpjohn@us.ibm.com>, Carl Love <cel@us.ibm.com>,
	Corey J Ashford <cjashfor@us.ibm.com>,
	Philip Mucci <mucci@eecs.utk.edu>,
	Dan Terpstra <terpstra@eecs.utk.edu>,
	perfmon2-devel <perfmon2-devel@lists.sourceforge.net>,
	Michael Kerrisk <mtk.manpages@googlemail.com>,
	roland <roland@redhat.com>
Subject: [RFC][PATCH] fcntl: F_[SG]ETOWN_TID
Date: Fri, 31 Jul 2009 10:35:20 +0200	[thread overview]
Message-ID: <1249029320.6391.72.camel@twins> (raw)
In-Reply-To: <20090730202804.GA13675@redhat.com>

In order to direct the SIGIO signal to a particular thread of a
multi-threaded application we cannot, like suggested by the manpage, put
a TID into the regular fcntl(F_SETOWN) call. It will still be send to
the whole process of which that thread is part.

Since people do want to properly direct SIGIO we introduce F_SETOWN_TID,
which functions similarly to F_SETOWN, except positive arguments are
interpreted as TIDs and negative arguments are interpreted as PIDs.

This extension is fully bug compatible with the old F_GETOWN
implementation in that F_GETOWN_TID will be troubled by the negative
return value for PIDs similarly to F_GETOWN's trouble with process
groups.

[ compile tested only so far ]

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
 arch/parisc/include/asm/fcntl.h |    2 +
 fs/fcntl.c                      |   64 +++++++++++++++++++++++++++++++++-----
 include/asm-generic/fcntl.h     |    4 ++
 include/linux/fs.h              |   11 +++++-
 net/socket.c                    |    2 +-
 5 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/arch/parisc/include/asm/fcntl.h b/arch/parisc/include/asm/fcntl.h
index 1e1c824..5d5235a 100644
--- a/arch/parisc/include/asm/fcntl.h
+++ b/arch/parisc/include/asm/fcntl.h
@@ -28,6 +28,8 @@
 #define F_SETOWN	12	/*  for sockets. */
 #define F_SETSIG	13	/*  for sockets. */
 #define F_GETSIG	14	/*  for sockets. */
+#define F_GETOWN_TID	15
+#define F_SETOWN_TID	16
 
 /* for posix fcntl() and lockf() */
 #define F_RDLCK		01
diff --git a/fs/fcntl.c b/fs/fcntl.c
index ae41308..8d0b7f9 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -197,13 +197,15 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
 }
 
 static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
-                     int force)
+                     int flags)
 {
 	write_lock_irq(&filp->f_owner.lock);
-	if (force || !filp->f_owner.pid) {
+	if ((flags & FF_SETOWN_FORCE) || !filp->f_owner.pid) {
 		put_pid(filp->f_owner.pid);
 		filp->f_owner.pid = get_pid(pid);
 		filp->f_owner.pid_type = type;
+		filp->f_owner.task_only =
+			(type == PIDTYPE_PID && (flags & FF_SETOWN_TID));
 
 		if (pid) {
 			const struct cred *cred = current_cred();
@@ -215,7 +217,7 @@ static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
 }
 
 int __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
-		int force)
+		int flags)
 {
 	int err;
 
@@ -223,12 +225,12 @@ int __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
 	if (err)
 		return err;
 
-	f_modown(filp, pid, type, force);
+	f_modown(filp, pid, type, flags);
 	return 0;
 }
 EXPORT_SYMBOL(__f_setown);
 
-int f_setown(struct file *filp, unsigned long arg, int force)
+int f_setown(struct file *filp, unsigned long arg, int flags)
 {
 	enum pid_type type;
 	struct pid *pid;
@@ -241,7 +243,7 @@ int f_setown(struct file *filp, unsigned long arg, int force)
 	}
 	rcu_read_lock();
 	pid = find_vpid(who);
-	result = __f_setown(filp, pid, type, force);
+	result = __f_setown(filp, pid, type, flags);
 	rcu_read_unlock();
 	return result;
 }
@@ -263,6 +265,40 @@ pid_t f_getown(struct file *filp)
 	return pid;
 }
 
+static int f_setown_tid(struct file *filp, unsigned long arg)
+{
+	int flags = FF_SETOWN_FORCE;
+	struct pid *pid;
+	int who = arg;
+	int ret = 0;
+
+	if (who < 0)
+		who = -who;
+	else
+		flags |= FF_SETOWN_TID;
+
+	rcu_read_lock();
+	pid = find_vpid(who);
+	ret = __f_setown(filp, pid, PIDTYPE_PID, flags);
+	rcu_read_unlock();
+
+	return ret;
+}
+
+static pid_t f_getown_tid(struct file *filp)
+{
+	pid_t tid;
+
+	read_lock(&filp->f_owner.lock);
+	tid = pid_vnr(filp->f_owner.pid);
+	if (filp->f_owner.pid_type == PIDTYPE_PGID)
+		tid = 0;
+	if (!filp->f_owner.task_only)
+		tid = -tid;
+	read_unlock(&filp->f_owner.lock);
+	return tid;
+}
+
 static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
 		struct file *filp)
 {
@@ -311,7 +347,14 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
 		force_successful_syscall_return();
 		break;
 	case F_SETOWN:
-		err = f_setown(filp, arg, 1);
+		err = f_setown(filp, arg, FF_SETOWN_FORCE);
+		break;
+	case F_GETOWN_TID:
+		err = f_getown_tid(filp);
+		force_successful_syscall_return();
+		break;
+	case F_SETOWN_TID:
+		err = f_setown_tid(filp, arg);
 		break;
 	case F_GETSIG:
 		err = filp->f_owner.signum;
@@ -431,6 +474,7 @@ static void send_sigio_to_task(struct task_struct *p,
 			       int fd,
 			       int reason)
 {
+	int (*send_sig)(int, struct siginfo *, struct task_struct *);
 	/*
 	 * F_SETSIG can change ->signum lockless in parallel, make
 	 * sure we read it once and use the same value throughout.
@@ -440,6 +484,8 @@ static void send_sigio_to_task(struct task_struct *p,
 	if (!sigio_perm(p, fown, signum))
 		return;
 
+	send_sig = fown->task_only ? send_sig_info : group_send_sig_info;
+
 	switch (signum) {
 		siginfo_t si;
 		default:
@@ -461,11 +507,11 @@ static void send_sigio_to_task(struct task_struct *p,
 			else
 				si.si_band = band_table[reason - POLL_IN];
 			si.si_fd    = fd;
-			if (!group_send_sig_info(signum, &si, p))
+			if (!send_sig(signum, &si, p))
 				break;
 		/* fall-through: fall back on the old plain SIGIO signal */
 		case 0:
-			group_send_sig_info(SIGIO, SEND_SIG_PRIV, p);
+			send_sig(SIGIO, SEND_SIG_PRIV, p);
 	}
 }
 
diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h
index 4d3e483..d7906b8 100644
--- a/include/asm-generic/fcntl.h
+++ b/include/asm-generic/fcntl.h
@@ -73,6 +73,10 @@
 #define F_SETSIG	10	/* for sockets. */
 #define F_GETSIG	11	/* for sockets. */
 #endif
+#ifndef F_SETOWN_TID
+#define F_SETOWN_TID	12
+#define F_GETOWN_TID	13
+#endif
 
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0872372..42697e7 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -872,6 +872,7 @@ struct fown_struct {
 	rwlock_t lock;          /* protects pid, uid, euid fields */
 	struct pid *pid;	/* pid or -pgrp where SIGIO should be sent */
 	enum pid_type pid_type;	/* Kind of process group SIGIO should be sent to */
+	bool task_only;		/* task or group signal */
 	uid_t uid, euid;	/* uid/euid of process setting the owner */
 	int signum;		/* posix.1b rt signal to be delivered on IO */
 };
@@ -1291,8 +1292,14 @@ extern void kill_fasync(struct fasync_struct **, int, int);
 /* only for net: no internal synchronization */
 extern void __kill_fasync(struct fasync_struct *, int, int);
 
-extern int __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
-extern int f_setown(struct file *filp, unsigned long arg, int force);
+/*
+ * setown flags
+ */ 
+#define FF_SETOWN_FORCE		1
+#define FF_SETOWN_TID		2
+
+extern int __f_setown(struct file *filp, struct pid *, enum pid_type, int flags);
+extern int f_setown(struct file *filp, unsigned long arg, int flags);
 extern void f_delown(struct file *filp);
 extern pid_t f_getown(struct file *filp);
 extern int send_sigurg(struct fown_struct *fown);
diff --git a/net/socket.c b/net/socket.c
index 791d71a..ac57f8e 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -916,7 +916,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 			err = -EFAULT;
 			if (get_user(pid, (int __user *)argp))
 				break;
-			err = f_setown(sock->file, pid, 1);
+			err = f_setown(sock->file, pid, FF_SETOWN_FORCE);
 			break;
 		case FIOGETOWN:
 		case SIOCGPGRP:



  parent reply	other threads:[~2009-07-31  8:32 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-27 16:51 perf_counters issue with self-sampling threads stephane eranian
2009-07-27 16:56 ` Peter Zijlstra
2009-07-27 21:25 ` Andi Kleen
     [not found]   ` <7c86c4470907272213w2ee57080re50dd22a4d73a7e0@mail.gmail.com>
2009-07-28  8:51     ` stephane eranian
2009-07-28  8:56       ` Andi Kleen
2009-07-28  9:13         ` stephane eranian
2009-08-04 16:09     ` stephane eranian
2009-07-29 12:19 ` Peter Zijlstra
2009-07-29 12:37   ` stephane eranian
2009-07-29 12:46     ` Peter Zijlstra
2009-07-29 22:17   ` Oleg Nesterov
2009-07-30 11:31     ` Peter Zijlstra
2009-07-30 19:20       ` Oleg Nesterov
2009-07-30 20:00         ` Peter Zijlstra
2009-07-30 20:28           ` Oleg Nesterov
2009-07-30 21:09             ` stephane eranian
2009-07-31  8:35             ` Peter Zijlstra [this message]
2009-07-31 14:01               ` [RFC][PATCH] fcntl: F_[SG]ETOWN_TID stephane eranian
2009-07-31 20:52               ` Oleg Nesterov
2009-07-31 21:11               ` Andrew Morton
2009-08-01  1:27                 ` [PATCH 0/2] send_sigio/do_send_sig_info (Was: [RFC][PATCH] fcntl: F_[SG]ETOWN_TID) Oleg Nesterov
2009-08-03 15:48                   ` [PATCH 3/2] fcntl: F_[SG]ETOWN_TID Peter Zijlstra
2009-08-03 17:16                     ` Oleg Nesterov
2009-08-03 17:47                       ` Peter Zijlstra
2009-08-03 18:06                         ` Oleg Nesterov
2009-08-03 18:36                           ` Peter Zijlstra
2009-08-03 19:02                             ` Oleg Nesterov
2009-08-04 11:39                               ` [PATCH 3/2 -v3] fcntl: F_[SG]ETOWN_EX Peter Zijlstra
2009-08-04 16:20                                 ` Oleg Nesterov
2009-08-04 16:52                                   ` Peter Zijlstra
2009-08-04 17:19                                     ` Oleg Nesterov
2009-08-06 13:14                                       ` [PATCH 3/2 -v4] " Peter Zijlstra
2009-08-06 19:05                                         ` Oleg Nesterov
2009-08-07 12:10                                           ` stephane eranian
2009-08-01  1:28                 ` [PATCH 1/2] signals: introduce do_send_sig_info() helper Oleg Nesterov
2009-08-01  1:28                 ` [PATCH 2/2] signals: send_sigio: use do_send_sig_info() to avoid check_kill_permission() Oleg Nesterov
2009-08-03 12:53                 ` [RFC][PATCH] fcntl: F_[SG]ETOWN_TID stephane eranian
2009-08-09  5:46                   ` F_SETOWN_TID: F_SETOWN was thread-specific for a while Jamie Lokier
2009-08-10 12:22                     ` stephane eranian
2009-08-10 17:03                       ` Oleg Nesterov
2009-08-10 21:01                         ` stephane eranian
2009-08-17 17:16                           ` Oleg Nesterov
2009-08-17 17:40                             ` Oleg Nesterov
2009-08-17 22:26                             ` stephane eranian
2009-08-18 11:45                               ` Oleg Nesterov
2009-08-20 10:00                                 ` stephane eranian
2009-08-11 13:10                         ` Jamie Lokier
2009-08-17 17:05                           ` Oleg Nesterov
2009-08-03 15:21                 ` [RFC][PATCH] fcntl: F_[SG]ETOWN_TID Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1249029320.6391.72.camel@twins \
    --to=a.p.zijlstra@chello.nl \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=cel@us.ibm.com \
    --cc=cjashfor@us.ibm.com \
    --cc=eranian@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=mpjohn@us.ibm.com \
    --cc=mtk.manpages@googlemail.com \
    --cc=mucci@eecs.utk.edu \
    --cc=oleg@redhat.com \
    --cc=paulus@samba.org \
    --cc=perfmon2-devel@lists.sourceforge.net \
    --cc=robert.richter@amd.com \
    --cc=roland@redhat.com \
    --cc=terpstra@eecs.utk.edu \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.