linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* How to check whether executing in atomic context?
@ 2009-10-14  6:36 Leonidas .
  2009-10-14  9:21 ` Leonidas .
  0 siblings, 1 reply; 11+ messages in thread
From: Leonidas . @ 2009-10-14  6:36 UTC (permalink / raw)
  To: linux-kernel

Hi List,

I am working on a profiler kind of module, the exported apis of my
module can be
called from process context and interrupt context as well. Depending on the
context I am called in, I need to call sleepable/nonsleepable variants
of my internal
bookkeeping functions.

I am aware of in_interrupt() call which can be used to check current
context and take action
accordingly.

Is there any api which can help figure out whether we are executing
while hold a spinlock? I.e
an api which can help figure out sleepable/nonsleepable context? If it
is not there, what can
be done for writing the same? Any pointers will be helpful.

-Leo.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How to check whether executing in atomic context?
  2009-10-14  6:36 How to check whether executing in atomic context? Leonidas .
@ 2009-10-14  9:21 ` Leonidas .
  2009-10-14  9:34   ` Leonidas .
  2009-10-14 10:13   ` Gleb Natapov
  0 siblings, 2 replies; 11+ messages in thread
From: Leonidas . @ 2009-10-14  9:21 UTC (permalink / raw)
  To: linux-kernel

On Tue, Oct 13, 2009 at 11:36 PM, Leonidas . <leonidas137@gmail.com> wrote:
> Hi List,
>
> I am working on a profiler kind of module, the exported apis of my
> module can be
> called from process context and interrupt context as well. Depending on the
> context I am called in, I need to call sleepable/nonsleepable variants
> of my internal
> bookkeeping functions.
>
> I am aware of in_interrupt() call which can be used to check current
> context and take action
> accordingly.
>
> Is there any api which can help figure out whether we are executing
> while hold a spinlock? I.e
> an api which can help figure out sleepable/nonsleepable context? If it
> is not there, what can
> be done for writing the same? Any pointers will be helpful.
>
> -Leo.
>

  While searching through the sources, I found this,

  97/*
  98 * Are we running in atomic context?  WARNING: this macro cannot
  99 * always detect atomic context; in particular, it cannot know about
 100 * held spinlocks in non-preemptible kernels.  Thus it should not be
 101 * used in the general case to determine whether sleeping is possible.
 102 * Do not use in_atomic() in driver code.
 103 */
 104#define in_atomic()     ((preempt_count() & ~PREEMPT_ACTIVE) !=
PREEMPT_INATOMIC_BASE)
 105

this just complicates the matter, right? This does not work in general
case but I think this
will always work if the kernel is preemptible.

Is there no way to write a generic macro?


