3

To schedule an action to happen later in a linux kernel driver I have 2 options:

  • add_timer
  • queue_delayed_work

One difference I know about: for timers you need to specify expires which is the jiffies value when the timer will expire, for delayed work you need to specify the delay of jiffies.

I've been reading other questions about timers and work_queue's, and it mentions timers run outside process context. Is this different from delayed work?

Also I know there is an issue with timers, when calculating the expires, it might happen the value overflows, so the calculated value is smaller than the current jiffies and the timer expired immediately (correct me if I'm wrong here). Does delayed work suffer from the same issue? If it does, how do

To me it seems easier to use delayed work (because the work is not periodically). But what disadvantages over using timers?

EDIT I did some further research. It seems queue_delayed_work just uses add_timer internally.

So my new question is, how do I take properly care of the jiffies overflow for timers? For example how can I set a timer/delayed_work to a 10min delay?

Community
  • 1
  • 1
To1ne
  • 1,108
  • 2
  • 12
  • 22

3 Answers3

3

In case of kernel programming, when your callback function for timer/work needs to sleep then you have to use delayed_work. As delayed_work runs in process context you can use those function which may sleep or tends to sleep inside callback function. While in case of kernel timer you can not use those function which sleeps or tends to sleep. Conclusion: if your call back function needs sleeping use work queues else use timers/tasklets.

Hope it helps :)

The joker
  • 189
  • 1
  • 6
2

As I stated in my question, queue_delayed_work just uses add_timer internally. So the use is equally.

To1ne
  • 1,108
  • 2
  • 12
  • 22
2

Answer to your second question.

10 minutes from now, for use with a kernel timer:

// 10 minutes * 60 converts to seconds * 1000 converts to microseconds
// msecs_to_jiffies converts the resulting microsecond delay to jiffies
//   which is added to the current time (system variable jiffies)

jiffies + msecs_to_jiffies(10 * 60 *1000)

And for queuing delayed work, you would just use the 10 minute delay part:

msecs_to_jiffies(10 * 60 * 1000)

Re overflow - if you need to compare jiffies yourself, see the time_after and time_before (and other) macros http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/include/linux/jiffies.h#L93

dormouse
  • 21
  • 2