Re: Regarding Devfreq

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2012/4/17 Satendra... <satendra.pratap@xxxxxxxxx>:
> Hi Ham,
>
> On 16 April 2012 17:40, MyungJoo Ham <myungjoo.ham@xxxxxxxxx> wrote:
>>
>> On Mon, Apr 16, 2012 at 7:19 PM, MyungJoo Ham <myungjoo.ham@xxxxxxxxx>
>> wrote:
>> > On Mon, Apr 16, 2012 at 4:02 PM, Satendra... <satendra.pratap@xxxxxxxxx>
>> > wrote:
>> >> Hi Ham,
>> >>
>> >> I have used jiffies to calculate the busy time and total time for a
>> >> module
>> >> (made of 'n' functions say).
>> >> I have added a bew structure:
>> >
>> > Hi.
>> >
>> > In my ARM SoC systems, one jiffy is 5ms. I don't think other systems
>> > won't vary too much (should be around several hundred us to several
>> > ms). Are you sure that jiffy has enough granularity for your system?
>> > If you are counting the length spent in a function call, shouldn't
>> > nsecs be usec? (ktime?). And for saving such values, the
>> > "private_data" is intended for individual devfreq drivers
>> > communicating with governors specific to the drivers. Devfreq->data is
>> > intended for individual devfreq governors. Thus, yes, platform-data is
>> > the right place for devfreq driver internal.
>> >
>> > Cheers!
>> > MyungJoo.
>> >
>>
>> Ah.. and one missing point:
>>
>> Please consider the concurrency. You may have multiple instance of
>> function calls in your device driver. And please do not block them by
>> simply adding locks there if this performance counting is the only
>> reason to make them mutually exclusive. This is another reason to
>> count nsecs (ktime) locally in the function and add the end-start
>> (local variable) into the aggregation variable (lock here only or use
>> atomic operators).
>>
>> Cheers!
>> MyungJoo.
>>
>
> Yes thats true that we will have multiple instances of function calls but
> every instance of driver
> will have its own copy of counters which can be accessed through platform
> data.

Even if each instance of driver has its own data structure, there
could be concurrent function calls to one driver, which will cause
problems.

I'm not talking about:
Thread 1: do_something_on(dev A)
Thread 2: do_something_on(dev B)
I'm talking about:
Thread 1: do_something_on(dev A)
Thread 2: do_something_on(dev A)


