All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matt Helsley <matthltc@us.ibm.com>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru>,
	Guillaume Thouvenin <guillaume.thouvenin@bull.net>
Subject: [RFC][PATCH 3/3] Process events biarch bug: New process events connector value
Date: Tue, 27 Jun 2006 04:49:35 -0700	[thread overview]
Message-ID: <1151408975.21787.1815.camel@stark> (raw)
In-Reply-To: 20060627112644.804066367@localhost.localdomain

"Deprecate" existing Process Events connector interface and add a new one
that works cleanly on biarch platforms.

Any expansion of the previous event structure would break userspace's ability
to workaround the biarch incompatibility problem. Hence this patch creates a
new interface and generates events (for both when necessary).

Signed-off-by: Matt Helsley <matthltc@us.ibm.com>
---
 drivers/connector/cn_proc.c |   65 +++++++++++++++++++++++++++++---------------
 include/linux/cn_proc.h     |   23 ++++++++++-----
 include/linux/connector.h   |    3 +-
 3 files changed, 61 insertions(+), 30 deletions(-)

Index: linux-2.6.17-mm3-biarch/include/linux/connector.h
===================================================================
--- linux-2.6.17-mm3-biarch.orig/include/linux/connector.h
+++ linux-2.6.17-mm3-biarch/include/linux/connector.h
@@ -29,11 +29,12 @@
 
 /*
  * Process Events connector unique ids -- used for message routing
  */
 #define CN_IDX_PROC			0x1
-#define CN_VAL_PROC			0x1
+#define CN_VAL_PROC_DEPRECATED		0x1 /* deprecated */
+#define CN_VAL_PROC			0x2
 #define CN_IDX_CIFS			0x2
 #define CN_VAL_CIFS                     0x1
 #define CN_W1_IDX			0x3	/* w1 communication */
 #define CN_W1_VAL			0x1
 
Index: linux-2.6.17-mm3-biarch/drivers/connector/cn_proc.c
===================================================================
--- linux-2.6.17-mm3-biarch.orig/drivers/connector/cn_proc.c
+++ linux-2.6.17-mm3-biarch/drivers/connector/cn_proc.c
@@ -30,13 +30,19 @@
 #include <linux/notifier.h>
 #include <asm/atomic.h>
 
 #include <linux/cn_proc.h>
 
-#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event))
-
-static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
+#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + \
+			  max(sizeof(struct proc_event), \
+			      sizeof(struct proc_event_deprecated)))
+
+static atomic_t proc_event_num_old_listeners = ATOMIC_INIT(0);
+static struct cb_id cn_proc_event_deprecated_id = {
+	CN_IDX_PROC,
+	CN_VAL_PROC_DEPRECATED
+};
 static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
 
 /* proc_event_counts is used as the sequence number of the netlink message */
 static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 };
 