-Leo.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How to check whether executing in atomic context?
  2009-10-14  9:21 ` Leonidas .
@ 2009-10-14  9:34   ` Leonidas .
  2009-10-14 10:13   ` Gleb Natapov
  1 sibling, 0 replies; 11+ messages in thread
From: Leonidas . @ 2009-10-14  9:34 UTC (permalink / raw)
  To: linux-kernel

On Wed, Oct 14, 2009 at 2:21 AM, Leonidas . <leonidas137@gmail.com> wrote:
> On Tue, Oct 13, 2009 at 11:36 PM, Leonidas . <leonidas137@gmail.com> wrote:
>> Hi List,
>>
>> I am working on a profiler kind of module, the exported apis of my
>> module can be
>> called from process context and interrupt context as well. Depending on the
>> context I am called in, I need to call sleepable/nonsleepable variants
>> of my internal
>> bookkeeping functions.
>>
>> I am aware of in_interrupt() call which can be used to check current
>> context and take action
>> accordingly.
>>
>> Is there any api which can help figure out whether we are executing
>> while hold a spinlock? I.e
>> an api which can help figure out sleepable/nonsleepable context? If it
>> is not there, what can
>> be done for writing the same? Any pointers will be helpful.
>>
>> -Leo.
>>
>
>  While searching through the sources, I found this,
>
>  97/*
>  98 * Are we running in atomic context?  WARNING: this macro cannot
>  99 * always detect atomic context; in particular, it cannot know about
>  100 * held spinlocks in non-preemptible kernels.  Thus it should not be
>  101 * used in the general case to determine whether sleeping is possible.
>  102 * Do not use in_atomic() in driver code.
>  103 */
>  104#define in_atomic()     ((preempt_count() & ~PREEMPT_ACTIVE) !=
> PREEMPT_INATOMIC_BASE)
>  105
>
> this just complicates the matter, right? This does not work in general
> case but I think this
> will always work if the kernel is preemptible.
>
> Is there no way to write a generic macro?
>
>
> -Leo.
>

Just saw this:

http://thread.gmane.org/gmane.linux.kernel.wireless.general/12716

Looks like, there is no way to figure out that.


-Leo.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How to check whether executing in atomic context?
  2009-10-14  9:21 ` Leonidas .
  2009-10-14  9:34   ` Leonidas .
@ 2009-10-14 10:13   ` Gleb Natapov
  2009-10-14 10:24     ` Leonidas .
  1 sibling, 1 reply; 11+ messages in thread
From: Gleb Natapov @ 2009-10-14 10:13 UTC (permalink / raw)
  To: Leonidas .; +Cc: linux-kernel

On Wed, Oct 14, 2009 at 02:21:22AM -0700, Leonidas . wrote:
> On Tue, Oct 13, 2009 at 11:36 PM, Leonidas . <leonidas137@gmail.com> wrote:
> > Hi List,
> >
> > I am working on a profiler kind of module, the exported apis of my
> > module can be
> > called from process context and interrupt context as well. Depending on the
> > context I am called in, I need to call sleepable/nonsleepable variants
> > of my internal
> > bookkeeping functions.
> >
> > I am aware of in_interrupt() call which can be used to check current
> > context and take action
> > accordingly.
> >
> > Is there any api which can help figure out whether we are executing
> > while hold a spinlock? I.e
> > an api which can help figure out sleepable/nonsleepable context? If it
> > is not there, what can
> > be done for writing the same? Any pointers will be helpful.
> >
> > -Leo.
> >
> 
>   While searching through the sources, I found this,
> 
>   97/*
>   98 * Are we running in atomic context?  WARNING: this macro cannot
>   99 * always detect atomic context; in particular, it cannot know about
>  100 * held spinlocks in non-preemptible kernels.  Thus it should not be
>  101 * used in the general case to determine whether sleeping is possible.
>  102 * Do not use in_atomic() in driver code.
>  103 */
>  104#define in_atomic()     ((preempt_count() & ~PREEMPT_ACTIVE) !=
> PREEMPT_INATOMIC_BASE)
>  105
> 
> this just complicates the matter, right? This does not work in general
> case but I think this
> will always work if the kernel is preemptible.
> 
> Is there no way to write a generic macro?
> 
> 
Attached patch make in_atomic() to work for non-preemptable kernels too.
Doesn't look to big or scary.

Disclaimer: tested only inside kvm guest 64bit, haven't measured overhead.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 6d527ee..a6b6040 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -92,12 +92,11 @@
  */
 #define in_nmi()	(preempt_count() & NMI_MASK)
 
+#define PREEMPT_CHECK_OFFSET 1
 #if defined(CONFIG_PREEMPT)
 # define PREEMPT_INATOMIC_BASE kernel_locked()
-# define PREEMPT_CHECK_OFFSET 1
 #else
 # define PREEMPT_INATOMIC_BASE 0
-# define PREEMPT_CHECK_OFFSET 0
 #endif
 
 /*
@@ -116,12 +115,11 @@
 #define in_atomic_preempt_off() \
 		((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET)
 
+#define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #ifdef CONFIG_PREEMPT
 # define preemptible()	(preempt_count() == 0 && !irqs_disabled())
-# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #else
 # define preemptible()	0
-# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
 
 #if defined(CONFIG_SMP) || defined(CONFIG_GENERIC_HARDIRQS)
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index 72b1a10..7d039ca 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -82,14 +82,24 @@ do { \
 
 #else
 
-#define preempt_disable()		do { } while (0)
-#define preempt_enable_no_resched()	do { } while (0)
-#define preempt_enable()		do { } while (0)
+#define preempt_disable() \
+do { \
+	inc_preempt_count(); \
+	barrier(); \
+} while (0)
+
+#define preempt_enable() \
+do { \
+	barrier(); \
+	dec_preempt_count(); \
+} while (0)
+
+#define preempt_enable_no_resched()	preempt_enable()
 #define preempt_check_resched()		do { } while (0)
 
-#define preempt_disable_notrace()		do { } while (0)
-#define preempt_enable_no_resched_notrace()	do { } while (0)
-#define preempt_enable_notrace()		do { } while (0)
+#define preempt_disable_notrace()		preempt_disable()
+#define preempt_enable_no_resched_notrace()	preempt_enable()
+#define preempt_enable_notrace()		preempt_enable()
 
 #endif
 
diff --git a/kernel/sched.c b/kernel/sched.c
index 1535f38..841e0d0 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2556,10 +2556,8 @@ void sched_fork(struct task_struct *p, int clone_flags)
 #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
 	p->oncpu = 0;
 #endif
-#ifdef CONFIG_PREEMPT
 	/* Want to start with kernel preemption disabled. */
 	task_thread_info(p)->preempt_count = 1;
-#endif
 	plist_node_init(&p->pushable_tasks, MAX_PRIO);
 
 	put_cpu();
@@ -6943,11 +6941,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
 	spin_unlock_irqrestore(&rq->lock, flags);
 
 	/* Set the preempt count _outside_ the spinlocks! */
-#if defined(CONFIG_PREEMPT)
 	task_thread_info(idle)->preempt_count = (idle->lock_depth >= 0);
-#else
-	task_thread_info(idle)->preempt_count = 0;
-#endif
 	/*
 	 * The idle tasks have their own, simple scheduling class:
 	 */
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c
index 39f1029..6e2659d 100644
--- a/lib/kernel_lock.c
+++ b/lib/kernel_lock.c
@@ -93,6 +93,7 @@ static inline void __lock_kernel(void)
  */
 static inline void __lock_kernel(void)
 {
+	preempt_disable();
 	_raw_spin_lock(&kernel_flag);
 }
 #endif
--
			Gleb.

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: How to check whether executing in atomic context?
  2009-10-14 10:13   ` Gleb Natapov
