!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/arch/alpha/kernel/   drwxr-xr-x
Free 318.37 GB of 458.09 GB (69.5%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     irq_smp.c (5.3 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 *    linux/arch/alpha/kernel/irq_smp.c
 *
 */

#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>

#include <asm/system.h>
#include <asm/io.h>


/* Who has global_irq_lock. */
int global_irq_holder = NO_PROC_ID;

/* This protects IRQ's. */
spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED;

/* Global IRQ locking depth. */
static void *previous_irqholder = NULL;

#define MAXCOUNT 100000000


static void
show(char * str, void *where)
{
#if 0
    int i;
        unsigned long *stack;
#endif
        int cpu = smp_processor_id();

        printk("\n%s, CPU %d: %p\n", str, cpu, where);
        printk("irq:  %d [%d %d]\n",
           irqs_running(),
               local_irq_count(0),
               local_irq_count(1));

        printk("bh:   %d [%d %d]\n",
           spin_is_locked(&global_bh_lock) ? 1 : 0,
           local_bh_count(0),
           local_bh_count(1));
#if 0
        stack = (unsigned long *) &str;
        for (i = 40; i ; i--) {
        unsigned long x = *++stack;
                if (x > (unsigned long) &init_task_union &&
            x < (unsigned long) &vsprintf) {
            printk("<[%08lx]> ", x);
                }
        }
#endif
}

static inline void
wait_on_irq(int cpu, void *where)
{
    int count = MAXCOUNT;

    for (;;) {

        /*
         * Wait until all interrupts are gone. Wait
         * for bottom half handlers unless we're
         * already executing in one..
         */
        if (!irqs_running()) {
            if (local_bh_count(cpu)
                || !spin_is_locked(&global_bh_lock))
                break;
        }

        /* Duh, we have to loop. Release the lock to avoid deadlocks */
        spin_unlock(&global_irq_lock);

        for (;;) {
            if (!--count) {
                show("wait_on_irq", where);
                count = MAXCOUNT;
            }
            __sti();
            udelay(1); /* make sure to run pending irqs */
            __cli();

            if (irqs_running())
                continue;
            if (spin_is_locked(&global_irq_lock))
                continue;
            if (!local_bh_count(cpu)
                && spin_is_locked(&global_bh_lock))
                continue;
            if (spin_trylock(&global_irq_lock))
                break;
        }
    }
}

static inline void
get_irqlock(int cpu, void* where)
{
    if (!spin_trylock(&global_irq_lock)) {
        /* Do we already hold the lock?  */
        if (cpu == global_irq_holder)
            return;
        /* Uhhuh.. Somebody else got it.  Wait.  */
        spin_lock(&global_irq_lock);
    }

    /*
     * Ok, we got the lock bit.
     * But that's actually just the easy part.. Now
     * we need to make sure that nobody else is running
     * in an interrupt context. 
     */
    wait_on_irq(cpu, where);

    /*
     * Finally.
     */
#ifdef CONFIG_DEBUG_SPINLOCK
    global_irq_lock.task = current;
    global_irq_lock.previous = where;
#endif
    global_irq_holder = cpu;
    previous_irqholder = where;
}

void
__global_cli(void)
{
    int cpu = smp_processor_id();
    void *where = __builtin_return_address(0);

    /*
     * Maximize ipl.  If ipl was previously 0 and if this thread
     * is not in an irq, then take global_irq_lock.
     */
    if (swpipl(IPL_MAX) == IPL_MIN && !local_irq_count(cpu))
        get_irqlock(cpu, where);
}

void
__global_sti(void)
{
        int cpu = smp_processor_id();

        if (!local_irq_count(cpu))
        release_irqlock(cpu);
    __sti();
}

/*
 * SMP flags value to restore to:
 * 0 - global cli
 * 1 - global sti
 * 2 - local cli
 * 3 - local sti
 */
unsigned long
__global_save_flags(void)
{
        int retval;
        int local_enabled;
        unsigned long flags;
    int cpu = smp_processor_id();

        __save_flags(flags);
        local_enabled = (!(flags & 7));
        /* default to local */
        retval = 2 + local_enabled;

        /* Check for global flags if we're not in an interrupt.  */
        if (!local_irq_count(cpu)) {
                if (local_enabled)
                        retval = 1;
                if (global_irq_holder == cpu)
                        retval = 0;
    }
    return retval;
}

void
__global_restore_flags(unsigned long flags)
{
        switch (flags) {
        case 0:
                __global_cli();
                break;
        case 1:
                __global_sti();
                break;
        case 2:
                __cli();
                break;
        case 3:
                __sti();
                break;
        default:
                printk(KERN_ERR "global_restore_flags: %08lx (%p)\n",
                        flags, __builtin_return_address(0));
        }
}

/*
 * From its use, I infer that synchronize_irq() stalls a thread until
 * the effects of a command to an external device are known to have
 * taken hold.  Typically, the command is to stop sending interrupts.
 * The strategy here is wait until there is at most one processor
 * (this one) in an irq.  The memory barrier serializes the write to
 * the device and the subsequent accesses of global_irq_count.
 * --jmartin
 */
#define DEBUG_SYNCHRONIZE_IRQ 0

void
synchronize_irq(void)
{
#if 0
    /* Joe's version.  */
    int cpu = smp_processor_id();
    int local_count;
    int global_count;
    int countdown = 1<<24;
    void *where = __builtin_return_address(0);

    mb();
    do {
        local_count = local_irq_count(cpu);
        global_count = atomic_read(&global_irq_count);
        if (DEBUG_SYNCHRONIZE_IRQ && (--countdown == 0)) {
            printk("%d:%d/%d\n", cpu, local_count, global_count);
            show("synchronize_irq", where);
            break;
        }
    } while (global_count != local_count);
#else
    /* Jay's version.  */
    if (irqs_running()) {
        cli();
        sti();
    }
#endif
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0268 ]--