lkml.org 
[lkml]   [2003]   [Feb]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH][2.5][3/15] smp_call_function/_on_cpu - i386
    On Sun, 9 Feb 2003, James Bottomley wrote:

    > The voyager pieces of this don't provide the smp_call_function_on_cpu(),
    > since voyager doesn't compile kernel/smp.c, so voyager will break the
    > first time someone uses the new function.

    Oops, thanks, new i386 patch appended.

    > As a general comment, wouldn't it be better simply to make
    > smp_call_function an alias for smp_call_function_on_cpu with the mask
    > being the cpu_online_map? That way we'd reduce the amount of duplicated
    > code.

    Some SMP architectures can specify special destinations so that
    ALL_BUT_SELF can be sent in one IPI instead of sending it individually. I
    think it's good to seperate them in that case, although perhaps other
    architectures could have these functions collapsed.

    Index: linux-2.5.59-bk/arch/i386/kernel/cpuid.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/kernel/cpuid.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 cpuid.c
    --- linux-2.5.59-bk/arch/i386/kernel/cpuid.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/kernel/cpuid.c 9 Feb 2003 09:23:29 -0000
    @@ -71,7 +71,7 @@
    cmd.reg = reg;
    cmd.data = data;

    - smp_call_function(cpuid_smp_cpuid, &cmd, 1, 1);
    + smp_call_function(cpuid_smp_cpuid, &cmd, 1);
    }
    }
    #else /* ! CONFIG_SMP */
    Index: linux-2.5.59-bk/arch/i386/kernel/io_apic.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/kernel/io_apic.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 io_apic.c
    --- linux-2.5.59-bk/arch/i386/kernel/io_apic.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/kernel/io_apic.c 9 Feb 2003 09:23:29 -0000
    @@ -1049,7 +1049,7 @@

    void print_all_local_APICs (void)
    {
    - smp_call_function(print_local_APIC, NULL, 1, 1);
    + smp_call_function(print_local_APIC, NULL, 1);
    print_local_APIC(NULL);
    }

    @@ -1524,7 +1524,7 @@
    */
    printk(KERN_INFO "activating NMI Watchdog ...");

    - smp_call_function(enable_NMI_through_LVT0, NULL, 1, 1);
    + smp_call_function(enable_NMI_through_LVT0, NULL, 1);
    enable_NMI_through_LVT0(NULL);

    printk(" done.\n");
    Index: linux-2.5.59-bk/arch/i386/kernel/ldt.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/kernel/ldt.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 ldt.c
    --- linux-2.5.59-bk/arch/i386/kernel/ldt.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/kernel/ldt.c 9 Feb 2003 09:23:29 -0000
    @@ -59,7 +59,7 @@
    #ifdef CONFIG_SMP
    preempt_disable();
    if (current->mm->cpu_vm_mask != (1 << smp_processor_id()))
    - smp_call_function(flush_ldt, 0, 1, 1);
    + smp_call_function(flush_ldt, 0, 1);
    preempt_enable();
    #endif
    }
    Index: linux-2.5.59-bk/arch/i386/kernel/microcode.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/kernel/microcode.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 microcode.c
    --- linux-2.5.59-bk/arch/i386/kernel/microcode.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/kernel/microcode.c 9 Feb 2003 09:23:29 -0000
    @@ -183,7 +183,7 @@
    int i, error = 0, err;
    struct microcode *m;

    - if (smp_call_function(do_update_one, NULL, 1, 1) != 0) {
    + if (smp_call_function(do_update_one, NULL, 1) != 0) {
    printk(KERN_ERR "microcode: IPI timeout, giving up\n");
    return -EIO;
    }
    Index: linux-2.5.59-bk/arch/i386/kernel/msr.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/kernel/msr.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 msr.c
    --- linux-2.5.59-bk/arch/i386/kernel/msr.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/kernel/msr.c 9 Feb 2003 09:23:29 -0000
    @@ -124,7 +124,7 @@
    cmd.data[0] = eax;
    cmd.data[1] = edx;

    - smp_call_function(msr_smp_wrmsr, &cmd, 1, 1);
    + smp_call_function(msr_smp_wrmsr, &cmd, 1);
    return cmd.err;
    }
    }
    @@ -139,7 +139,7 @@
    cmd.cpu = cpu;
    cmd.reg = reg;

    - smp_call_function(msr_smp_rdmsr, &cmd, 1, 1);
    + smp_call_function(msr_smp_rdmsr, &cmd, 1);

    *eax = cmd.data[0];
    *edx = cmd.data[1];
    Index: linux-2.5.59-bk/arch/i386/kernel/reboot.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/kernel/reboot.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 reboot.c
    --- linux-2.5.59-bk/arch/i386/kernel/reboot.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/kernel/reboot.c 9 Feb 2003 09:23:29 -0000
    @@ -243,7 +243,7 @@
    cleared reboot_smp, and do the reboot if it is the
    correct CPU, otherwise it halts. */
    if (reboot_cpu != cpuid)
    - smp_call_function((void *)machine_restart , NULL, 1, 0);
    + smp_call_function((void *)machine_restart , NULL, 0);
    }

    /* if reboot_cpu is still -1, then we want a tradional reboot,
    Index: linux-2.5.59-bk/arch/i386/kernel/smp.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/kernel/smp.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 smp.c
    --- linux-2.5.59-bk/arch/i386/kernel/smp.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/kernel/smp.c 9 Feb 2003 09:23:29 -0000
    @@ -452,7 +452,7 @@

    void flush_tlb_all(void)
    {
    - smp_call_function (flush_tlb_all_ipi,0,1,1);
    + smp_call_function (flush_tlb_all_ipi,0,1);

    do_flush_tlb_all_local();
    }
    @@ -499,13 +499,11 @@
    * in the system.
    */

    -int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
    - int wait)
    +int smp_call_function (void (*func) (void *info), void *info, int wait)
    /*
    * [SUMMARY] Run a function on all other CPUs.
    * <func> The function to run. This must be fast and non-blocking.
    * <info> An arbitrary pointer to pass to the function.
    - * <nonatomic> currently unused.
    * <wait> If true, wait (atomically) until function has completed on other CPUs.
    * [RETURNS] 0 on success, else a negative status code. Does not return until
    * remote CPUs are nearly ready to execute <<func>> or are or have executed.
    @@ -545,6 +543,62 @@
    return 0;
    }

    +/*
    + * smp_call_function_on_cpu - Runs func on all processors in the mask
    + *
    + * @func: The function to run. This must be fast and non-blocking.
    + * @info: An arbitrary pointer to pass to the function.
    + * @wait: If true, wait (atomically) until function has completed on other CPUs.
    + * @mask The bitmask of CPUs to call the function
    + *
    + * Returns 0 on success, else a negative status code. Does not return until
    + * remote CPUs are nearly ready to execute func or have executed it.
    + *
    + * You must not call this function with disabled interrupts or from a
    + * hardware interrupt handler or from a bottom half handler.
    + */
    +
    +int smp_call_function_on_cpu (void (*func) (void *info), void *info,
    + int wait, unsigned long mask)
    +{
    + struct call_data_struct data;
    + int num_cpus = hweight32(mask), cpu;
    +
    + if (num_cpus == 0)
    + return -EINVAL;
    +
    + cpu = get_cpu();
    + if ((1UL << cpu) & mask) {
    + put_cpu_no_resched();
    + return -EINVAL;
    + }
    +
    + data.func = func;
    + data.info = info;
    + atomic_set(&data.started, 0);
    + data.wait = wait;
    + if (wait)
    + atomic_set(&data.finished, 0);
    +
    + spin_lock(&call_lock);
    + call_data = &data;
    + wmb();
    +
    + /* Send a message to the CPUs in the mask and wait for them to respond */
    + send_IPI_mask_sequence(mask, CALL_FUNCTION_VECTOR);
    +
    + /* Wait for response */
    + while (atomic_read(&data.started) != num_cpus)
    + cpu_relax();
    +
    + if (wait)
    + while (atomic_read(&data.finished) != num_cpus)
    + cpu_relax();
    + spin_unlock(&call_lock);
    + put_cpu_no_resched();
    + return 0;
    +}
    +
    static void stop_this_cpu (void * dummy)
    {
    /*
    @@ -564,7 +618,7 @@

    void smp_send_stop(void)
    {
    - smp_call_function(stop_this_cpu, NULL, 1, 0);
    + smp_call_function(stop_this_cpu, NULL, 0);

    local_irq_disable();
    disable_local_APIC();
    Index: linux-2.5.59-bk/arch/i386/kernel/sysenter.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/kernel/sysenter.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 sysenter.c
    --- linux-2.5.59-bk/arch/i386/kernel/sysenter.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/kernel/sysenter.c 9 Feb 2003 09:23:29 -0000
    @@ -96,7 +96,7 @@

    memcpy((void *) page, sysent, sizeof(sysent));
    enable_sep_cpu(NULL);
    - smp_call_function(enable_sep_cpu, NULL, 1, 1);
    + smp_call_function(enable_sep_cpu, NULL, 1);
    return 0;
    }

    Index: linux-2.5.59-bk/arch/i386/kernel/cpu/mcheck/non-fatal.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/kernel/cpu/mcheck/non-fatal.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 non-fatal.c
    --- linux-2.5.59-bk/arch/i386/kernel/cpu/mcheck/non-fatal.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/kernel/cpu/mcheck/non-fatal.c 9 Feb 2003 09:23:29 -0000
    @@ -49,7 +49,7 @@

    static void do_mce_timer(void *data)
    {
    - smp_call_function (mce_checkregs, NULL, 1, 1);
    + smp_call_function (mce_checkregs, NULL, 1);
    }

    static DECLARE_WORK(mce_work, do_mce_timer, NULL);
    Index: linux-2.5.59-bk/arch/i386/kernel/cpu/mtrr/main.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/kernel/cpu/mtrr/main.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 main.c
    --- linux-2.5.59-bk/arch/i386/kernel/cpu/mtrr/main.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/kernel/cpu/mtrr/main.c 9 Feb 2003 09:23:29 -0000
    @@ -224,7 +224,7 @@
    atomic_set(&data.gate,0);

    /* Start the ball rolling on other CPUs */
    - if (smp_call_function(ipi_handler, &data, 1, 0) != 0)
    + if (smp_call_function(ipi_handler, &data, 0) != 0)
    panic("mtrr: timed out waiting for other CPUs\n");

    local_irq_save(flags);
    Index: linux-2.5.59-bk/arch/i386/mach-voyager/voyager_smp.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/mach-voyager/voyager_smp.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 voyager_smp.c
    --- linux-2.5.59-bk/arch/i386/mach-voyager/voyager_smp.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/mach-voyager/voyager_smp.c 9 Feb 2003 16:19:57 -0000
    @@ -1091,22 +1091,24 @@
    /* Call this function on all CPUs using the function_interrupt above
    <func> The function to run. This must be fast and non-blocking.
    <info> An arbitrary pointer to pass to the function.
    - <retry> If true, keep retrying until ready.
    <wait> If true, wait until function has completed on other CPUs.
    + <mask> a bitmask of cpus to IPI to, this shouldn't contain the current cpu.
    [RETURNS] 0 on success, else a negative status code. Does not return until
    remote CPUs are nearly ready to execute <<func>> or are or have executed.
    */
    +
    int
    -smp_call_function (void (*func) (void *info), void *info, int retry,
    - int wait)
    +smp_call_function_on_cpu (void (*func) (void *info), void *info, int wait,
    + unsigned long mask)
    {
    struct call_data_struct data;
    - __u32 mask = cpu_online_map;
    + int cpu, num_cpus = hweight32(mask);

    - mask &= ~(1<<smp_processor_id());
    -
    - if (!mask)
    - return 0;
    + cpu = get_cpu();
    + if ((num_cpus == 0) || ((1UL << cpu) & mask)) {
    + put_cpu_no_resched();
    + return -EINVAL;
    + }

    data.func = func;
    data.info = info;
    @@ -1118,8 +1120,8 @@
    spin_lock(&call_lock);
    call_data = &data;
    wmb();
    - /* Send a message to all other CPUs and wait for them to respond */
    - send_CPI_allbutself(VIC_CALL_FUNCTION_CPI);
    + /* Send a message to CPUs and wait for them to respond */
    + send_CPI(mask, VIC_CALL_FUNCTION_CPI);

    /* Wait for response */
    while (data.started)
    @@ -1130,10 +1132,28 @@
    barrier();

    spin_unlock(&call_lock);
    -
    + put_cpu_no_resched();
    return 0;
    }

    +/* Call this function on all CPUs using the function_interrupt above
    + <func> The function to run. This must be fast and non-blocking.
    + <info> An arbitrary pointer to pass to the function.
    + <wait> If true, wait until function has completed on other CPUs.
    + [RETURNS] 0 on success, else a negative status code. Does not return until
    + remote CPUs are nearly ready to execute <<func>> or are or have executed.
    +*/
    +int
    +smp_call_function (void (*func) (void *info), void *info, int wait)
    +{
    + struct call_data_struct data;
    + __u32 mask = cpu_online_map;
    +
    + mask &= ~(1<<smp_processor_id());
    +
    + return smp_call_function_on_cpu(func, info, wait, mask);
    +}
    +
    /* Sorry about the name. In an APIC based system, the APICs
    * themselves are programmed to send a timer interrupt. This is used
    * by linux to reschedule the processor. Voyager doesn't have this,
    @@ -1233,7 +1253,7 @@
    void
    flush_tlb_all(void)
    {
    - smp_call_function (flush_tlb_all_function, 0, 1, 1);
    + smp_call_function (flush_tlb_all_function, 0, 1);

    do_flush_tlb_all_local();
    }
    @@ -1276,7 +1296,7 @@
    void
    smp_send_stop(void)
    {
    - smp_call_function(smp_stop_cpu_function, NULL, 1, 1);
    + smp_call_function(smp_stop_cpu_function, NULL, 1);
    }

    /* this function is triggered in time.c when a clock tick fires
    Index: linux-2.5.59-bk/arch/i386/mm/pageattr.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/mm/pageattr.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 pageattr.c
    --- linux-2.5.59-bk/arch/i386/mm/pageattr.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/mm/pageattr.c 9 Feb 2003 09:23:29 -0000
    @@ -132,7 +132,7 @@
    static inline void flush_map(void)
    {
    #ifdef CONFIG_SMP
    - smp_call_function(flush_kernel_map, NULL, 1, 1);
    + smp_call_function(flush_kernel_map, NULL, 1);
    #endif
    flush_kernel_map(NULL);
    }
    Index: linux-2.5.59-bk/arch/i386/oprofile/nmi_int.c
    ===================================================================
    RCS file: /build/cvsroot/linux-2.5.59-bk/arch/i386/oprofile/nmi_int.c,v
    retrieving revision 1.1.1.1
    diff -u -r1.1.1.1 nmi_int.c
    --- linux-2.5.59-bk/arch/i386/oprofile/nmi_int.c 9 Feb 2003 09:08:22 -0000 1.1.1.1
    +++ linux-2.5.59-bk/arch/i386/oprofile/nmi_int.c 9 Feb 2003 09:23:29 -0000
    @@ -95,7 +95,7 @@
    * without actually triggering any NMIs as this will
    * break the core code horrifically.
    */
    - smp_call_function(nmi_cpu_setup, NULL, 0, 1);
    + smp_call_function(nmi_cpu_setup, NULL, 1);
    nmi_cpu_setup(0);
    set_nmi_callback(nmi_callback);
    oprofile_pmdev = set_nmi_pm_callback(oprofile_pm_callback);
    @@ -148,7 +148,7 @@
    {
    unset_nmi_pm_callback(oprofile_pmdev);
    unset_nmi_callback();
    - smp_call_function(nmi_cpu_shutdown, NULL, 0, 1);
    + smp_call_function(nmi_cpu_shutdown, NULL, 1);
    nmi_cpu_shutdown(0);
    }

    @@ -162,7 +162,7 @@

    static int nmi_start(void)
    {
    - smp_call_function(nmi_cpu_start, NULL, 0, 1);
    + smp_call_function(nmi_cpu_start, NULL, 1);
    nmi_cpu_start(0);
    return 0;
    }
    @@ -177,7 +177,7 @@

    static void nmi_stop(void)
    {
    - smp_call_function(nmi_cpu_stop, NULL, 0, 1);
    + smp_call_function(nmi_cpu_stop, NULL, 1);
    nmi_cpu_stop(0);
    }

    -
    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 13:33    [W:0.045 / U:92.948 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site