@ 2009-10-14 10:24     ` Leonidas .
  2009-10-14 17:39       ` Stefan Richter
  0 siblings, 1 reply; 11+ messages in thread
From: Leonidas . @ 2009-10-14 10:24 UTC (permalink / raw)
  To: Gleb Natapov; +Cc: linux-kernel

On Wed, Oct 14, 2009 at 3:13 AM, Gleb Natapov <gleb@redhat.com> wrote:
> On Wed, Oct 14, 2009 at 02:21:22AM -0700, Leonidas . wrote:
>> On Tue, Oct 13, 2009 at 11:36 PM, Leonidas . <leonidas137@gmail.com> wrote:
>> > Hi List,
>> >
>> > I am working on a profiler kind of module, the exported apis of my
>> > module can be
>> > called from process context and interrupt context as well. Depending on the
>> > context I am called in, I need to call sleepable/nonsleepable variants
>> > of my internal
>> > bookkeeping functions.
>> >
>> > I am aware of in_interrupt() call which can be used to check current
>> > context and take action
>> > accordingly.
>> >
>> > Is there any api which can help figure out whether we are executing
>> > while hold a spinlock? I.e
>> > an api which can help figure out sleepable/nonsleepable context? If it
>> > is not there, what can
>> > be done for writing the same? Any pointers will be helpful.
>> >
>> > -Leo.
>> >
>>
>>   While searching through the sources, I found this,
>>
>>   97/*
>>   98 * Are we running in atomic context?  WARNING: this macro cannot
>>   99 * always detect atomic context; in particular, it cannot know about
>>  100 * held spinlocks in non-preemptible kernels.  Thus it should not be
>>  101 * used in the general case to determine whether sleeping is possible.
>>  102 * Do not use in_atomic() in driver code.
>>  103 */
>>  104#define in_atomic()     ((preempt_count() & ~PREEMPT_ACTIVE) !=
>> PREEMPT_INATOMIC_BASE)
>>  105
>>
>> this just complicates the matter, right? This does not work in general
>> case but I think this
>> will always work if the kernel is preemptible.
>>
>> Is there no way to write a generic macro?
>>
>>
> Attached patch make in_atomic() to work for non-preemptable kernels too.
> Doesn't look to big or scary.
>
> Disclaimer: tested only inside kvm guest 64bit, haven't measured overhead.
>
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
> index 6d527ee..a6b6040 100644
> --- a/include/linux/hardirq.h
> +++ b/include/linux/hardirq.h
> @@ -92,12 +92,11 @@
>  */
>  #define in_nmi()       (preempt_count() & NMI_MASK)
>
> +#define PREEMPT_CHECK_OFFSET 1
>  #if defined(CONFIG_PREEMPT)
>  # define PREEMPT_INATOMIC_BASE kernel_locked()
> -# define PREEMPT_CHECK_OFFSET 1
>  #else
>  # define PREEMPT_INATOMIC_BASE 0
> -# define PREEMPT_CHECK_OFFSET 0
>  #endif
>
>  /*
> @@ -116,12 +115,11 @@
>  #define in_atomic_preempt_off() \
>                ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET)
>
> +#define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
>  #ifdef CONFIG_PREEMPT
>  # define preemptible() (preempt_count() == 0 && !irqs_disabled())
> -# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
>  #else
>  # define preemptible() 0
> -# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
>  #endif
>
>  #if defined(CONFIG_SMP) || defined(CONFIG_GENERIC_HARDIRQS)
> diff --git a/include/linux/preempt.h b/include/linux/preempt.h
> index 72b1a10..7d039ca 100644
> --- a/include/linux/preempt.h
> +++ b/include/linux/preempt.h
> @@ -82,14 +82,24 @@ do { \
>
>  #else
>
> -#define preempt_disable()              do { } while (0)
> -#define preempt_enable_no_resched()    do { } while (0)
> -#define preempt_enable()               do { } while (0)
> +#define preempt_disable() \
> +do { \
> +       inc_preempt_count(); \
> +       barrier(); \
> +} while (0)
> +
> +#define preempt_enable() \
> +do { \
> +       barrier(); \
> +       dec_preempt_count(); \
> +} while (0)
> +
> +#define preempt_enable_no_resched()    preempt_enable()
>  #define preempt_check_resched()                do { } while (0)
>
> -#define preempt_disable_notrace()              do { } while (0)
> -#define preempt_enable_no_resched_notrace()    do { } while (0)
> -#define preempt_enable_notrace()               do { } while (0)
> +#define preempt_disable_notrace()              preempt_disable()
> +#define preempt_enable_no_resched_notrace()    preempt_enable()
> +#define preempt_enable_notrace()               preempt_enable()
>
>  #endif
>
> diff --git a/kernel/sched.c b/kernel/sched.c
> index 1535f38..841e0d0 100644
> --- a/kernel/sched.c
> +++ b/kernel/sched.c
> @@ -2556,10 +2556,8 @@ void sched_fork(struct task_struct *p, int clone_flags)
>  #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
>        p->oncpu = 0;
>  #endif
> -#ifdef CONFIG_PREEMPT
>        /* Want to start with kernel preemption disabled. */
>        task_thread_info(p)->preempt_count = 1;
> -#endif
>        plist_node_init(&p->pushable_tasks, MAX_PRIO);
>
>        put_cpu();
> @@ -6943,11 +6941,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
>        spin_unlock_irqrestore(&rq->lock, flags);
>
>        /* Set the preempt count _outside_ the spinlocks! */
> -#if defined(CONFIG_PREEMPT)
>        task_thread_info(idle)->preempt_count = (idle->lock_depth >= 0);
> -#else
> -       task_thread_info(idle)->preempt_count = 0;
> -#endif
>        /*
>         * The idle tasks have their own, simple scheduling class:
>         */
> diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c
> index 39f1029..6e2659d 100644
> --- a/lib/kernel_lock.c
> +++ b/lib/kernel_lock.c
> @@ -93,6 +93,7 @@ static inline void __lock_kernel(void)
>  */
>  static inline void __lock_kernel(void)
>  {
> +       preempt_disable();
>        _raw_spin_lock(&kernel_flag);
>  }
>  #endif
> --
>                        Gleb.
>

