error: return usable error strings, not nothing.
[akaros.git] / kern / drivers / dev / alarm.c
1 /* Copyright (c) 2013 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * #alarm: a device for registering per-process alarms.
6  *
7  * Allows a process to set up alarms, where the kernel will send an event to a
8  * posted ev_q at a certain TSC time.
9  *
10  * Every process has their own alarm sets and view of #alarm; gen and friends
11  * look at current's alarmset when it is time to gen or open a file.
12  *
13  * To use, first open #alarm/clone, and that gives you an alarm directory aN,
14  * where N is ID of the alarm.  ctl takes two commands: "evq POINTER" (to tell
15  * the kernel the pointer of your ev_q) and "cancel", to stop an alarm.  timer
16  * takes just the value (in absolute tsc time) to fire the alarm.
17  *
18  * While each process has a separate view of #alarm, it is possible to post a
19  * chan to Qctl or Qtimer to #srv.  If another proc has your Qtimer, it can set
20  * it in the past, thereby triggering an immediate event.  More clever than
21  * useful.
22  *
23  * Notes on refcnting (the trickier parts here):
24  * - the proc_alarms have counted references to their proc
25  *              proc won't free til all alarms are closed, which is fine.  we close
26  *              all files in destroy.  if a proc drops a chan in srv, the proc will stay
27  *              alive because the alarm is alive - til that chan is closed (srvremove)
28  *
29  *              other shady ways to keep a chan alive: cd to it!  if it is ., we'd
30  *              keep a ref around.  however, only alarmdir *file* grab refs, not
31  *              directories.
32  *
33  * - proc_alarms are kref'd, since there can be multiple chans per alarm
34  *              the only thing that keeps an alarm alive is a chan on a CTL or TIMER (or
35  *              other file).  when you cloned, you got back an open CTL, which keeps the
36  *              alarm (and the dir) alive.
37  *
38  *              we need to be careful generating krefs, in case alarms are concurrently
39  *              released and removed from the lists.  just like with procs and pid2proc,
40  *              we need to sync with the source of the kref. */
41
42 #include <kmalloc.h>
43 #include <string.h>
44 #include <stdio.h>
45 #include <assert.h>
46 #include <error.h>
47 #include <pmap.h>
48 #include <sys/queue.h>
49 #include <smp.h>
50 #include <kref.h>
51 #include <atomic.h>
52 #include <alarm.h>
53 #include <event.h>
54 #include <umem.h>
55 #include <devalarm.h>
56
57 struct dev alarmdevtab;
58
59 static char *devname(void)
60 {
61         return alarmdevtab.name;
62 }
63
64 /* qid path types */
65 #define Qtopdir                                 1
66 #define Qclone                                  2
67 #define Qalarmdir                               3
68 #define Qctl                                    4
69 #define Qtimer                                  5       /* Qctl + 1 */
70
71 /* This paddr/kaddr is a bit dangerous.  it'll work so long as we don't need all
72  * 64 bits for a physical address (48 is the current norm on x86_64). */
73 #define ADDR_SHIFT 5
74 #define QID2A(q) ((struct proc_alarm*)KADDR(((q).path >> ADDR_SHIFT)))
75 #define TYPE(q) ((q).path & ((1 << ADDR_SHIFT) - 1))
76 #define QID(ptr, type) ((PADDR(ptr) << ADDR_SHIFT) | type)
77 extern char *eve;
78
79 static void alarm_release(struct kref *kref)
80 {
81         struct proc_alarm *a = container_of(kref, struct proc_alarm, kref);
82         struct proc *p = a->proc;
83         assert(p);
84         spin_lock(&p->alarmset.lock);
85         TAILQ_REMOVE(&p->alarmset.list, a, link);
86         spin_unlock(&p->alarmset.lock);
87         /* When this returns, the alarm has either fired or it never will */
88         unset_alarm(p->alarmset.tchain, &a->a_waiter);
89         proc_decref(p);
90         kfree(a);
91 }
92
93 static void proc_alarm_handler(struct alarm_waiter *a_waiter)
94 {
95         struct proc_alarm *a = container_of(a_waiter, struct proc_alarm, a_waiter);
96         struct event_queue *ev_q = ACCESS_ONCE(a->ev_q);
97         struct event_msg msg;
98         if (!ev_q || !a->proc) {
99                 printk("[kernel] proc_alarm, bad ev_q %p or proc %p\n", ev_q, a->proc);
100                 return;
101         }
102         memset(&msg, 0, sizeof(struct event_msg));
103         msg.ev_type = EV_ALARM;
104         msg.ev_arg2 = a->id;
105         send_event(a->proc, ev_q, &msg, 0);
106 }
107
108 void devalarm_init(struct proc *p)
109 {
110         TAILQ_INIT(&p->alarmset.list);
111         spinlock_init(&p->alarmset.lock);
112         /* Just running all the proc alarms on core 0. */
113         p->alarmset.tchain = &per_cpu_info[0].tchain;
114         p->alarmset.id_counter = 0;
115 }
116
117 static int alarmgen(struct chan *c, char *entry_name,
118                                         struct dirtab *unused, int unused_nr_dirtab,
119                                         int s, struct dir *dp)
120 {
121         struct qid q;
122         struct proc_alarm *a_i;
123         struct proc *p = current;
124         /* Whether we're in one dir or at the top, .. still takes us to the top. */
125         if (s == DEVDOTDOT) {
126                 mkqid(&q, Qtopdir, 0, QTDIR);
127                 devdir(c, q, devname(), 0, eve, 0555, dp);
128                 return 1;
129         }
130         switch (TYPE(c->qid)) {
131                 case Qtopdir:
132                         /* Generate elements for the top level dir.  We support a clone and
133                          * alarm dirs at the top level */
134                         if (s == 0) {
135                                 mkqid(&q, Qclone, 0, QTFILE);
136                                 devdir(c, q, "clone", 0, eve, 0666, dp);
137                                 return 1;
138                         }
139                         s--;    /* 1 -> 0th element, 2 -> 1st element, etc */
140                         /* Gets the s-th element (0 index)
141                          * 
142                          * I would like to take advantage of the state machine and our
143                          * previous answer to get the sth element of the list.  We can get
144                          * at our previous run of gen from dp (struct dir), and use that to
145                          * get the next item.  I'd like to do something like:
146                          *
147                          * if (dp->qid.path >> ADDR_SHIFT)
148                          *      a_i = TAILQ_NEXT(QID2A(dp->qid), link);
149                          *
150                          * Dev would give us a 0'd dp path on the first run, so if we have a
151                          * path, we know we're on an iterative run.  However, the problem is
152                          * that we could have lost the element dp refers to (QID2A(dp->qid))
153                          * since our previous run, so we can't even access that memory to
154                          * check for refcnts or anything.  We need a new model for how gen
155                          * works (probably a gen_start and gen_stop devop, passed as
156                          * parameters to devwalk), so that we can have some invariants
157                          * between gen runs.
158                          *
159                          * Til then, we're stuck with arrays like in #ip (though we can use
160                          * Linux style fdsets) or lousy O(n^2) linked lists (like #srv).
161                          *
162                          * Note that we won't always start a gen loop with s == 0
163                          * (devdirread, for instance) */
164                         spin_lock(&p->alarmset.lock);
165                         TAILQ_FOREACH(a_i, &p->alarmset.list, link) {
166                                 if (s-- == 0)
167                                         break;
168                         }
169                         /* As soon as we unlock, someone could free a_i */
170                         if (!a_i) {
171                                 spin_unlock(&p->alarmset.lock);
172                                 return -1;
173                         }
174                         snprintf(get_cur_genbuf(), GENBUF_SZ, "a%d", a_i->id);
175                         mkqid(&q, QID(a_i, Qalarmdir), 0, QTDIR);
176                         devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
177                         spin_unlock(&p->alarmset.lock);
178                         return 1;
179                 case Qalarmdir:
180                         /* Gen the contents of the alarm dirs */
181                         s += Qctl;      /* first time through, start on Qctl */
182                         switch (s) {
183                                 case Qctl:
184                                         mkqid(&q, QID(QID2A(c->qid), Qctl), 0, QTFILE);
185                                         devdir(c, q, "ctl", 0, eve, 0666, dp);
186                                         return 1;
187                                 case Qtimer:
188                                         mkqid(&q, QID(QID2A(c->qid), Qtimer), 0, QTFILE);
189                                         devdir(c, q, "timer", 0, eve, 0666, dp);
190                                         return 1;
191                         }
192                         return -1;
193                         /* Need to also provide a direct hit for Qclone and all other files
194                          * (at all levels of the hierarchy).  Every file is both generated
195                          * (via the s increments in their respective directories) and
196                          * directly gen-able.  devstat() will call gen with a specific path
197                          * in the qid.  In these cases, we make a dir for whatever they are
198                          * asking for.  Note the qid stays the same.  I think this is what
199                          * the old plan9 comments above devgen were talking about for (ii).
200                          *
201                          * We don't need to do this for the directories - devstat will look
202                          * for the a directory by path and fail.  Then it will manually
203                          * build the stat output (check the -1 case in devstat). */
204                 case Qclone:
205                         devdir(c, c->qid, "clone", 0, eve, 0666, dp);
206                         return 1;
207                 case Qctl:
208                         devdir(c, c->qid, "ctl", 0, eve, 0666, dp);
209                         return 1;
210                 case Qtimer:
211                         devdir(c, c->qid, "timer", 0, eve, 0666, dp);
212                         return 1;
213         }
214         return -1;
215 }
216
217 static void alarminit(void)
218 {
219 }
220
221 static struct chan *alarmattach(char *spec)
222 {
223         struct chan *c = devattach(devname(), spec);
224         mkqid(&c->qid, Qtopdir, 0, QTDIR);
225         return c;
226 }
227
228 static struct walkqid *alarmwalk(struct chan *c, struct chan *nc, char **name,
229                                                                  int nname)
230 {
231         return devwalk(c, nc, name, nname, 0, 0, alarmgen);
232 }
233
234 static int alarmstat(struct chan *c, uint8_t * db, int n)
235 {
236         return devstat(c, db, n, 0, 0, alarmgen);
237 }
238
239 /* It shouldn't matter if p = current is DYING.  We'll eventually fail to insert
240  * the open chan into p's fd table, then decref the chan. */
241 static struct chan *alarmopen(struct chan *c, int omode)
242 {
243         struct proc *p = current;
244         struct proc_alarm *a, *a_i;
245         switch (TYPE(c->qid)) {
246                 case Qtopdir:
247                 case Qalarmdir:
248                         if (omode & O_REMCLO)
249                                 error(EPERM, ERROR_FIXME);
250                         if (omode & O_WRITE)
251                                 error(EISDIR, ERROR_FIXME);
252                         break;
253                 case Qclone:
254                         a = kzmalloc(sizeof(struct proc_alarm), KMALLOC_WAIT);
255                         kref_init(&a->kref, alarm_release, 1);
256                         init_awaiter(&a->a_waiter, proc_alarm_handler);
257                         spin_lock(&p->alarmset.lock);
258                         a->id = p->alarmset.id_counter++;
259                         proc_incref(p, 1);
260                         a->proc = p;
261                         TAILQ_INSERT_TAIL(&p->alarmset.list, a, link);
262                         spin_unlock(&p->alarmset.lock);
263                         mkqid(&c->qid, QID(a, Qctl), 0, QTFILE);
264                         break;
265                 case Qctl:
266                 case Qtimer:
267                         /* the purpose of opening is to hold a kref on the proc_alarm */
268                         a = QID2A(c->qid);
269                         assert(a);
270                         /* this isn't a valid pointer yet, since our chan doesn't have a
271                          * ref.  since the time that walk gave our chan the qid, the chan
272                          * could have been closed, and the alarm decref'd and freed.  the
273                          * qid is essentially an uncounted reference, and we need to go to
274                          * the source to attempt to get a real ref.  Unfortunately, this is
275                          * another scan of the list, same as devsrv. */
276                         spin_lock(&p->alarmset.lock);
277                         TAILQ_FOREACH(a_i, &p->alarmset.list, link) {
278                                 if (a_i == a) {
279                                         assert(a->proc == current);
280                                         /* it's still possible we're not getting the ref, racing
281                                          * with the release method */
282                                         if (!kref_get_not_zero(&a->kref, 1)) {
283                                                 a_i = 0;        /* lost the race, will error out later */
284                                         }
285                                         break;
286                                 }
287                         }
288                         spin_unlock(&p->alarmset.lock);
289                         if (!a_i)
290                                 error(EFAIL, "Unable to open alarm, concurrent closing");
291                         break;
292         }
293         c->mode = openmode(omode);
294         /* Assumes c is unique (can't be closed concurrently */
295         c->flag |= COPEN;
296         c->offset = 0;
297         return c;
298 }
299
300 static void alarmcreate(struct chan *c, char *name, int omode, uint32_t perm)
301 {
302         error(EPERM, ERROR_FIXME);
303 }
304
305 static void alarmremove(struct chan *c)
306 {
307         error(EPERM, ERROR_FIXME);
308 }
309
310 static int alarmwstat(struct chan *c, uint8_t * dp, int n)
311 {
312         error(EFAIL, "No alarmwstat");
313         return 0;
314 }
315
316 static void alarmclose(struct chan *c)
317 {
318         /* There are more closes than opens.  For instance, sysstat doesn't open,
319          * but it will close the chan it got from namec.  We only want to clean
320          * up/decref chans that were actually open. */
321         if (!(c->flag & COPEN))
322                 return;
323         switch (TYPE(c->qid)) {
324                 case Qctl:
325                 case Qtimer:
326                         kref_put(&QID2A(c->qid)->kref);
327                         break;
328         }
329 }
330
331 static long alarmread(struct chan *c, void *ubuf, long n, int64_t offset)
332 {
333         struct proc_alarm *p_alarm;
334         switch (TYPE(c->qid)) {
335                 case Qtopdir:
336                 case Qalarmdir:
337                         return devdirread(c, ubuf, n, 0, 0, alarmgen);
338                 case Qctl:
339                         p_alarm = QID2A(c->qid);
340                         return readnum(offset, ubuf, n, p_alarm->id, NUMSIZE32);
341                 case Qtimer:
342                         p_alarm = QID2A(c->qid);
343                         return readnum(offset, ubuf, n, p_alarm->a_waiter.wake_up_time,
344                                                    NUMSIZE64);
345                 default:
346                         panic("Bad QID %p in devalarm", c->qid.path);
347         }
348         return 0;
349 }
350
351 /* Note that in read and write we have an open chan, which means we have an
352  * active kref on the p_alarm.  Also note that we make no assumptions about
353  * current here - we find the proc (and the tchain) via the ref stored in the
354  * proc_alarm. */
355 static long alarmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
356 {
357         ERRSTACK(1);
358         char num64[NUMSIZE64];
359         struct cmdbuf *cb;
360         struct proc_alarm *p_alarm;
361         uint64_t hexval;
362
363         switch (TYPE(c->qid)) {
364                 case Qtopdir:
365                 case Qalarmdir:
366                         error(EPERM, ERROR_FIXME);
367                 case Qctl:
368                         p_alarm = QID2A(c->qid);
369                         cb = parsecmd(ubuf, n);
370                         if (waserror()) {
371                                 kfree(cb);
372                                 nexterror();
373                         }
374                         if (cb->nf < 1)
375                                 error(EFAIL, "short control request");
376                         if (!strcmp(cb->f[0], "evq")) {
377                                 if (cb->nf < 2)
378                                         error(EFAIL, "evq needs a pointer");
379                                 /* i think it's safe to do a stroul on a parsecmd.  it's kernel
380                                  * memory, and space or 0 terminated */
381                                 hexval = strtoul(cb->f[1], 0, 16);
382                                 /* This is just to help userspace - event code can handle it */
383                                 if (!is_user_rwaddr((void *)hexval, sizeof(struct event_queue)))
384                                         error(EFAIL, "Non-user ev_q pointer");
385                                 p_alarm->ev_q = (struct event_queue *)hexval;
386                         } else if (!strcmp(cb->f[0], "cancel")) {
387                                 unset_alarm(p_alarm->proc->alarmset.tchain, &p_alarm->a_waiter);
388                         } else {
389                                 error(EFAIL, "%s: not implemented", cb->f[0]);
390                         }
391                         kfree(cb);
392                         poperror();
393                         break;
394                 case Qtimer:
395                         /* want to give strtoul a null-terminated buf (can't handle random
396                          * user strings) */
397                         if (n > sizeof(num64)) {
398                                 set_errno(EINVAL);
399                                 error(EFAIL, "attempted to write %d chars, max %d", n,
400                                           sizeof(num64));
401                         }
402                         memcpy(num64, ubuf, n);
403                         num64[n] = 0;   /* enforce trailing 0 */
404                         hexval = strtoul(num64, 0, 16);
405                         p_alarm = QID2A(c->qid);
406                         /* if you don't know if it was running or not, resetting will turn
407                          * it on regardless. */
408                         reset_alarm_abs(p_alarm->proc->alarmset.tchain, &p_alarm->a_waiter,
409                                                         hexval);
410                         break;
411                 default:
412                         panic("Bad QID %p in devalarm", c->qid.path);
413         }
414         return n;
415 }
416
417 struct dev alarmdevtab __devtab = {
418         .name = "alarm",
419
420         .reset = devreset,
421         .init = alarminit,
422         .shutdown = devshutdown,
423         .attach = alarmattach,
424         .walk = alarmwalk,
425         .stat = alarmstat,
426         .open = alarmopen,
427         .create = alarmcreate,
428         .close = alarmclose,
429         .read = alarmread,
430         .bread = devbread,
431         .write = alarmwrite,
432         .bwrite = devbwrite,
433         .remove = alarmremove,
434         .wstat = alarmwstat,
435         .power = devpower,
436         .chaninfo = devchaninfo,
437 };