@@ -100,18 +106,18 @@ static inline void proc_exit_connector(s
  * mechanisms.
  */
 static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
 {
 	struct cn_msg *msg;
-	struct proc_event *ev;
+	struct proc_event_deprecated *ev;
 	__u8 buffer[CN_PROC_MSG_SIZE];
 
-	if (atomic_read(&proc_event_num_listeners) < 1)
+	if (atomic_read(&proc_event_num_old_listeners) < 1)
 		return;
 
 	msg = (struct cn_msg*)buffer;
-	ev = (struct proc_event*)msg->data;
+	ev = (struct proc_event_deprecated*)msg->data;
 	msg->seq = rcvd_seq;
 	ktime_get_ts(&ev->timestamp);
 	ev->cpu = -1;
 	ev->what = PROC_EVENT_NONE;
 	ev->event_data.ack.err = err;
@@ -123,11 +129,11 @@ static void cn_proc_ack(int err, int rcv
 
 /**
  * cn_proc_mcast_ctl
  * @data: message sent from userspace via the connector
  */
-static void cn_proc_mcast_ctl(void *data)
+static void cn_proc_mcast_old_ctl(void *data)
 {
 	struct cn_msg *msg = data;
 	enum proc_cn_mcast_op *mc_op = NULL;
 	int err = 0;
 
@@ -135,14 +141,14 @@ static void cn_proc_mcast_ctl(void *data
 		return;
 
 	mc_op = (enum proc_cn_mcast_op*)msg->data;
 	switch (*mc_op) {
 	case PROC_CN_MCAST_LISTEN:
-		atomic_inc(&proc_event_num_listeners);
+		atomic_inc(&proc_event_num_old_listeners);
 		break;
 	case PROC_CN_MCAST_IGNORE:
-		atomic_dec(&proc_event_num_listeners);
+		atomic_dec(&proc_event_num_old_listeners);
 		break;
 	default:
 		err = EINVAL;
 		break;
 	}
@@ -158,16 +164,15 @@ static int cn_proc_watch_task(struct not
 			      void *t)
 {
 	struct task_struct *task = t;
 	struct cn_msg *msg;
 	struct proc_event *ev;
+	struct proc_event_deprecated *ev_old;
+	struct timespec timestamp;
 	__u8 buffer[CN_PROC_MSG_SIZE];
 	int rc = NOTIFY_OK;
 
-	if (atomic_read(&proc_event_num_listeners) < 1)
-		return rc;
-
 	msg = (struct cn_msg*)buffer;
 	ev = (struct proc_event*)msg->data;
 	switch (get_watch_event(val)) {
 	case WATCH_TASK_CLONE:
 		proc_fork_connector(task, ev);
@@ -189,16 +194,26 @@ static int cn_proc_watch_task(struct not
 		break;
 	}
 	if (rc != NOTIFY_OK)
 		return rc;
 	get_seq(&msg->seq, &ev->cpu);
-	ktime_get_ts(&ev->timestamp); /* get high res monotonic timestamp */
+	ktime_get_ts(&timestamp); /* get high res monotonic timestamp */
+	ev->timestamp_ns = ((__u64)timestamp.tv_sec*(__u64)NSEC_PER_SEC) + (__u64)timestamp.tv_nsec;
 	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
 	msg->ack = 0; /* not used */
 	msg->len = sizeof(*ev);
 	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
 	/* If cn_netlink_send() fails, drop data */
+
+	if (atomic_read(&proc_event_num_old_listeners) < 1)
+		return rc;
+	ev_old = (struct proc_event_deprecated*)msg->data;
+	msg->len = sizeof(*ev_old);
+	memmove(&ev_old->event_data, &ev->event_data, sizeof(ev->event_data));
+	memcpy(&ev_old->timestamp, &timestamp, sizeof(timestamp));
+	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+	/* If cn_netlink_send() fails, drop data */
 	return rc;
 }
 
 static struct notifier_block __read_mostly cn_proc_nb = {
 	.notifier_call = cn_proc_watch_task,
@@ -211,20 +226,27 @@ static struct notifier_block __read_most
  */
 static int __init cn_proc_init(void)
 {
 	int err;
 
-	if ((err = cn_add_callback(&cn_proc_event_id, "cn_proc",
-	 			   &cn_proc_mcast_ctl))) {
-		printk(KERN_WARNING "cn_proc failed to register\n");
-		goto out;
-	}
+	err = cn_add_callback(&cn_proc_event_deprecated_id, "cn_proc_old",
+			      &cn_proc_mcast_old_ctl);
+	if (err)
+		goto error_old;
+	err = cn_add_callback(&cn_proc_event_id, "cn_proc", NULL);
+	if (err)
+		goto error;
 
 	err = register_task_watcher(&cn_proc_nb);
-	if (err != 0)
-		cn_del_callback(&cn_proc_event_id);
-out:
+	if (err)
+		goto error;
+	return err;
+error:
+	cn_del_callback(&cn_proc_event_id);
+error_old:
+	cn_del_callback(&cn_proc_event_deprecated_id);
+	printk(KERN_WARNING "cn_proc failed to register\n");
 	return err;
 }
 
 static void cn_proc_fini(void)
 {
@@ -234,10 +256,11 @@ static void cn_proc_fini(void)
 	if (err != 0)
 		printk(KERN_WARNING
 		       "cn_proc failed to unregister its task notify block\n");
 
 	cn_del_callback(&cn_proc_event_id);
+	cn_del_callback(&cn_proc_event_deprecated_id);
 }
 
 module_init(cn_proc_init);
 module_exit(cn_proc_fini);
 
Index: linux-2.6.17-mm3-biarch/include/linux/cn_proc.h
===================================================================
--- linux-2.6.17-mm3-biarch.orig/include/linux/cn_proc.h
+++ linux-2.6.17-mm3-biarch/include/linux/cn_proc.h
@@ -55,18 +55,11 @@ struct proc_event {
 		/* "next" should be 0x00000400 */
 		/* "last" is the last process event: exit */
 		PROC_EVENT_EXIT = 0x80000000
 	} what;
 	__u32 cpu;
-
- 	/*
- 	 * UGH! timespec is biarch incompatible. See
- 	 * Documentation/connector/process_events.txt if you're going to listen
- 	 * for process events in userspace.
- 	 */
-	struct timespec timestamp;
-
+	__u64 timestamp_ns;
 	union process_event_data { /* must be last field of proc_event struct */
 		struct {
 			__u32 err;
 		} ack;
 
@@ -100,6 +93,20 @@ struct proc_event {
 			pid_t process_tgid;
 			__u32 exit_code, exit_signal;
 		} exit;
 	} event_data;
 };
+
+struct proc_event_deprecated {
+	enum what what;
+	__u32 cpu;
+
+	/*
+	 * UGH! timespec is biarch incompatible. See
+	 * Documentation/connector/process_events.txt if you're going to listen
+	 * for process events in userspace.
+	 */
+	struct timespec timestamp;
+	union process_event_data event_data;
+};
+
 #endif	/* CN_PROC_H */

--


  parent reply	other threads:[~2006-06-27 11:54 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20060627112644.804066367@localhost.localdomain>
2006-06-27 11:47 ` [RFC][PATCH 1/3] Process events biarch bug: Name process event data union type and annotate for compatibility Matt Helsley
2006-06-27 11:48 ` [RFC][PATCH 2/3] Process events biarch bug: Process events timestamp bug Matt Helsley
2006-06-27 11:49 ` Matt Helsley [this message]
2006-06-27 19:14   ` [RFC][PATCH 3/3] Process events biarch bug: New process events connector value Chandra Seetharaman
2006-06-27 21:39     ` Matt Helsley
2006-06-27 23:54       ` Chandra Seetharaman
2006-06-28  1:29         ` Matt Helsley
2006-06-28  5:53       ` Evgeniy Polyakov
2006-06-30  8:46         ` Evgeniy Polyakov
2006-06-28  6:00 Albert Cahalan

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=1151408975.21787.1815.camel@stark \
    --to=matthltc@us.ibm.com \
    --cc=guillaume.thouvenin@bull.net \
    --cc=johnpol@2ka.mipt.ru \
    --cc=linux-kernel@vger.kernel.org \
    /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.