Unbelievable! I was just thinking about the logic to achieve the same, and
someone has already done this. Thanks for the patch.

Actually, in my case, I dont think I will be able to patch and rebuild
the kernel.
Also, my use case is also much simpler, I just want to call kmalloc
depending on
the context I am running in, by giving appropriate flags.

So, I am doing something like this:

if(preemptible())
    flags = (in_atomic() == 0) ? GFP_KERNEL : GFP_ATOMIC;
else
     /*Cant afford failing, dont care abt emergency pool depleting etc*/
    flags = GFP_ATOMIC

kmalloc(size, flags);

I am aware that, in_atomic() should not be used by drivers/modules
except core kernel,
but there is no other provision, I cant change the interfaces of the
function calls or have
two copies of functions i.e. sleepable/nonsleepable since the profiler
I am porting is
originally written for BSD.

-Leo.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How to check whether executing in atomic context?
  2009-10-14 10:24     ` Leonidas .
@ 2009-10-14 17:39       ` Stefan Richter
  2009-10-14 19:11         ` Leonidas .
  0 siblings, 1 reply; 11+ messages in thread
From: Stefan Richter @ 2009-10-14 17:39 UTC (permalink / raw)
  To: Leonidas .; +Cc: Gleb Natapov, linux-kernel

On 10/14/2009 12:24 PM, Leonidas . wrote:
> On Wed, Oct 14, 2009 at 3:13 AM, Gleb Natapov <gleb@redhat.com> wrote:
>> On Wed, Oct 14, 2009 at 02:21:22AM -0700, Leonidas . wrote:
>>> On Tue, Oct 13, 2009 at 11:36 PM, Leonidas . <leonidas137@gmail.com> wrote:
>>> > Hi List,
>>> >
>>> > I am working on a profiler kind of module, the exported apis of my module can be
>>> > called from process context and interrupt context as well. Depending on the
>>> > context I am called in, I need to call sleepable/nonsleepable variants
>>> > of my internal bookkeeping functions.
>>> >
>>> > I am aware of in_interrupt() call which can be used to check current
>>> > context and take action accordingly.
>>> >
>>> > Is there any api which can help figure out whether we are executing while hold a spinlock? I.e
>>> > an api which can help figure out sleepable/nonsleepable context? If it is not there, what can
>>> > be done for writing the same? Any pointers will be helpful.
[...]
>>>   While searching through the sources, I found this,
>>>
>>>   97/*
>>>   98 * Are we running in atomic context?  WARNING: this macro cannot
>>>   99 * always detect atomic context; in particular, it cannot know about
>>>  100 * held spinlocks in non-preemptible kernels.  Thus it should not be
>>>  101 * used in the general case to determine whether sleeping is possible.
>>>  102 * Do not use in_atomic() in driver code.
>>>  103 */
>>>  104#define in_atomic()     ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_INATOMIC_BASE)
>>>  105
>>>
>>> this just complicates the matter, right? This does not work in general case but I think this
>>> will always work if the kernel is preemptible.
>>>
>>> Is there no way to write a generic macro?
[...]
>> Attached patch make in_atomic() to work for non-preemptable kernels too.
>> Doesn't look to big or scary.
>>
>> Disclaimer: tested only inside kvm guest 64bit, haven't measured overhead.
[...]
> Unbelievable! I was just thinking about the logic to achieve the same, and
> someone has already done this. Thanks for the patch.

I don't know whether Gleb's patch works or doesn't work as you require
it.  But my opinion is that the recommendation "do not use in_atomic()
in driver code" is valid nevertheless.

Very often the better course of action is to change your API from

void my_routine()
{
	if (in_atomic())
		this;
	else
		that;
}

to either

void my_routine(bool can_sleep)
{
	if (!can_sleep)
		this;
	else
		that;
}

or to

void my_routine_atomic()
{
	this;
}

void my_routine()
{
	that;
}

In other words, let the caller of your routine tell it whether it's
atomic context or not.

Instead of a "bool can_sleep" argument, a "gfp_t flags" argument is
often used.

Or provide only the my_routine_atomic() variant if the difference to the
sleeping variant isn't huge.
-- 
Stefan Richter
-=====-==--= =-=- -===-
http://arcgraph.de/sr/

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How to check whether executing in atomic context?
  2009-10-14 17:39       ` Stefan Richter