> So AFAICS we need not to worry about concurrency issue because no instance
> will touch the
> counters of another instance. Please correct if i am wrong.
>
> Below is the code using ktime API:
>
> typedef struct devfreq_perf_counters {
> #ifdef DEVFREQ_USE_KTIME
>         ktime_t fentry_time; /* jiffies at the enrty of a func */
>         ktime_t start_time; /* starting jiffies for every busy/total \
>                              load cal in the last x seconds*/
>         ktime_t prev_count; /* last jiffies count */
>         s64 busy_time; /* total execution jiffies count in the last \
>                               x seconds */
> #else
>         unsigned long fentry_time; /* jiffies at the enrty of a func */
>         unsigned long start_time; /* starting jiffies for every busy/total \
>                                              load cal in the last x
> seconds*/
>         unsigned long prev_count; /* last jiffies count */
>         unsigned long busy_time; /* total execution jiffies count in the
> last \
>                                       x seconds */
> #endif
> }devfreq_counters;
>
> #ifdef DEVFREQ_USE_KTIME
> /* using ktime */
>         #define devfreq_func_start(dc) do {\
>                 (dc)->fentry_time = ktime_get();\
>         }while(0)
>
>         #define devfreq_func_end(dc) do {\
>                 (dc)->prev_count = ktime_get();\
>                 (dc)->busy_time += ktime_to_ns(ktime_sub((dc)->prev_count, \
>                                         (dc)->fentry_time));\
>         }while(0)
>
>         #define module_busy_time(dc)    ((dc)->busy_time)
>
>         #define module_busy_plus_not_busy_time(dc) \
>                 ktime_to_ns(ktime_sub(ktime_get(), (dc)->start_time))
>
>         #define devfreq_reset_counters(dc) do { \
>                 (dc)->start_time = ktime_get();\
>         }while(0)
> #else
>         #define devfreq_func_start(dc) \
>                 (dc)->fentry_time = jiffies
>
>         #define devfreq_fun_end(dc) do { \
>                 (dc)->prev_count = (jiffies)-((dc)->fentry_time);\
>                 (dc)->busy_time += (dc)->prev_count;\
>         }while(0)
>
>         #define module_busy_time(dc) \
>                 jiffies_to_usecs((dc)->busy_time)
>
>         #define module_busy_plus_not_busy_time(dc) \
>                 jiffies_to_usecs(((jiffies) - (dc)->start_time))
>
>         #define devfreq_reset_counters(dc) do { \
>                 (dc)->fentry_time = 0UL; \
>                 (dc)->prev_count = 0UL; \
>                 (dc)->busy_time = 0UL; \
>                 (dc)->start_time = jiffies;\
>         }while(0)
> #endif
>
> Thanks,
> Satendra
>
>>
>> >>
>> >> typedef struct devfreq_perf_counters {
>> >>         unsigned long func_entry_jiffies; /* jiffies at the enrty of a
>> >> func
>> >> */
>> >>         unsigned long start_jiffies; /* starting jiffies for every
>> >> busy/total \
>> >>                                              load cal in the last x
>> >> seconds*/
>> >>         unsigned long local_jiffies; /* last jiffies count */
>> >>         unsigned long busy_jiffies; /* total execution jiffies count in
>> >> the
>> >> last \
>> >>                                       x seconds */
>> >> }devfreq_counters;
>> >>
>> >> This structure's instance can be included in the platform_data(or
>> >> private
>> >> data) of the
>> >> driver which has to register itself with devfreq. This way while doing
>> >> set_drv_data, access
>> >> to these counters could be available all the time.
>> >>
>> >> Now there is one initialization function :
>> >>
>> >> void devfreq_counters_init(void *data)
>> >> {
>> >>         devfreq_counters **dc = &data->dpc;
>> >>
>> >>         *dc = kzalloc(sizeof (devfreq_counters), GFP_KERNEL);
>> >>
>> >>         (*dc)->func_entry_jiffies = 0UL;
>> >>         (*dc)->local_jiffies = 0UL;
>> >>         (*dc)->busy_jiffies = 0UL;
>> >>         (*dc)->start_jiffies = jiffies;
>> >>
>> >>         return;
>> >> }
>> >>
>> >> This function initializes the counters and is called at the end of
>> >> driver
>> >> initialiation function.
>> >>
>> >> Now there is a list of APIs as shown below:
>> >>
>> >> #define devfreq_jiffies_start(dc) \
>> >>         dc->func_entry_jiffies = jiffies
>> >>
>> >> #define devfreq_jiffies_end(dc) do { \
>> >>         dc->local_jiffies = (jiffies)-(dc->func_entry_jiffies);\
>> >>         dc->busy_jiffies += dc->local_jiffies;\
>> >> }while(0)
>> >>
>> >> #define busy_jiffies_in_usec(dc) \
>> >>         jiffies_to_usecs((dc)->busy_jiffies)
>> >>
>> >> #define busy_plus_not_busy_jiffies_in_usec(dc) \
>> >>         jiffies_to_usecs(((jiffies) - (dc)->start_jiffies))
>> >>
>> >> #define devfreq_reset_counters(dc) do { \
>> >>         dc->func_entry_jiffies = 0UL; \
>> >>         dc->local_jiffies = 0UL; \
>> >>         dc->busy_jiffies = 0UL; \
>> >>         dc->start_jiffies = jiffies;\
>> >> }while(0)
>> >>
>> >> Description:
>> >> - devfreq_jiffies_start(dc): Will be called in the start of the
>> >> function
>> >> (this is one of the functions
>> >> which we want to consider in measuring the busy time of the driver)
>> >> - devfreq_jiffies_end(dc): Will be called at the end of that function
>> >> - busy_jiffies_in_usec(dc): Will return jiffies for which all
>> >> considered
>> >> (for busy time) driver's
>> >> functions were busy
>> >> - busy_plus_not_busy_jiffies_in_usec(dc): Total jiffies i.e. busy time
>> >> + not
>> >> busy time of driver
>> >> - devfreq_reset_counters(dc): obvious
>> >>
>> >> I wanted the simple solution to busy and load and i thought about this.
>> >> This
>> >> solution hasn't been verified
>> >> yet.
>> >>
>> >> Ham, can you please provide your views on it.
>> >>
>> >> Thanks,
>> >> Satendra
>> >>
>> >>
>> >> On 29 March 2012 07:44, MyungJoo Ham <myungjoo.ham@xxxxxxxxx> wrote:
>> >>>
>> >>> 2012/3/28 Satendra... <satendra.pratap@xxxxxxxxx>
>> >>> >
>> >>> > Hi Ham,
>> >>> >
>> >>> > In the below struct :
>> >>> > struct devfreq_dev_status {
>> >>> >         /* both since the last measure */
>> >>> >         unsigned long total_time;
>> >>> >         unsigned long busy_time;
>> >>> >         unsigned long current_frequency;
>> >>> >         void *private_data;
>> >>> > };
>> >>> >
>> >>> > How to calculate total_time/busy_time? Does it require hardware
>> >>> > support
>> >>> > (may be some performance counters)?
>> >>> >
>> >>> > Thanks,
>> >>> > Satendra
>> >>>
>> >>> It is decided by each devfreq device driver, which is why
>> >>> get_dev_status() is to be provided by the devfreq device driver.
>> >>>
>> >>> If the device has performance counters, then, it's great, but
>> >>> performance counters are not mandatory.
>> >>>
>> >>> Here goes a list of mechanisms to fetch busy/total time:
>> >>> - Performance counters
>> >>> - Measure the time between "operation start" and "operation end" and
>> >>> accumulate the time (getting busy time. probably by ktime?)
>> >>> - Measure the idle time (CPUIDLE/CPUFREQ does this)
>> >>> - Count the number of operation and calculate the operational time
>> >>> based on the number.
>> >>> - and so on.
>> >>>
>> >>> As you can see in the list, you don't need a hardware support such as
>> >>> performance counters.
>> >>>
>> >>>
>> >>>
>> >>> Cheers!
>> >>> MyungJoo.
>> >>>
>> >>> >
>> >>> >
>> >>> > On 21 March 2012 15:49, 함명주 <myungjoo.ham@xxxxxxxxxxx> wrote:
>> >>> >>
>> >>> >> Hi Stendra,
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> - Bascially, you can determine the voltage based on frequency;
>> >>> >> thus, we
>> >>> >> do not need to determint voltages at DVFS framework. It is
>> >>> >> corresponding
>> >>> >> device driver's responsibility even when we have AVS features.
>> >>> >> Thus,
>> >>> >> yes,
>> >>> >> the target callback needs to control both frequency and voltage
>> >>> >> (and
>> >>> >> anything else required to change the frequency/voltage)
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> - I recommend to use regulator framework to control regulators
>> >>> >> unless
>> >>> >> you
>> >>> >> really really need to ignore regulator framework. Don't reinvent
>> >>> >> the
>> >>> >> wheel.
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> - The three steps you've mentioned are correct.
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> - The mailing list is opened to all. You are welcomed to use it
>> >>> >> (CC'ed
>> >>> >> linux-pm) and just CC needed people.
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> Cheers!
>> >>> >>
>> >>> >> MyungJoo.
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> ------- Original Message -------
>> >>> >>
>> >>> >> Sender : Satendra...<satendra.pratap@xxxxxxxxx>
>> >>> >>
>> >>> >> Date : 2012-03-21 19:03 (GMT+09:00)
>> >>> >>
>> >>> >> Title : Re: Re: Regarding Devfreq
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> Hi Ham,
>> >>> >>
>> >>> >> Thank you very much for your reply. I will try not to disturb you
>> >>> >> much.
>> >>> >> In Devfreq I dont see any API related to voltage scaling. Is it the
>> >>> >> "->target" function's (in  struct devfreq_dev_profile)
>> >>> >> responsibility to change the voltage as well with frequency?
>> >>> >> Do we really need to register our regulators using regulator
>> >>> >> framework
>> >>> >> of
>> >>> >> linux for voltage scaling?
>> >>> >>
>> >>> >> For a clear understanding I need to do following to use devfreq (I
>> >>> >> am
>> >>> >> sorry as I may be verifying it again):
>> >>> >> - define an instance of "struct devfreq_dev_profile" and provide
>> >>> >> implementations of target, get_dev_status and exit callbacks
>> >>> >> - Implement our choice of governer or use any one from already
>> >>> >> implemented ones.
>> >>> >> - call "devfreq_add_device" function from our driver's probe
>> >>> >> function.
>> >>> >>
>> >>> >> is that it? or do we need to do something else also?
>> >>> >>
>> >>> >> Thanks,
>> >>> >> Satendra
>> >>> >>
>> >>> >>
>> >>> >> On 21 March 2012 15:14, 함명주 <myungjoo.ham@xxxxxxxxxxx> wrote:
>> >>> >>>
>> >>> >>> Hello Satendra,
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>> - For Devfreq, OPP is optional though recommended for easier
>> >>> >>> implementation. You can still implement all the needed things
>> >>> >>> without
>> >>> >>> OPP.
>> >>> >>> OPP is just a simple data structure to store pairs of voltage and
>> >>> >>> frequency.
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>> - Yes, you need to call devfreq_add_device() and supply the
>> >>> >>> required
>> >>> >>> data. You can implement your own governor or use one of predefined
>> >>> >>> governors. Runtime replacement of governors like CPUfreq is "TODO"
>> >>> >>> for
>> >>> >>> now.
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>> - For example, you can see /drivers/devfreq/exynos4_bus.c. GPU,
>> >>> >>> Display
>> >>> >>> devfreq drivers are under development in other companies (ARM).
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>> Cheers!
>> >>> >>>
>> >>> >>> MyungJoo.
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>> ------- Original Message -------
>> >>> >>>
>> >>> >>> Sender : Satendra...<satendra.pratap@xxxxxxxxx>
>> >>> >>>
>> >>> >>> Date : 2012-03-21 17:31 (GMT+09:00)
>> >>> >>>
>> >>> >>> Title : Re: Regarding Devfreq
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>> Hi Ham,
>> >>> >>>
>> >>> >>> I have studied DVFS and what I feel is that we need to use OPP and
>> >>> >>> Voltage regulator interfaces also to
>> >>> >>> maintain Optimum Performance Points and to provide APIs to change
>> >>> >>> the
>> >>> >>> voltage.
>> >>> >>> What I feel is that to use DVFS every driver has to
>> >>> >>> call devfreq_add_device function to register that device to
>> >>> >>> the devfreq framework. And in order to do that we have to
>> >>> >>> implement devfreq_dev_profile and our choice of governer.
>> >>> >>>
>> >>> >>> I appreciate your help.
>> >>> >>>
>> >>> >>> Thanks,
>> >>> >>> Satendra
>> >>> >>>
>> >>> >>> On 20 March 2012 12:16, Satendra... <satendra.pratap@xxxxxxxxx>
>> >>> >>> wrote:
>> >>> >>>>
>> >>> >>>> Hi Ham,
>> >>> >>>>
>> >>> >>>> We are working on a new SoC for our new product and would want to
>> >>> >>>> use
>> >>> >>>> your Devfreq
>> >>> >>>> framework for our devices. Would you please let me know any other
>> >>> >>>> implementation which
>> >>> >>>> uses devfreq ? so that we could take that as a reference.
>> >>> >>>> Or we would be the first one to start?
>> >>> >>>>
>> >>> >>>> Thanks,
>> >>> >>>> Satendra
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>> --
>> >>> >>>
>> >>> >>> MyungJoo Ham (함명주), PHD
>> >>> >>>
>> >>> >>> System S/W Lab, S/W Platform Team, Software Center
>> >>> >>> Samsung Electronics
>> >>> >>> Cell: +82-10-6714-2858
>> >>> >>>
>> >>> >>>
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> --
>> >>> >>
>> >>> >> MyungJoo Ham (함명주), PHD
>> >>> >>
>> >>> >> System S/W Lab, S/W Platform Team, Software Center
>> >>> >> Samsung Electronics
>> >>> >> Cell: +82-10-6714-2858
>> >>> >>
>> >>> >>
>> >>> >
>> >>> >
>> >>> >
>> >>> > _______________________________________________
>> >>> > linux-pm mailing list
>> >>> > linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx
>> >>> > https://lists.linuxfoundation.org/mailman/listinfo/linux-pm
>> >>>
>> >>>
>> >>>
>> >>>
>> >>> --
>> >>> MyungJoo Ham, Ph.D.
>> >>> System S/W Lab, S/W Center, Samsung Electronics
>> >>
>> >>
>> >
>> >
>> >
>> > --
>> > MyungJoo Ham, Ph.D.
>> > System S/W Lab, S/W Center, Samsung Electronics
>>
>>
>>
>> --
>> MyungJoo Ham, Ph.D.
>> System S/W Lab, S/W Center, Samsung Electronics
>
>



-- 
MyungJoo Ham, Ph.D.
System S/W Lab, S/W Center, Samsung Electronics
_______________________________________________
linux-pm mailing list
linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linuxfoundation.org/mailman/listinfo/linux-pm



[Index of Archives]     [Linux ACPI]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [CPU Freq]     [Kernel Newbies]     [Fedora Kernel]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux