Re: vmd(8): simplify vcpu logic, removing uart & net reads

2021-07-15 Thread Mike Larkin
On Sun, Jul 11, 2021 at 08:10:42AM -0400, Dave Voutila wrote:
>
> Ping...looking for OK. Would like to get this committed this week.
>

Sorry this took so long. ok mlarkin.

Thanks to the numerous testers who ran with this for the past few
weeks.

> Dave Voutila writes:
>
> > Looking for an OK for this one now. Anyone?
> >
> > Dave Voutila  writes:
> >
> >> Dave Voutila writes:
> >>
> >>> Looking for some broader testing of the following diff. It cleans up
> >>> some complicated logic predominantly left over from the early days of
> >>> vmd prior to its having a dedicated device thread.
> >>
> >> Still looking for tester feedback. I've been running this diff while
> >> hosting multiple guests continously (OpenBSD-current, Alpine 3.14,
> >> Debian 10.10, Ubuntu 20.04) with no issues.
> >>
> >> I know a few folks have told me they've applied the diff and have not
> >> seen issues.
> >
> > I've had positive reports from 4 people. Thanks everyone that tested and
> > provided feedback!
> >
> >>
> >> I'll prod for OK next week, so if you've tested the diff please let me
> >> know!
> >
> > OK to commit?
> >
> >>
> >>>
> >>> In summary, this diff:
> >>>
> >>> - Removes vionet "rx pending" state handling and removes the code path
> >>>   for the vcpu thread to possibly take control of the virtio net device
> >>>   and attempt a read of the underlying tap(4). (virtio.{c,h}, vm.c)
> >>>
> >>> - Removes ns8250 "rcv pending" state handling and removes the code path
> >>>   for the vcpu thread to read the pty via com_rcv(). (ns8250.{c,h})
> >>>
> >>> In both of the above cases, the event handling thread will be notified
> >>> of readable data and deal with it.
> >>>
> >>> Why remove them? The logic is overly complicated and hard to reason
> >>> about for zero gain. (This diff results in no intended functional
> >>> change.) Plus, some of the above logic I helped add to deal with the
> >>> race conditions and state corruption over a year ago. The logic was
> >>> needed once upon a time, but shouldn't be needed at present.
> >>>
> >>> I've had positive testing feedback from abieber@ so far with at least
> >>> the ns8250/uart diff, but want to cast a broader net here with both
> >>> before either part is committed. I debated splitting these up, but
> >>> they're thematically related.
> >>>
> >>> -dv
> >>>
> >>> Index: virtio.c
> >>> ===
> >>> RCS file: /cvs/src/usr.sbin/vmd/virtio.c,v
> >>> retrieving revision 1.91
> >>> diff -u -p -r1.91 virtio.c
> >>> --- virtio.c  21 Jun 2021 02:38:18 -  1.91
> >>> +++ virtio.c  23 Jun 2021 11:28:03 -
> >>> @@ -1254,12 +1254,12 @@ static int
> >>>  vionet_rx(struct vionet_dev *dev)
> >>>  {
> >>>   char buf[PAGE_SIZE];
> >>> - int hasdata, num_enq = 0, spc = 0;
> >>> + int num_enq = 0, spc = 0;
> >>>   struct ether_header *eh;
> >>>   ssize_t sz;
> >>>
> >>>   do {
> >>> - sz = read(dev->fd, buf, sizeof buf);
> >>> + sz = read(dev->fd, buf, sizeof(buf));
> >>>   if (sz == -1) {
> >>>   /*
> >>>* If we get EAGAIN, No data is currently available.
> >>> @@ -1270,21 +1270,17 @@ vionet_rx(struct vionet_dev *dev)
> >>>   "device");
> >>>   } else if (sz > 0) {
> >>>   eh = (struct ether_header *)buf;
> >>> - if (!dev->lockedmac || sz < ETHER_HDR_LEN ||
> >>> + if (!dev->lockedmac ||
> >>>   ETHER_IS_MULTICAST(eh->ether_dhost) ||
> >>>   memcmp(eh->ether_dhost, dev->mac,
> >>>   sizeof(eh->ether_dhost)) == 0)
> >>>   num_enq += vionet_enq_rx(dev, buf, sz, &spc);
> >>>   } else if (sz == 0) {
> >>>   log_debug("process_rx: no data");
> >>> - hasdata = 0;
> >>>   break;
> >>>   }
> >>> + } while (spc > 0 && sz > 0);
> >>>
> >>> - hasdata = fd_hasdata(dev->fd);
> >>> - } while (spc && hasdata);
> >>> -
> >>> - dev->rx_pending = hasdata;
> >>>   return (num_enq);
> >>>  }
> >>>
> >>> @@ -1301,16 +1297,6 @@ vionet_rx_event(int fd, short kind, void
> >>>
> >>>   mutex_lock(&dev->mutex);
> >>>
> >>> - /*
> >>> -  * We already have other data pending to be received. The data that
> >>> -  * has become available now will be enqueued to the vionet_dev
> >>> -  * later.
> >>> -  */
> >>> - if (dev->rx_pending) {
> >>> - mutex_unlock(&dev->mutex);
> >>> - return;
> >>> - }
> >>> -
> >>>   if (vionet_rx(dev) > 0) {
> >>>   /* XXX: vcpu_id */
> >>>   vcpu_assert_pic_irq(dev->vm_id, 0, dev->irq);
> >>> @@ -1320,40 +1306,6 @@ vionet_rx_event(int fd, short kind, void
> >>>  }
> >>>
> >>>  /*
> >>> - * vionet_process_rx
> >>> - *
> >>> - * Processes any remaining pending receivable data for a vionet device.
> >>> - * Called on VCPU exit. Although we poll on the tap file descriptor of
> >>> - * a vionet_

Re: cron(8): add '@' interval time specifier

2021-07-15 Thread David Higgs
On Thu, Jul 15, 2021 at 11:20 AM Leo Unglaub  wrote:

> Hey,
> this is a very clean solution to a very common problem that i have. A
> lot of tasks that i run from cron have very different completion times.
> Right now i use the -s [1] option in crontab to make sure only one task
> is running at once and so that they don't overlap if they take longer to
> complete than the interval i schedule them. But the problem with the -s
> workflow is that the interval can get messed up if the interval is
> smaller than the execution period. This will basically "skip" a run.
>
> With your patch this can be avioded in a very clean way. I have your
> patch a try and for my local testing usecase it worked as expected. This
> would clean up a lot of things in my personal workflow. Thank you very
> mich for the patch Job, much appreciated!
>
> Thanks and greetings
> Leo
>
> [1] https://man.openbsd.org/crontab.5#s
>
> On 10/07/2021 16:07, Job Snijders wrote:
> > The below patch adds a new kind of time specifier: an interval (in
> > minutes). When used, cron(8) will schedule the next instance of a job
> > after the previous job has completed and a full interval has passed.
> >
> > A crontab(5) configured as following:
> >
> >  $ crontab -l
> >  @3 sleep 100
> >
> > Will result in this schedule:
> >
> >  Jul 10 13:38:17 vurt cron[96937]: (CRON) STARTUP (V5.0)
> >  Jul 10 13:42:01 vurt cron[79385]: (job) CMD (sleep 100)
> >  Jul 10 13:47:01 vurt cron[3165]: (job) CMD (sleep 100)
> >  Jul 10 13:52:01 vurt cron[40539]: (job) CMD (sleep 100)
> >  Jul 10 13:57:01 vurt cron[84504]: (job) CMD (sleep 100)
> >
> > A use case could be running rpki-client more frequently than once an
> > hour:
> >
> >  @15 -n rpki-client && bgpctl reload
> >
> > The above is equivalent to:
> >
> >  * * * * * -sn sleep 900 && rpki-client && bgpctl reload
> >
> > I borrowed the idea from FreeBSD's cron [1]. A difference between the
> > below changeset and the freebsd implementation is that they specify the
> > interval in seconds, while the below specifies in minutes. I was able
> > to leverage the 'singleton' infrastructure. And removed a comment that
> > reads like a TODO nobody is going to do.
> >
> > Thoughts?
>

Can't this type of problem also be solved with a shell script wrapper?

An infinite loop that does work and then sleeps?
Or perhaps a script that upon work completion, schedules itself in the
future with at(1)?
These could be kicked off initially with a @reboot crontab entry.

Or maybe I'm missing something that cron adds to the equation, in which
case, apologies.

--david


Re: cron(8): add '@' interval time specifier

2021-07-15 Thread Leo Unglaub

Hey,
this is a very clean solution to a very common problem that i have. A 
lot of tasks that i run from cron have very different completion times. 
Right now i use the -s [1] option in crontab to make sure only one task 
is running at once and so that they don't overlap if they take longer to 
complete than the interval i schedule them. But the problem with the -s 
workflow is that the interval can get messed up if the interval is 
smaller than the execution period. This will basically "skip" a run.


With your patch this can be avioded in a very clean way. I have your 
patch a try and for my local testing usecase it worked as expected. This
would clean up a lot of things in my personal workflow. Thank you very 
mich for the patch Job, much appreciated!


Thanks and greetings
Leo

[1] https://man.openbsd.org/crontab.5#s

On 10/07/2021 16:07, Job Snijders wrote:

The below patch adds a new kind of time specifier: an interval (in
minutes). When used, cron(8) will schedule the next instance of a job
after the previous job has completed and a full interval has passed.

A crontab(5) configured as following:

 $ crontab -l
 @3 sleep 100

Will result in this schedule:

 Jul 10 13:38:17 vurt cron[96937]: (CRON) STARTUP (V5.0)
 Jul 10 13:42:01 vurt cron[79385]: (job) CMD (sleep 100)
 Jul 10 13:47:01 vurt cron[3165]: (job) CMD (sleep 100)
 Jul 10 13:52:01 vurt cron[40539]: (job) CMD (sleep 100)
 Jul 10 13:57:01 vurt cron[84504]: (job) CMD (sleep 100)

A use case could be running rpki-client more frequently than once an
hour:

 @15 -n rpki-client && bgpctl reload

The above is equivalent to:

 * * * * * -sn sleep 900 && rpki-client && bgpctl reload

I borrowed the idea from FreeBSD's cron [1]. A difference between the
below changeset and the freebsd implementation is that they specify the
interval in seconds, while the below specifies in minutes. I was able
to leverage the 'singleton' infrastructure. And removed a comment that
reads like a TODO nobody is going to do.

Thoughts?