@ 2009-10-14 19:11         ` Leonidas .
  2009-10-14 19:15           ` Stefan Richter
  0 siblings, 1 reply; 11+ messages in thread
From: Leonidas . @ 2009-10-14 19:11 UTC (permalink / raw)
  To: Stefan Richter; +Cc: Gleb Natapov, linux-kernel

On Wed, Oct 14, 2009 at 11:09 PM, Stefan Richter
<stefanr@s5r6.in-berlin.de> wrote:
> On 10/14/2009 12:24 PM, Leonidas . wrote:
>> On Wed, Oct 14, 2009 at 3:13 AM, Gleb Natapov <gleb@redhat.com> wrote:
>>> On Wed, Oct 14, 2009 at 02:21:22AM -0700, Leonidas . wrote:
>>>> On Tue, Oct 13, 2009 at 11:36 PM, Leonidas . <leonidas137@gmail.com> wrote:
>>>> > Hi List,
>>>> >
>>>> > I am working on a profiler kind of module, the exported apis of my module can be
>>>> > called from process context and interrupt context as well. Depending on the
>>>> > context I am called in, I need to call sleepable/nonsleepable variants
>>>> > of my internal bookkeeping functions.
>>>> >
>>>> > I am aware of in_interrupt() call which can be used to check current
>>>> > context and take action accordingly.
>>>> >
>>>> > Is there any api which can help figure out whether we are executing while hold a spinlock? I.e
>>>> > an api which can help figure out sleepable/nonsleepable context? If it is not there, what can
>>>> > be done for writing the same? Any pointers will be helpful.
> [...]
>>>>   While searching through the sources, I found this,
>>>>
>>>>   97/*
>>>>   98 * Are we running in atomic context?  WARNING: this macro cannot
>>>>   99 * always detect atomic context; in particular, it cannot know about
>>>>  100 * held spinlocks in non-preemptible kernels.  Thus it should not be
>>>>  101 * used in the general case to determine whether sleeping is possible.
>>>>  102 * Do not use in_atomic() in driver code.
>>>>  103 */
>>>>  104#define in_atomic()     ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_INATOMIC_BASE)
>>>>  105
>>>>
>>>> this just complicates the matter, right? This does not work in general case but I think this
>>>> will always work if the kernel is preemptible.
>>>>
>>>> Is there no way to write a generic macro?
> [...]
>>> Attached patch make in_atomic() to work for non-preemptable kernels too.
>>> Doesn't look to big or scary.
>>>
>>> Disclaimer: tested only inside kvm guest 64bit, haven't measured overhead.
> [...]
>> Unbelievable! I was just thinking about the logic to achieve the same, and
>> someone has already done this. Thanks for the patch.
>
> I don't know whether Gleb's patch works or doesn't work as you require
> it.  But my opinion is that the recommendation "do not use in_atomic()
> in driver code" is valid nevertheless.
>
> Very often the better course of action is to change your API from
>
> void my_routine()
> {
>        if (in_atomic())
>                this;
>        else
>                that;
> }
>
> to either
>
> void my_routine(bool can_sleep)
> {
>        if (!can_sleep)
>                this;
>        else
>                that;
> }
>
> or to
>
> void my_routine_atomic()
> {
>        this;
> }
>
> void my_routine()
> {
>        that;
> }
>
> In other words, let the caller of your routine tell it whether it's
> atomic context or not.
>
> Instead of a "bool can_sleep" argument, a "gfp_t flags" argument is
> often used.
>
> Or provide only the my_routine_atomic() variant if the difference to the
> sleeping variant isn't huge.
> --
> Stefan Richter
> -=====-==--= =-=- -===-
> http://arcgraph.de/sr/
>


