From: gosha <embedded@nm.ru> To: devel-kernel@lists.altlinux.org Subject: Re: [d-kernel] -немного недопонял, - В kernel 2.6.16 теперь ждущие блокировки spinlock() не работают?] (Sergey Vlasov) Date: Mon, 19 Jun 2006 14:27:41 +0000 Message-ID: <146102371.20060619142741@nm.ru> (raw) In-Reply-To: <mailman.17.1150606807.13795.devel-kernel@lists.altlinux.org> >Значит, этот тест был выполнен на ядре *-up, где spin_lock() >действительно ничего не делает. Spinlock используются только на SMP >для синхронизации между несколькими процессорами. Код, пытающийся >рекурсивно захватить один и тот же spinlock на одном процессоре, >недопустим - это гарантированный deadlock. > И в include/linux/spinlock*.h ничего похожего на разблокировку/ блокировку .... >Все реализации spinlock архитектурно-зависимые, и поэтому лежат в >include/asm-*. фрагмент include/linux/spinlock.h : ------------------------------------------------------- #if defined(CONFIG_SMP) # include <asm/spinlock.h> // прикомпилируются только в случае многопроцессорных систем #else # include <linux/spinlock_up.h> #endif ------------------------------------------------------- фрагмент include/linux/compiler.h : ------------------------------------------------------- #ifdef __CHECKER__ .................... # define __acquire(x) __context__(1) # define __release(x) __context__(-1) #else .......................... # define __acquire(x) (void)0 # define __release(x) (void)0 #endif ------------------------------------------------------- фрагмент include/linux/spinlock_api.h: ------------------------------------------------------- #define __LOCK(lock) do { preempt_disable(); __acquire(lock); (void)(lock); } while (0) #define __UNLOCK(lock) do { preempt_enable(); __release(lock); (void)(lock); } while (0) #define _spin_lock(lock) __LOCK(lock) #define _spin_unlock(lock) __UNLOCK(lock) ------------------------------------------------------- Т.е. для однопроцессорных систем ждущие блокировки spinlock() и не должны ничего делать в принципе?? Судя по коду это так, но это как бы нелогично... Напр касок кода /kernel/irq/hahdle.c : ------------------------------------------------------- /* do_IRQ handles all normal device IRQ's (the special SMP cross-CPU interrupts have their own specific handlers). */ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) { irq_desc_t *desc = irq_desc + irq; struct irqaction * action; unsigned int status; kstat_this_cpu.irqs[irq]++; if (CHECK_IRQ_PER_CPU(desc->status)) { irqreturn_t action_ret; /* No locking required for CPU-local interrupts: */ if (desc->handler->ack) desc->handler->ack(irq); action_ret = handle_IRQ_event(irq, regs, desc->action); desc->handler->end(irq); return 1; } spin_lock(&desc->lock); if (desc->handler->ack) desc->handler->ack(irq); /* * REPLAY is when Linux resends an IRQ that was dropped earlier * WAITING is used by probe to mark irqs that are being tested */ status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); status |= IRQ_PENDING; /* we _want_ to handle it */ /* * If the IRQ is disabled for whatever reason, we cannot * use the action we have. */ action = NULL; if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) { action = desc->action; status &= ~IRQ_PENDING; /* we commit to handling */ status |= IRQ_INPROGRESS; /* we are handling it */ } desc->status = status; /* * If there is no IRQ handler or it was disabled, exit early. * Since we set PENDING, if another processor is handling * a different instance of this same irq, the other processor * will take care of it. */ if (unlikely(!action)) goto out; /* * Edge triggered interrupts need to remember * pending events. * This applies to any hw interrupts that allow a second * instance of the same irq to arrive while we are in do_IRQ * or in the handler. But the code here only handles the _second_ * instance of the irq, not the third or fourth. So it is mostly * useful for irq hardware that does not mask cleanly in an * SMP environment. */ for (;;) { irqreturn_t action_ret; spin_unlock(&desc->lock); action_ret = handle_IRQ_event(irq, regs, action); spin_lock(&desc->lock); if (!noirqdebug) note_interrupt(irq, desc, action_ret, regs); if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; } desc->status &= ~IRQ_INPROGRESS; out: /* * The ->end() handler has to deal with interrupts which got * disabled while the handler was running. */ desc->handler->end(irq); spin_unlock(&desc->lock); return 1; } --------------------------------------------------------------------------- Также все работает в режиме CONFIG_DEBUG_SPINLOCK : #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) # include <linux/spinlock_api_smp.h> #else # include <linux/spinlock_api_up.h> #endif --------------------------------------------------------------------------- Так и должно быть??? У меня во всех книжках по линуксу написано, что это ждущая блокировка и оно должно работать как мутекс! --------------------------------------------------------------------------- -- С Уважением, gosha mailto:embedded@nm.ru
prev parent reply other threads:[~2006-06-19 14:27 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2006-06-19 9:20 ` gosha 2006-06-19 10:04 ` Sergey Vlasov 2006-06-19 14:27 ` gosha [this message]
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=146102371.20060619142741@nm.ru \ --to=embedded@nm.ru \ --cc=devel-kernel@lists.altlinux.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
ALT Linux kernel packages development This inbox may be cloned and mirrored by anyone: git clone --mirror http://lore.altlinux.org/devel-kernel/0 devel-kernel/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 devel-kernel devel-kernel/ http://lore.altlinux.org/devel-kernel \ devel-kernel@altlinux.org devel-kernel@altlinux.ru devel-kernel@altlinux.com public-inbox-index devel-kernel Example config snippet for mirrors. Newsgroup available over NNTP: nntp://lore.altlinux.org/org.altlinux.lists.devel-kernel AGPL code for this site: git clone https://public-inbox.org/public-inbox.git