On Tue, May 26, 2020 at 4:22 AM Wonsup Yoon <[email protected]> wrote:
> Thank you for the response.
>
> Yes, dynamic_percpu<T> is perfect for my purpose.
>
> However, I encountered another issue.
>
> If I use dynamic_percpu with preempt-lock (I think it is very common
> pattern), it abort due to assertion failed.
> It seems lazy binding prevents preemption lock.
> So, I had to add -fno-plt option, and it works.
>
You are right about preempt lock and your workaround for lazy binding.
However, to use a per-cpu variable, you don't need full preemption locking
- all you need is *migration* locking - in other words, the thread running
this code should not be migrated to a different CPU (this will change the
meaning of the per-cpu variable while you're using it), but it is perfectly
fine for the thread to be preempted to run a different thread - as long as
the original thread eventually returns to run on the same CPU it previously
ran on.
So just replace your use of "preempt_lock" by "migration_lock" (include
<osv/migration-lock.hh>) and everything should work, without disabling lazy
binding.
Please note that if you use the per-cpu on a thread which is already bound
to a specific CPU (which was the case in your original code you shared),
you don't even need migration lock! A pinned thread already can't migrate
to any other CPU, so it doesn't need to use this migration-avoidance
mechanism at all. You can use per-cpu variables on such threads without any
special protection.
>
>
>
> example code)
>
> #include <stdio.h>
> #include <assert.h>
>
> #include <osv/preempt-lock.hh>
> #include <osv/percpu.hh>
>
> struct counter {
> int x = 0;
>
> void inc(){
> x += 1;
> }
>
> int get(){
> return x;
> }
> };
>
> dynamic_percpu<counter> c;
>
> int main(int argc, char *argv[])
> {
> SCOPE_LOCK(preempt_lock);
> c->inc();
>
> return 0;
> }
>
>
> Backtrace)
>
> [backtrace]
> 0x000000004023875a <__assert_fail+26>
> 0x000000004035860c <elf::object::resolve_pltgot(unsigned int)+492>
> 0x0000000040358669 <elf_resolve_pltgot+57>
> 0x000000004039e2ef <???+1077535471>
> 0x000010000000f333 <???+62259>
> 0x000000004042a47c <osv::application::run_main()+60>
> 0x0000000040224bd0 <osv::application::main()+144>
> 0x000000004042a628 <???+1078109736>
> 0x0000000040462715 <???+1078339349>
> 0x00000000403fac86 <thread_main_c+38>
> 0x000000004039f632 <???+1077540402>
>
>
>
>
> 2020년 5월 24일 일요일 오후 5시 26분 17초 UTC+9, Nadav Har'El 님의 말:
>>
>>
>> On Sat, May 23, 2020 at 6:35 PM Wonsup Yoon <[email protected]> wrote:
>>
>>> Hi,
>>>
>>> I'm trying to use PERCPU macro in application or module.
>>>
>>
>> Hi,
>>
>> The PERCPU macro does not support this. What it does is to add
>> information about this variable in a special section of the executable
>> (".percpu"), then arch/x64/loader.ld makes sure all these entries will be
>> together between "_percpu_start" and "_percpu_end", and finally sched.cc
>> for every CPU creates (in the cpu::cpu(id) constructor) a copy of this
>> data. So if a loadable module (share library) contains another per-cpu
>> variable, it never gets added to the percpu area.
>>
>> However, I believe we do have a mechanism that will suite you:
>> *dynamic_percpu<T>*.
>> You can create (and destroy) such an object of type dynamic_percpu<T> at
>> any time, and it does the right thing: The variable will be allocated on
>> all CPUs when the object is created, will be allocated on new cpus if those
>> happen, and will be freed when the object is destroyed.
>> In your case you can have a global dynamic_percpu<T> variable in your
>> loadable module. This object will be created when the module is loaded, and
>> destroyed when the module is unloaded - which is what you want.
>>
>> Nadav.
>>
> --
> You received this message because you are subscribed to the Google Groups
> "OSv Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/osv-dev/07f76c69-0448-4a97-b587-995f7dbafe58%40googlegroups.com
> <https://groups.google.com/d/msgid/osv-dev/07f76c69-0448-4a97-b587-995f7dbafe58%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups "OSv
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/osv-dev/CANEVyjvJfw8_sxz%2BWFpUcMDvKpcRFFUjmcykousmEFMY0%2BVhYA%40mail.gmail.com.