I agree with you and earlier consensus on list about the atomic and
non-atomic variants.

The issue with my code, as I have explained briefly earlier in the
same thread is as
follows:

My apis can be inserted at any place in this code by user. I have no
control over this
part except telling user to call atomic/non-atomic apis depending on
the context.

What makes it more complicated is this, the user might achieve the
functionality via instrumenting his source code, i.e. something like
using -finstrument flag of gcc. As per above inferences about
in_atomic(), in case of instrumentation there is no choice other than
providing all apis as atomic apis, this might not be the right thing
to do under all circumstances. Especially, for my code since I do lot
of allocations for book keeping.

I am not aware of any Linux kernel module which can comply to this
kind of use case, what would be the most optimal thing to do here?

-Leo.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How to check whether executing in atomic context?
  2009-10-14 19:11         ` Leonidas .
@ 2009-10-14 19:15           ` Stefan Richter
  2009-10-14 19:22             ` Samuel Thibault
  2009-10-14 19:24             ` Leonidas .
  0 siblings, 2 replies; 11+ messages in thread
From: Stefan Richter @ 2009-10-14 19:15 UTC (permalink / raw)
  To: Leonidas .; +Cc: Gleb Natapov, linux-kernel

Leonidas . wrote:
> On Wed, Oct 14, 2009 at 11:09 PM, Stefan Richter
> <stefanr@s5r6.in-berlin.de> wrote:
>> let the caller of your routine tell it whether it's atomic context
>> or not.
[...]
> What makes it more complicated is this, the user might achieve the
> functionality via instrumenting his source code, i.e. something like
> using -finstrument flag of gcc. As per above inferences about
> in_atomic(), in case of instrumentation there is no choice other than
> providing all apis as atomic apis, this might not be the right thing
> to do under all circumstances. Especially, for my code since I do lot
> of allocations for book keeping.
> 
> I am not aware of any Linux kernel module which can comply to this
> kind of use case, what would be the most optimal thing to do here?

