> From: "Sven M. Hallberg" <pe...@khjk.org>
> Date: Wed, 12 Jun 2019 23:18:24 +0200
> 
> Mark Kettenis on Tue, Jun 11 2019:
> > The drm(4) codebase really needs multi-threaded task queues [...]
> >
> > The diff also starts 4 threads for each workqueue that gets created by
> > the drm(4) layer.  The number 4 is a bit arbitrary but it is the
> > number of threads that Linux creates per CPU for a so-called "unbound"
> > workqueue which hopefully is enough to always make progress.
> > 
> > Please test.
> 
> Looks good and appears to work fine with two displays (one internal, one
> external). Will test with three at work tomorrow.
> 
> 
> > -   dev_priv->hotplug.poll_init_work.tq = systq;
> 
> Intentional?

Yes.  It removes a local modification that should no longer be necessary.

Unfortunately the diff doesn't work with amdgpu.  Some more thinking
needed...

> > Index: dev/pci/drm/drm_linux.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/pci/drm/drm_linux.c,v
> > retrieving revision 1.38
> > diff -u -p -r1.38 drm_linux.c
> > --- dev/pci/drm/drm_linux.c 9 Jun 2019 12:58:30 -0000       1.38
> > +++ dev/pci/drm/drm_linux.c 11 Jun 2019 18:54:38 -0000
> > @@ -1399,15 +1399,15 @@ drm_linux_init(void)
> >  {
> >     if (system_wq == NULL) {
> >             system_wq = (struct workqueue_struct *)
> > -               taskq_create("drmwq", 1, IPL_HIGH, 0);
> > +               taskq_create("drmwq", 4, IPL_HIGH, 0);
> >     }
> >     if (system_unbound_wq == NULL) {
> >             system_unbound_wq = (struct workqueue_struct *)
> > -               taskq_create("drmubwq", 1, IPL_HIGH, 0);
> > +               taskq_create("drmubwq", 4, IPL_HIGH, 0);
> >     }
> >     if (system_long_wq == NULL) {
> >             system_long_wq = (struct workqueue_struct *)
> > -               taskq_create("drmlwq", 1, IPL_HIGH, 0);
> > +               taskq_create("drmlwq", 4, IPL_HIGH, 0);
> >     }
> >  
> >     if (taskletq == NULL)
> > Index: dev/pci/drm/i915/intel_hotplug.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/pci/drm/i915/intel_hotplug.c,v
> > retrieving revision 1.2
> > diff -u -p -r1.2 intel_hotplug.c
> > --- dev/pci/drm/i915/intel_hotplug.c        14 Apr 2019 10:14:52 -0000      
> > 1.2
> > +++ dev/pci/drm/i915/intel_hotplug.c        11 Jun 2019 18:54:38 -0000
> > @@ -619,7 +619,6 @@ void intel_hpd_init_work(struct drm_i915
> >     INIT_WORK(&dev_priv->hotplug.hotplug_work, i915_hotplug_work_func);
> >     INIT_WORK(&dev_priv->hotplug.dig_port_work, i915_digport_work_func);
> >     INIT_WORK(&dev_priv->hotplug.poll_init_work, i915_hpd_poll_init_work);
> > -   dev_priv->hotplug.poll_init_work.tq = systq;
> >     INIT_DELAYED_WORK(&dev_priv->hotplug.reenable_work,
> >                       intel_hpd_irq_storm_reenable_work);
> >  }
> > Index: kern/kern_task.c
> > ===================================================================
> > RCS file: /cvs/src/sys/kern/kern_task.c,v
> > retrieving revision 1.25
> > diff -u -p -r1.25 kern_task.c
> > --- kern/kern_task.c        28 Apr 2019 04:20:40 -0000      1.25
> > +++ kern/kern_task.c        11 Jun 2019 18:54:39 -0000
> > @@ -43,6 +43,7 @@ struct taskq {
> >             TQ_S_DESTROYED
> >     }                        tq_state;
> >     unsigned int             tq_running;
> > +   unsigned int             tq_barrier;
> >     unsigned int             tq_nthreads;
> >     unsigned int             tq_flags;
> >     const char              *tq_name;
> > @@ -59,6 +60,7 @@ static const char taskq_sys_name[] = "sy
> >  struct taskq taskq_sys = {
> >     TQ_S_CREATED,
> >     0,
> > +   0,
> >     1,
> >     0,
> >     taskq_sys_name,
> > @@ -77,6 +79,7 @@ static const char taskq_sys_mp_name[] = 
> >  struct taskq taskq_sys_mp = {
> >     TQ_S_CREATED,
> >     0,
> > +   0,
> >     1,
> >     TASKQ_MPSAFE,
> >     taskq_sys_mp_name,
> > @@ -122,6 +125,7 @@ taskq_create(const char *name, unsigned 
> >  
> >     tq->tq_state = TQ_S_CREATED;
> >     tq->tq_running = 0;
> > +   tq->tq_barrier = 0;
> >     tq->tq_nthreads = nthreads;
> >     tq->tq_name = name;
> >     tq->tq_flags = flags;
> > @@ -161,6 +165,7 @@ taskq_destroy(struct taskq *tq)
> >             panic("unexpected %s tq state %u", tq->tq_name, tq->tq_state);
> >     }
> >  
> > +   tq->tq_barrier = 0;
> >     while (tq->tq_running > 0) {
> >             wakeup(tq);
> >             msleep(&tq->tq_running, &tq->tq_mtx, PWAIT, "tqdestroy", 0);
> > @@ -223,6 +228,7 @@ taskq_barrier(struct taskq *tq)
> >  
> >     WITNESS_CHECKORDER(&tq->tq_lock_object, LOP_NEWORDER, NULL);
> >  
> > +   SET(t.t_flags, TASK_BARRIER);
> >     task_add(tq, &t);
> >     cond_wait(&c, "tqbar");
> >  }
> > @@ -238,6 +244,7 @@ taskq_del_barrier(struct taskq *tq, stru
> >     if (task_del(tq, del))
> >             return;
> >  
> > +   SET(t.t_flags, TASK_BARRIER);
> >     task_add(tq, &t);
> >     cond_wait(&c, "tqbar");
> >  }
> > @@ -304,6 +311,7 @@ taskq_next_work(struct taskq *tq, struct
> >     struct task *next;
> >  
> >     mtx_enter(&tq->tq_mtx);
> > +retry:
> >     while ((next = TAILQ_FIRST(&tq->tq_worklist)) == NULL) {
> >             if (tq->tq_state != TQ_S_RUNNING) {
> >                     mtx_leave(&tq->tq_mtx);
> > @@ -311,6 +319,17 @@ taskq_next_work(struct taskq *tq, struct
> >             }
> >  
> >             msleep(tq, &tq->tq_mtx, PWAIT, "bored", 0);
> > +   }
> > +
> > +   if (ISSET(next->t_flags, TASK_BARRIER)) {
> > +           if (++tq->tq_barrier == tq->tq_nthreads) {
> > +                   tq->tq_barrier = 0;
> > +                   wakeup(tq);
> > +           } else {
> > +                   while (tq->tq_barrier > 0)
> > +                           msleep(tq, &tq->tq_mtx, PWAIT, "tqblk", 0);
> > +                   goto retry;
> > +           }
> >     }
> >  
> >     TAILQ_REMOVE(&tq->tq_worklist, next, t_entry);
> > Index: sys/task.h
> > ===================================================================
> > RCS file: /cvs/src/sys/sys/task.h,v
> > retrieving revision 1.15
> > diff -u -p -r1.15 task.h
> > --- sys/task.h      28 Apr 2019 04:20:40 -0000      1.15
> > +++ sys/task.h      11 Jun 2019 18:54:39 -0000
> > @@ -31,6 +31,7 @@ struct task {
> >  };
> >  
> >  #define TASK_ONQUEUE               1
> > +#define TASK_BARRIER               2
> >  
> >  TAILQ_HEAD(task_list, task);
> >  
> 

Reply via email to