lkml.org 
[lkml]   [2005]   [Mar]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: [patch 1/2] fork_connector: add a fork connector
    From
    Date
    ChangeLog:

    - Remove the global cn_fork_lock and replace it by a per CPU
    counter.
    - The processor ID has been added in the data part of the message.
    Thus datas sent in a message are: "CPU_ID PARENT_PID CHILD_PID"

    Those modifications were done to be more scalable because, as
    mentioned by Jesse Barnes, the global cn_fork_lock won't work well on a
    large CPU system.

    This patch applies to 2.6.11-mm4.

    Regards,
    Guillaume

    ---

    drivers/connector/Kconfig | 11 +++++
    drivers/connector/Makefile | 1
    drivers/connector/cn_fork.c | 85 ++++++++++++++++++++++++++++++++++++++++++++
    include/linux/connector.h | 4 ++
    kernel/fork.c | 44 ++++++++++++++++++++++
    5 files changed, 145 insertions(+)


    Index: linux-2.6.11-mm4-cnfork/drivers/connector/Kconfig
    ===================================================================
    --- linux-2.6.11-mm4-cnfork.orig/drivers/connector/Kconfig 2005-03-16 14:21:46.000000000 +0100
    +++ linux-2.6.11-mm4-cnfork/drivers/connector/Kconfig 2005-03-16 14:34:41.000000000 +0100
    @@ -10,4 +10,15 @@
    Connector support can also be built as a module. If so, the module
    will be called cn.ko.

    +config FORK_CONNECTOR
    + bool "Enable fork connector"
    + depends on CONNECTOR=y
    + default y
    + ---help---
    + It adds a connector in kernel/fork.c:do_fork() function. When a fork
    + occurs, netlink is used to transfer information about the parent and
    + its child. This information can be used by a user space application.
    + The fork connector can be enable/disable by sending a message to the
    + connector with the corresponding group id.
    +
    endmenu
    Index: linux-2.6.11-mm4-cnfork/drivers/connector/Makefile
    ===================================================================
    --- linux-2.6.11-mm4-cnfork.orig/drivers/connector/Makefile 2005-03-16 14:21:46.000000000 +0100
    +++ linux-2.6.11-mm4-cnfork/drivers/connector/Makefile 2005-03-16 14:34:41.000000000 +0100
    @@ -1,2 +1,3 @@
    obj-$(CONFIG_CONNECTOR) += cn.o
    +obj-$(CONFIG_FORK_CONNECTOR) += cn_fork.o
    cn-objs := cn_queue.o connector.o
    Index: linux-2.6.11-mm4-cnfork/drivers/connector/cn_fork.c
    ===================================================================
    --- linux-2.6.11-mm4-cnfork.orig/drivers/connector/cn_fork.c 2003-01-30 11:24:37.000000000 +0100
    +++ linux-2.6.11-mm4-cnfork/drivers/connector/cn_fork.c 2005-03-16 14:34:41.000000000 +0100
    @@ -0,0 +1,85 @@
    +/*
    + * cn_fork.c
    + *
    + * 2005 Copyright (c) Guillaume Thouvenin <guillaume.thouvenin@bull.net>
    + * All rights reserved.
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License as published by
    + * the Free Software Foundation; either version 2 of the License, or
    + * (at your option) any later version.
    + *
    + * This program is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    + * GNU General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public License
    + * along with this program; if not, write to the Free Software
    + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    + */
    +
    +#include <linux/module.h>
    +#include <linux/kernel.h>
    +#include <linux/init.h>
    +
    +#include <linux/connector.h>
    +
    +MODULE_LICENSE("GPL");
    +MODULE_AUTHOR("Guillaume Thouvenin <guillaume.thouvenin@bull.net>");
    +MODULE_DESCRIPTION("Enable or disable the usage of the fork connector");
    +
    +int cn_fork_enable = 0;
    +struct cb_id cb_fork_id = { CN_IDX_FORK, CN_VAL_FORK };
    +
    +/**
    + * cn_fork_callback - enable or disable the fork connector
    + * @data: message send by the connector
    + *
    + * The callback allows to enable or disable the sending of information
    + * about fork in the do_fork() routine. To enable the fork, the user
    + * space application must send the integer 1 in the data part of the
    + * message. To disable the fork connector, it must send the integer 0.
    + */
    +static void cn_fork_callback(void *data)
    +{
    + struct cn_msg *msg = (struct cn_msg *)data;
    +
    + if (cn_already_initialized && (msg->len == sizeof(cn_fork_enable)))
    + memcpy(&cn_fork_enable, msg->data, sizeof(cn_fork_enable));
    +}
    +
    +/**
    + * cn_fork_init - initialization entry point
    + *
    + * This routine will be run at kernel boot time because this driver is
    + * built in the kernel. It adds the connector callback to the connector
    + * driver.
    + */
    +static int cn_fork_init(void)
    +{
    + int err;
    +
    + err = cn_add_callback(&cb_fork_id, "cn_fork", &cn_fork_callback);
    + if (err) {
    + printk(KERN_WARNING "Failed to register cn_fork\n");
    + return -EINVAL;
    + }
    +
    + printk(KERN_NOTICE "cn_fork is registered\n");
    + return 0;
    +}
    +
    +/**
    + * cn_fork_exit - exit entry point
    + *
    + * As this driver is always statically compiled into the kernel the
    + * cn_fork_exit has no effect.
    + */
    +static void cn_fork_exit(void)
    +{
    + cn_del_callback(&cb_fork_id);
    +}
    +
    +module_init(cn_fork_init);
    +module_exit(cn_fork_exit);
    Index: linux-2.6.11-mm4-cnfork/include/linux/connector.h
    ===================================================================
    --- linux-2.6.11-mm4-cnfork.orig/include/linux/connector.h 2005-03-16 14:21:49.000000000 +0100
    +++ linux-2.6.11-mm4-cnfork/include/linux/connector.h 2005-03-16 14:34:41.000000000 +0100
    @@ -28,6 +28,8 @@
    #define CN_VAL_KOBJECT_UEVENT 0x0000
    #define CN_IDX_SUPERIO 0xaabb /* SuperIO subsystem */
    #define CN_VAL_SUPERIO 0xccdd
    +#define CN_IDX_FORK 0xfeed /* fork events */
    +#define CN_VAL_FORK 0xbeef


    #define CONNECTOR_MAX_MSG_SIZE 1024
    @@ -133,6 +135,8 @@
    };

    extern int cn_already_initialized;
    +extern int cn_fork_enable;
    +extern struct cb_id cb_fork_id;

    int cn_add_callback(struct cb_id *, char *, void (* callback)(void *));
    void cn_del_callback(struct cb_id *);
    Index: linux-2.6.11-mm4-cnfork/kernel/fork.c
    ===================================================================
    --- linux-2.6.11-mm4-cnfork.orig/kernel/fork.c 2005-03-16 14:21:49.000000000 +0100
    +++ linux-2.6.11-mm4-cnfork/kernel/fork.c 2005-03-21 13:13:25.000000000 +0100
    @@ -41,6 +41,7 @@
    #include <linux/profile.h>
    #include <linux/rmap.h>
    #include <linux/acct.h>
    +#include <linux/connector.h>

    #include <asm/pgtable.h>
    #include <asm/pgalloc.h>
    @@ -63,6 +64,47 @@

    EXPORT_SYMBOL(tasklist_lock);

    +#ifdef CONFIG_FORK_CONNECTOR
    +
    +#define CN_FORK_INFO_SIZE 64
    +#define CN_FORK_MSG_SIZE (sizeof(struct cn_msg) + CN_FORK_INFO_SIZE)
    +
    +static DEFINE_PER_CPU(unsigned long, fork_counts);
    +
    +static inline void fork_connector(pid_t parent, pid_t child)
    +{
    + if (cn_fork_enable) {
    + struct cn_msg *msg;
    + __u8 buffer[CN_FORK_MSG_SIZE];
    +
    + msg = (struct cn_msg *)buffer;
    +
    + memcpy(&msg->id, &cb_fork_id, sizeof(msg->id));
    +
    + msg->ack = 0; /* not used */
    + msg->seq = get_cpu_var(fork_counts)++;
    +
    + /*
    + * size of data is the number of characters
    + * printed plus one for the trailing '\0'
    + */
    + memset(msg->data, '\0', CN_FORK_INFO_SIZE);
    + msg->len = scnprintf(msg->data, CN_FORK_INFO_SIZE-1,
    + "%i %i %i",
    + smp_processor_id(), parent, child) + 1;
    +
    + put_cpu_var(fork_counts);
    +
    + cn_netlink_send(msg, CN_IDX_FORK);
    + }
    +}
    +#else
    +static inline void fork_connector(pid_t parent, pid_t child)
    +{
    + return;
    +}
    +#endif /* CONFIG_FORK_CONNECTOR */
    +
    int nr_processes(void)
    {
    int cpu;
    @@ -1253,6 +1295,8 @@
    if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE))
    ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
    }
    +
    + fork_connector(current->pid, p->pid);
    } else {
    free_pidmap(pid);
    pid = PTR_ERR(p);

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:11    [W:0.109 / U:30.840 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site