And preallocation is not feasible either?
-- 
Stefan Richter
-=====-==--= =-=- -===-
http://arcgraph.de/sr/

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How to check whether executing in atomic context?
  2009-10-14 19:15           ` Stefan Richter
@ 2009-10-14 19:22             ` Samuel Thibault
  2009-10-14 19:24             ` Leonidas .
  1 sibling, 0 replies; 11+ messages in thread
From: Samuel Thibault @ 2009-10-14 19:22 UTC (permalink / raw)
  To: Stefan Richter; +Cc: Leonidas ., Gleb Natapov, linux-kernel

Stefan Richter, le Wed 14 Oct 2009 21:15:39 +0200, a écrit :
> > I am not aware of any Linux kernel module which can comply to this
> > kind of use case, what would be the most optimal thing to do here?
> 
> And preallocation is not feasible either?

Or deferring work to a kernel thread.

Samuel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How to check whether executing in atomic context?
  2009-10-14 19:15           ` Stefan Richter
  2009-10-14 19:22             ` Samuel Thibault
@ 2009-10-14 19:24             ` Leonidas .
  2009-10-15  8:31               ` Leonidas .
  1 sibling, 1 reply; 11+ messages in thread
From: Leonidas . @ 2009-10-14 19:24 UTC (permalink / raw)
  To: Stefan Richter; +Cc: Gleb Natapov, linux-kernel

On Thu, Oct 15, 2009 at 12:45 AM, Stefan Richter
<stefanr@s5r6.in-berlin.de> wrote:
> Leonidas . wrote:
>> On Wed, Oct 14, 2009 at 11:09 PM, Stefan Richter
>> <stefanr@s5r6.in-berlin.de> wrote:
>>> let the caller of your routine tell it whether it's atomic context
>>> or not.
> [...]
>> What makes it more complicated is this, the user might achieve the
>> functionality via instrumenting his source code, i.e. something like
>> using -finstrument flag of gcc. As per above inferences about
>> in_atomic(), in case of instrumentation there is no choice other than
>> providing all apis as atomic apis, this might not be the right thing
>> to do under all circumstances. Especially, for my code since I do lot
>> of allocations for book keeping.
>>
>> I am not aware of any Linux kernel module which can comply to this
>> kind of use case, what would be the most optimal thing to do here?
>
> And preallocation is not feasible either?
> --
> Stefan Richter
> -=====-==--= =-=- -===-
> http://arcgraph.de/sr/
>

Yes, I preallocate a buffer at module init time. But assume that, I am
profiling kmalloc(),
and number of kmallocs() done over time increases rapidly, I need to allocate
on demand as well depending on the load. (Actually, I am not profiling kmalloc,
it just makes a good example in this case). Currently, I preallocate a
large buffer
and as I reach the threshold, I try to grab small buffers as needed.
Obvious solution
here would be to grab a larger buffer, the only issue here would be it
might be just wasteful.

So, knowing the running context and allocating sounded like a better idea to me.

-Leo.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How to check whether executing in atomic context?
  2009-10-14 19:24             ` Leonidas .
