Export CONFIG_ options via #version/kconfig
[akaros.git] / kern / drivers / dev / alarm.c
1 /* Copyright (c) 2013 The Regents of the University of California
2  * Copyright (c) 2016 Google Inc.
3  * Barret Rhoden <brho@cs.berkeley.edu>
4  * See LICENSE for details.
5  *
6  * #alarm: a device for registering per-process alarms.
7  *
8  * Allows a process to set up alarms, which they can tap to get events at a
9  * certain TSC time.
10  *
11  * Every process has their own alarm sets and view of #alarm; gen and friends
12  * look at current's alarmset when it is time to gen or open a file.
13  *
14  * To use, first open #alarm/clone, and that gives you an alarm directory aN,
15  * where N is ID of the alarm.  The FD you get from clone points to 'ctl.'
16  *
17  * 'ctl' takes no commands.  You can read it to get the ID.  That's it.
18  *
19  * 'timer' takes the hex string value (in absolute tsc time) to fire the alarm.
20  * Writing 0 disables the alarm.  You can read 'timer' to get the next time it
21  * will fire, in TSC time.  0 means it is disabled.  To find out about the timer
22  * firing, put an FD tap on 'timer' for FDTAP_FILT_WRITTEN.
23  *
24  * 'period' takes the hex string value (in TSC ticks) for the period of the
25  * alarm.  If non-zero, the alarm will rearm when it fires.  You can read the
26  * period.
27  *
28  * Reading the 'count' file will return the number of times the alarm has
29  * expired since the last read or the last write to 'timer'.  If this is 0, then
30  * read() will block or EAGAIN.  You cannot write 'count'.  You can tap it for
31  * FDTAP_FILT_READABLE.
32  *
33  * While each process has a separate view of #alarm, it is possible to post a
34  * chan to Qctl or Qtimer to #srv.  If another proc has your Qtimer, it can set
35  * it in the past, thereby triggering an immediate event.  More clever than
36  * useful.
37  *
38  * Notes on refcnting (the trickier parts here):
39  * - the proc_alarms have counted references to their proc
40  *              proc won't free til all alarms are closed, which is fine.  we close
41  *              all files in destroy.  if a proc drops a chan in srv, the proc will stay
42  *              alive because the alarm is alive - til that chan is closed (srvremove)
43  *
44  *              other shady ways to keep a chan alive: cd to it!  if it is ., we'd
45  *              keep a ref around.  however, only alarmdir *file* grab refs, not
46  *              directories.
47  *
48  * - proc_alarms are kref'd, since there can be multiple chans per alarm
49  *              the only thing that keeps an alarm alive is a chan on a CTL or TIMER (or
50  *              other file).  when you cloned, you got back an open CTL, which keeps the
51  *              alarm (and the dir) alive.
52  *
53  *              we need to be careful generating krefs, in case alarms are concurrently
54  *              released and removed from the lists.  just like with procs and pid2proc,
55  *              we need to sync with the source of the kref. */
56
57 #include <kmalloc.h>
58 #include <string.h>
59 #include <stdio.h>
60 #include <assert.h>
61 #include <error.h>
62 #include <pmap.h>
63 #include <sys/queue.h>
64 #include <smp.h>
65 #include <kref.h>
66 #include <atomic.h>
67 #include <alarm.h>
68 #include <umem.h>
69 #include <devalarm.h>
70
71 struct dev alarmdevtab;
72
73 static char *devname(void)
74 {
75         return alarmdevtab.name;
76 }
77
78 /* qid path types */
79 #define Qtopdir                                 1
80 #define Qclone                                  2
81 #define Qalarmdir                               3
82 #define Qctl                                    4
83 #define Qtimer                                  5       /* Qctl + 1 */
84 #define Qperiod                                 6
85 #define Qcount                                  7
86
87 /* This paddr/kaddr is a bit dangerous.  it'll work so long as we don't need all
88  * 64 bits for a physical address (48 is the current norm on x86_64). */
89 #define ADDR_SHIFT 5
90 #define QID2A(q) ((struct proc_alarm*)KADDR(((q).path >> ADDR_SHIFT)))
91 #define TYPE(q) ((q).path & ((1 << ADDR_SHIFT) - 1))
92 #define QID(ptr, type) ((PADDR(ptr) << ADDR_SHIFT) | type)
93 extern struct username eve;
94
95 static void alarm_release(struct kref *kref)
96 {
97         struct proc_alarm *a = container_of(kref, struct proc_alarm, kref);
98         struct proc *p = a->proc;
99         assert(p);
100         spin_lock(&p->alarmset.lock);
101         TAILQ_REMOVE(&p->alarmset.list, a, link);
102         spin_unlock(&p->alarmset.lock);
103         /* When this returns, the alarm has either fired or it never will */
104         unset_alarm(p->alarmset.tchain, &a->a_waiter);
105         proc_decref(p);
106         kfree(a);
107 }
108
109 static void alarm_fire_taps(struct proc_alarm *a, int filter)
110 {
111         struct fd_tap *tap_i;
112
113         SLIST_FOREACH(tap_i, &a->fd_taps, link)
114                 fire_tap(tap_i, filter);
115 }
116
117 static void proc_alarm_handler(struct alarm_waiter *a_waiter)
118 {
119         struct proc_alarm *a = container_of(a_waiter, struct proc_alarm, a_waiter);
120
121         cv_lock(&a->cv);
122         a->count++;
123         if (!a->period) {
124                 a_waiter->wake_up_time = 0;
125         } else {
126                 /* TODO: use an alarm helper, once we switch over to nsec */
127                 a_waiter->wake_up_time += a->period;
128                 set_alarm(a->proc->alarmset.tchain, a_waiter);
129         }
130         __cv_broadcast(&a->cv);
131         /* Fires taps for both Qtimer and Qcount. */
132         alarm_fire_taps(a, FDTAP_FILT_WRITTEN | FDTAP_FILT_READABLE);
133         cv_unlock(&a->cv);
134 }
135
136 void devalarm_init(struct proc *p)
137 {
138         TAILQ_INIT(&p->alarmset.list);
139         spinlock_init(&p->alarmset.lock);
140         /* Just running all the proc alarms on core 0. */
141         p->alarmset.tchain = &per_cpu_info[0].tchain;
142         p->alarmset.id_counter = 0;
143 }
144
145 static int alarmgen(struct chan *c, char *entry_name,
146                                         struct dirtab *unused, int unused_nr_dirtab,
147                                         int s, struct dir *dp)
148 {
149         struct qid q;
150         struct proc_alarm *a_i;
151         struct proc *p = current;
152         /* Whether we're in one dir or at the top, .. still takes us to the top. */
153         if (s == DEVDOTDOT) {
154                 mkqid(&q, Qtopdir, 0, QTDIR);
155                 devdir(c, q, devname(), 0, eve.name, 0555, dp);
156                 return 1;
157         }
158         switch (TYPE(c->qid)) {
159                 case Qtopdir:
160                         /* Generate elements for the top level dir.  We support a clone and
161                          * alarm dirs at the top level */
162                         if (s == 0) {
163                                 mkqid(&q, Qclone, 0, QTFILE);
164                                 devdir(c, q, "clone", 0, eve.name, 0666, dp);
165                                 return 1;
166                         }
167                         s--;    /* 1 -> 0th element, 2 -> 1st element, etc */
168                         /* Gets the s-th element (0 index)
169                          *
170                          * I would like to take advantage of the state machine and our
171                          * previous answer to get the sth element of the list.  We can get
172                          * at our previous run of gen from dp (struct dir), and use that to
173                          * get the next item.  I'd like to do something like:
174                          *
175                          * if (dp->qid.path >> ADDR_SHIFT)
176                          *      a_i = TAILQ_NEXT(QID2A(dp->qid), link);
177                          *
178                          * Dev would give us a 0'd dp path on the first run, so if we have a
179                          * path, we know we're on an iterative run.  However, the problem is
180                          * that we could have lost the element dp refers to (QID2A(dp->qid))
181                          * since our previous run, so we can't even access that memory to
182                          * check for refcnts or anything.  We need a new model for how gen
183                          * works (probably a gen_start and gen_stop devop, passed as
184                          * parameters to devwalk), so that we can have some invariants
185                          * between gen runs.
186                          *
187                          * Til then, we're stuck with arrays like in #ip (though we can use
188                          * Linux style fdsets) or lousy O(n^2) linked lists (like #srv).
189                          *
190                          * Note that we won't always start a gen loop with s == 0
191                          * (devdirread, for instance) */
192                         spin_lock(&p->alarmset.lock);
193                         TAILQ_FOREACH(a_i, &p->alarmset.list, link) {
194                                 if (s-- == 0)
195                                         break;
196                         }
197                         /* As soon as we unlock, someone could free a_i */
198                         if (!a_i) {
199                                 spin_unlock(&p->alarmset.lock);
200                                 return -1;
201                         }
202                         snprintf(get_cur_genbuf(), GENBUF_SZ, "a%d", a_i->id);
203                         mkqid(&q, QID(a_i, Qalarmdir), 0, QTDIR);
204                         devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
205                         spin_unlock(&p->alarmset.lock);
206                         return 1;
207                 case Qalarmdir:
208                         /* Gen the contents of the alarm dirs */
209                         s += Qctl;      /* first time through, start on Qctl */
210                         switch (s) {
211                                 case Qctl:
212                                         mkqid(&q, QID(QID2A(c->qid), Qctl), 0, QTFILE);
213                                         devdir(c, q, "ctl", 0, eve.name, 0666, dp);
214                                         return 1;
215                                 case Qtimer:
216                                         mkqid(&q, QID(QID2A(c->qid), Qtimer), 0, QTFILE);
217                                         devdir(c, q, "timer", 0, eve.name, 0666, dp);
218                                         return 1;
219                                 case Qperiod:
220                                         mkqid(&q, QID(QID2A(c->qid), Qperiod), 0, QTFILE);
221                                         devdir(c, q, "period", 0, eve.name, 0666, dp);
222                                         return 1;
223                                 case Qcount:
224                                         mkqid(&q, QID(QID2A(c->qid), Qcount), 0, QTFILE);
225                                         devdir(c, q, "count", 0, eve.name, 0666, dp);
226                                         return 1;
227                         }
228                         return -1;
229                         /* Need to also provide a direct hit for Qclone and all other files
230                          * (at all levels of the hierarchy).  Every file is both generated
231                          * (via the s increments in their respective directories) and
232                          * directly gen-able.  devstat() will call gen with a specific path
233                          * in the qid.  In these cases, we make a dir for whatever they are
234                          * asking for.  Note the qid stays the same.  I think this is what
235                          * the old plan9 comments above devgen were talking about for (ii).
236                          *
237                          * We don't need to do this for the directories - devstat will look
238                          * for the a directory by path and fail.  Then it will manually
239                          * build the stat output (check the -1 case in devstat). */
240                 case Qclone:
241                         devdir(c, c->qid, "clone", 0, eve.name, 0666, dp);
242                         return 1;
243                 case Qctl:
244                         devdir(c, c->qid, "ctl", 0, eve.name, 0666, dp);
245                         return 1;
246                 case Qtimer:
247                         devdir(c, c->qid, "timer", 0, eve.name, 0666, dp);
248                         return 1;
249                 case Qperiod:
250                         devdir(c, c->qid, "period", 0, eve.name, 0666, dp);
251                         return 1;
252                 case Qcount:
253                         devdir(c, c->qid, "count", 0, eve.name, 0666, dp);
254                         return 1;
255         }
256         return -1;
257 }
258
259 static void alarminit(void)
260 {
261 }
262
263 static struct chan *alarmattach(char *spec)
264 {
265         struct chan *c = devattach(devname(), spec);
266         mkqid(&c->qid, Qtopdir, 0, QTDIR);
267         return c;
268 }
269
270 static struct walkqid *alarmwalk(struct chan *c, struct chan *nc, char **name,
271                                                                  int nname)
272 {
273         return devwalk(c, nc, name, nname, 0, 0, alarmgen);
274 }
275
276 static int alarmstat(struct chan *c, uint8_t * db, int n)
277 {
278         return devstat(c, db, n, 0, 0, alarmgen);
279 }
280
281 /* It shouldn't matter if p = current is DYING.  We'll eventually fail to insert
282  * the open chan into p's fd table, then decref the chan. */
283 static struct chan *alarmopen(struct chan *c, int omode)
284 {
285         struct proc *p = current;
286         struct proc_alarm *a, *a_i;
287         switch (TYPE(c->qid)) {
288                 case Qtopdir:
289                 case Qalarmdir:
290                         if (omode & O_REMCLO)
291                                 error(EPERM, ERROR_FIXME);
292                         if (omode & O_WRITE)
293                                 error(EISDIR, ERROR_FIXME);
294                         break;
295                 case Qclone:
296                         a = kzmalloc(sizeof(struct proc_alarm), MEM_WAIT);
297                         kref_init(&a->kref, alarm_release, 1);
298                         SLIST_INIT(&a->fd_taps);
299                         cv_init(&a->cv);
300                         qlock_init(&a->qlock);
301                         init_awaiter(&a->a_waiter, proc_alarm_handler);
302                         spin_lock(&p->alarmset.lock);
303                         a->id = p->alarmset.id_counter++;
304                         proc_incref(p, 1);
305                         a->proc = p;
306                         TAILQ_INSERT_TAIL(&p->alarmset.list, a, link);
307                         spin_unlock(&p->alarmset.lock);
308                         mkqid(&c->qid, QID(a, Qctl), 0, QTFILE);
309                         break;
310                 case Qctl:
311                 case Qtimer:
312                 case Qperiod:
313                 case Qcount:
314                         /* the purpose of opening is to hold a kref on the proc_alarm */
315                         a = QID2A(c->qid);
316                         assert(a);
317                         /* this isn't a valid pointer yet, since our chan doesn't have a
318                          * ref.  since the time that walk gave our chan the qid, the chan
319                          * could have been closed, and the alarm decref'd and freed.  the
320                          * qid is essentially an uncounted reference, and we need to go to
321                          * the source to attempt to get a real ref.  Unfortunately, this is
322                          * another scan of the list, same as devsrv. */
323                         spin_lock(&p->alarmset.lock);
324                         TAILQ_FOREACH(a_i, &p->alarmset.list, link) {
325                                 if (a_i == a) {
326                                         assert(a->proc == current);
327                                         /* it's still possible we're not getting the ref, racing
328                                          * with the release method */
329                                         if (!kref_get_not_zero(&a->kref, 1)) {
330                                                 a_i = 0;        /* lost the race, will error out later */
331                                         }
332                                         break;
333                                 }
334                         }
335                         spin_unlock(&p->alarmset.lock);
336                         if (!a_i)
337                                 error(EFAIL, "Unable to open alarm, concurrent closing");
338                         break;
339         }
340         c->mode = openmode(omode);
341         /* Assumes c is unique (can't be closed concurrently */
342         c->flag |= COPEN;
343         c->offset = 0;
344         return c;
345 }
346
347 static void alarmcreate(struct chan *c, char *name, int omode, uint32_t perm)
348 {
349         error(EPERM, ERROR_FIXME);
350 }
351
352 static void alarmremove(struct chan *c)
353 {
354         error(EPERM, ERROR_FIXME);
355 }
356
357 static int alarmwstat(struct chan *c, uint8_t * dp, int n)
358 {
359         error(EFAIL, "No alarmwstat");
360         return 0;
361 }
362
363 static void alarmclose(struct chan *c)
364 {
365         /* There are more closes than opens.  For instance, sysstat doesn't open,
366          * but it will close the chan it got from namec.  We only want to clean
367          * up/decref chans that were actually open. */
368         if (!(c->flag & COPEN))
369                 return;
370         switch (TYPE(c->qid)) {
371                 case Qctl:
372                 case Qtimer:
373                 case Qperiod:
374                 case Qcount:
375                         kref_put(&QID2A(c->qid)->kref);
376                         break;
377         }
378 }
379
380 /* Helper for Qcount to encapsulate timerfd. */
381 static long read_qcount(struct chan *c, void *ubuf, size_t n)
382 {
383         ERRSTACK(1);
384         struct proc_alarm *a = QID2A(c->qid);
385         struct cv_lookup_elm cle;
386         unsigned long old_count;
387
388         if (n > sizeof(old_count))
389                 error(EINVAL, "timerfd buffer is too small (%llu)", n);
390         /* TODO: have easily abortable CVs that don't require this mechanism. */
391         cv_lock(&a->cv);
392         __reg_abortable_cv(&cle, &a->cv);
393         if (waserror()) {
394                 cv_unlock(&a->cv);
395                 dereg_abortable_cv(&cle);
396                 nexterror();
397         }
398         while (!a->count) {
399                 if (c->flag & O_NONBLOCK)
400                         error(EAGAIN, "#alarm count was 0");
401                 if (should_abort(&cle))
402                         error(EINTR, "syscall aborted");
403                 cv_wait(&a->cv);
404         }
405         old_count = a->count;
406         a->count = 0;
407         cv_unlock(&a->cv);
408         dereg_abortable_cv(&cle);
409         poperror();
410         if (copy_to_user(ubuf, &old_count, sizeof(old_count)))
411                 error(EFAULT, "timerfd copy_to_user failed");
412         return sizeof(old_count);
413 }
414
415 static long alarmread(struct chan *c, void *ubuf, long n, int64_t offset)
416 {
417         struct proc_alarm *p_alarm;
418
419         switch (TYPE(c->qid)) {
420                 case Qtopdir:
421                 case Qalarmdir:
422                         return devdirread(c, ubuf, n, 0, 0, alarmgen);
423                 case Qctl:
424                         p_alarm = QID2A(c->qid);
425                         /* simple reads from p_alarm shouldn't need a lock */
426                         return readnum(offset, ubuf, n, p_alarm->id, NUMSIZE32);
427                 case Qtimer:
428                         p_alarm = QID2A(c->qid);
429                         return readnum(offset, ubuf, n, p_alarm->a_waiter.wake_up_time,
430                                                    NUMSIZE64);
431                 case Qperiod:
432                         p_alarm = QID2A(c->qid);
433                         return readnum(offset, ubuf, n, p_alarm->period, NUMSIZE64);
434                 case Qcount:
435                         return read_qcount(c, ubuf, n); /* ignore offset */
436                 default:
437                         panic("Bad QID %p in devalarm", c->qid.path);
438         }
439         return 0;
440 }
441
442 /* Helper, sets the procalarm to hexval (abs TSC ticks).  0 disarms. */
443 static void set_proc_alarm(struct proc_alarm *a, uint64_t hexval)
444 {
445         /* Due to how we have to maintain 'count', we need to strictly account for
446          * the firings of the alarm.  Easiest thing is to disarm it, reset
447          * everything, then rearm it.  Note that if someone is blocked on count = 0,
448          * they may still be blocked until the next time the alarm fires.
449          *
450          * unset waits on the handler, which grabs the cv lock, so we don't grab the
451          * cv lock.  However, we still need to protect ourselves from multiple
452          * setters trying to run this at once.  Unset actually can handle being
453          * called concurrently, but alarm setters can't, nor can it handle the
454          * unsets and sets getting out of sync.  For instance, two unsets followed
455          * by two sets would be a bug.  Likewise, setting the awaiter value while it
456          * is on a tchain is a bug.  The qlock prevents that. */
457         qlock(&a->qlock);
458         unset_alarm(a->proc->alarmset.tchain, &a->a_waiter);
459         cv_lock(&a->cv);
460         a->count = 0;
461         if (hexval) {
462                 set_awaiter_abs(&a->a_waiter, hexval);
463                 set_alarm(a->proc->alarmset.tchain, &a->a_waiter);
464         }
465         cv_unlock(&a->cv);
466         qunlock(&a->qlock);
467 }
468
469 /* Note that in read and write we have an open chan, which means we have an
470  * active kref on the p_alarm.  Also note that we make no assumptions about
471  * current here - we find the proc (and the tchain) via the ref stored in the
472  * proc_alarm. */
473 static long alarmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
474 {
475         struct proc_alarm *p_alarm;
476
477         switch (TYPE(c->qid)) {
478                 case Qtopdir:
479                 case Qalarmdir:
480                 case Qctl:
481                 case Qcount:
482                         error(EPERM, ERROR_FIXME);
483                 case Qtimer:
484                         set_proc_alarm(QID2A(c->qid), strtoul_from_ubuf(ubuf, n, 16));
485                         break;
486                 case Qperiod:
487                         p_alarm = QID2A(c->qid);
488                         /* racing with the handler which checks the val repeatedly */
489                         cv_lock(&p_alarm->cv);
490                         p_alarm->period = strtoul_from_ubuf(ubuf, n, 16);
491                         cv_unlock(&p_alarm->cv);
492                         break;
493                 default:
494                         panic("Bad QID %p in devalarm", c->qid.path);
495         }
496         return n;
497 }
498
499 /* We use the same tap list, regardless of Qtimer or Qcount */
500 static int tap_alarm(struct proc_alarm *a, struct fd_tap *tap, int cmd,
501                      int legal_filter)
502 {
503         int ret;
504
505         if (tap->filter & ~legal_filter) {
506                 set_error(ENOSYS, "Unsupported #%s tap, must be %p", devname(),
507                                   legal_filter);
508                 return -1;
509         }
510         cv_lock(&a->cv);
511         switch (cmd) {
512         case (FDTAP_CMD_ADD):
513                 SLIST_INSERT_HEAD(&a->fd_taps, tap, link);
514                 ret = 0;
515                 break;
516         case (FDTAP_CMD_REM):
517                 SLIST_REMOVE(&a->fd_taps, tap, fd_tap, link);
518                 ret = 0;
519                 break;
520         default:
521                 set_error(ENOSYS, "Unsupported #%s tap command %p",
522                                   devname(), cmd);
523                 ret = -1;
524         }
525         cv_unlock(&a->cv);
526         return ret;
527 }
528
529 static int alarm_tapfd(struct chan *c, struct fd_tap *tap, int cmd)
530 {
531         struct proc_alarm *a = QID2A(c->qid);
532
533         /* We don't actually support HANGUP, but epoll implies it. */
534         #define ALARM_LEGAL_TIMER_TAPS (FDTAP_FILT_WRITTEN | FDTAP_FILT_HANGUP)
535         #define ALARM_LEGAL_COUNT_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_HANGUP)
536
537         switch (TYPE(c->qid)) {
538         case Qtimer:
539                 return tap_alarm(a, tap, cmd, ALARM_LEGAL_TIMER_TAPS);
540         case Qcount:
541                 return tap_alarm(a, tap, cmd, ALARM_LEGAL_COUNT_TAPS);
542         default:
543                 set_error(ENOSYS, "Can't tap #%s file type %d", devname(),
544                           c->qid.path);
545                 return -1;
546         }
547 }
548
549 static char *alarm_chaninfo(struct chan *ch, char *ret, size_t ret_l)
550 {
551         struct proc_alarm *a;
552
553         switch (TYPE(ch->qid)) {
554         case Qctl:
555         case Qtimer:
556         case Qperiod:
557         case Qcount:
558                 a = QID2A(ch->qid);
559                 snprintf(ret, ret_l, "Id %d, %s, expires %llu, period %llu, count %llu",
560                          a->id, SLIST_EMPTY(&a->fd_taps) ? "untapped" : "tapped",
561                          a->a_waiter.wake_up_time, a->period, a->count);
562                 break;
563         default:
564                 return devchaninfo(ch, ret, ret_l);
565         }
566         return ret;
567 }
568
569 struct dev alarmdevtab __devtab = {
570         .name = "alarm",
571
572         .reset = devreset,
573         .init = alarminit,
574         .shutdown = devshutdown,
575         .attach = alarmattach,
576         .walk = alarmwalk,
577         .stat = alarmstat,
578         .open = alarmopen,
579         .create = alarmcreate,
580         .close = alarmclose,
581         .read = alarmread,
582         .bread = devbread,
583         .write = alarmwrite,
584         .bwrite = devbwrite,
585         .remove = alarmremove,
586         .wstat = alarmwstat,
587         .power = devpower,
588         .chaninfo = alarm_chaninfo,
589         .tapfd = alarm_tapfd,
590 };