@ 2009-10-15  8:31               ` Leonidas .
  0 siblings, 0 replies; 11+ messages in thread
From: Leonidas . @ 2009-10-15  8:31 UTC (permalink / raw)
  To: Stefan Richter; +Cc: Gleb Natapov, linux-kernel

On Wed, Oct 14, 2009 at 12:24 PM, Leonidas . <leonidas137@gmail.com> wrote:
> On Thu, Oct 15, 2009 at 12:45 AM, Stefan Richter
> <stefanr@s5r6.in-berlin.de> wrote:
>> Leonidas . wrote:
>>> On Wed, Oct 14, 2009 at 11:09 PM, Stefan Richter
>>> <stefanr@s5r6.in-berlin.de> wrote:
>>>> let the caller of your routine tell it whether it's atomic context
>>>> or not.
>> [...]
>>> What makes it more complicated is this, the user might achieve the
>>> functionality via instrumenting his source code, i.e. something like
>>> using -finstrument flag of gcc. As per above inferences about
>>> in_atomic(), in case of instrumentation there is no choice other than
>>> providing all apis as atomic apis, this might not be the right thing
>>> to do under all circumstances. Especially, for my code since I do lot
>>> of allocations for book keeping.
>>>
>>> I am not aware of any Linux kernel module which can comply to this
>>> kind of use case, what would be the most optimal thing to do here?
>>
>> And preallocation is not feasible either?
>> --
>> Stefan Richter
>> -=====-==--= =-=- -===-
>> http://arcgraph.de/sr/
>>
>
> Yes, I preallocate a buffer at module init time. But assume that, I am
> profiling kmalloc(),
> and number of kmallocs() done over time increases rapidly, I need to allocate
> on demand as well depending on the load. (Actually, I am not profiling kmalloc,
> it just makes a good example in this case). Currently, I preallocate a
> large buffer
> and as I reach the threshold, I try to grab small buffers as needed.
> Obvious solution
> here would be to grab a larger buffer, the only issue here would be it
> might be just wasteful.
>
> So, knowing the running context and allocating sounded like a better idea to me.
>
> -Leo.
>

>Or deferring work to a kernel thread.

You mean, have a kernel thread periodically check the memory
requirements and do allocations in
kernel thread context? So basically, insuring that all the allocations
are done outside atomic context
i.e. either preallocate or use kernel thread.

-Leo.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2009-10-15  8:32 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-14  6:36 How to check whether executing in atomic context? Leonidas .
2009-10-14  9:21 ` Leonidas .
2009-10-14  9:34   ` Leonidas .
2009-10-14 10:13   ` Gleb Natapov
2009-10-14 10:24     ` Leonidas .
2009-10-14 17:39       ` Stefan Richter
2009-10-14 19:11         ` Leonidas .
2009-10-14 19:15           ` Stefan Richter
2009-10-14 19:22             ` Samuel Thibault
2009-10-14 19:24             ` Leonidas .
2009-10-15  8:31               ` Leonidas .

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).