To my mind the performance is less interesting than making code more robust by avoiding the possibility that the taskq ent allocation can fail.<br><br>Sent from my phone<br><br>----- Reply message -----<br>From: "Garrett D'Amore" <garrett@damore.org><br>Date: Sat, Feb 12, 2011 08:49<br>Subject: [illumos-Developer] "preallocation" style taskqs<br>To: "Eric Schrock" <eric.schrock@delphix.com><br>Cc: <developer@lists.illumos.org><br><br><br>On Fri, 2011-02-11 at 17:34 -0500, Eric Schrock wrote:<br>> Seems reasonable to me.  Out of curiosity, do you have any perf<br>> numbers?<br><br>No numbers... its just something that has bugged me many many times.<br>There are cases where I know of bugs that result in far too many<br>allocations due to dispatching to the same queue millions of jobs, and<br>other cases where I know we are hitting the backing kmem store pretty<br>hard.<br><br>Collecting numbers would be done on a case by case basis as we convert<br>individual callers to use the new interface.<br><br>> <br>> Do we need it to be part of the DDI, or can we just make it<br>> consolidation private?  My concern is that if there is going to be any<br>> significant effort around taskq scalability (which there probably<br>> should be), we may want to change this structure.  And what does it<br>> even mean to be in the DDI in Illumos?  Do we have a 9F manpage<br>> repository that would be modified to include this?<br><br>I'd be happy to have a non-DDI version to start with.  The question<br>about what a DDI means are interesting... that presumes a functioning<br>ARC (there is developer-council, but that's mostly quiescent at<br>present), and real doc efforts, etc.<br><br><br>> On a side note, if you're looking at general taskq scalability, one<br>> major problem is the lack of CPU affinity for non-dynamic taskqs.<br><br>Yes, although its not entirely clear how to handle that generically --<br>but perhaps tagging a cpuid and dispatching to a per-cpu list first<br>would be a start.<br><br>        - Garrett<br>> <br>> <br>> Thanks,<br>> <br>> <br>> - Eric<br>> <br>> On Fri, Feb 11, 2011 at 4:14 PM, Garrett D'Amore <garrett@damore.org><br>> wrote:<br>>         So I've been wanting to do this for a long time.... and I<br>>         think that it<br>>         relates to certain bugs.<br>>         <br>>         In illumos, taskqs are used *heavily* for scheduling, because<br>>         they are<br>>         extremely convenient to work with.<br>>         <br>>         However, one thing that often gets overlooked is that the<br>>         implementation<br>>         in illumos requires hitting up a shared list, or possibly even<br>>         doing a<br>>         kmem_cache_alloc() to get a task entry.<br>>         <br>>         Many of the uses of taskqs could be made to eliminate this<br>>         code path,<br>>         reducing contention on hot paths (e.g. taskq dispatch can be<br>>         called up<br>>         to once per packet for networking!) by having support for<br>>         preallocated<br>>         taskq_ent_t's that were stored within data structures.<br>>         <br>>         For example, zio_t could use an inline taskq_ent_t, to handle<br>>         dispatching of zio_execute or zio_reexecute (although note<br>>         that this<br>>         only makes sense where a zio can only be dispatched onto a<br>>         single such<br>>         taskq.)<br>>         <br>>         This could also offer a "guaranteed" form of taskq dispatch,<br>>         since if<br>>         the data structure is already preallocated there is no chance<br>>         of an<br>>         allocation failure, even in situations which might be<br>>         challenging, like<br>>         interrupt context.<br>>         <br>>         For folks trying to achieve extreme performance, I think this<br>>         could win.<br>>         <br>>         To this end, I'm proposing the following:<br>>         <br>>         sizeof (taskq_ent_t) become a fixed part of the DDI.  (The<br>>         actual<br>>         structure contents would be undocumented/opaque.)<br>>         <br>>         creation of a new interface:<br>>         <br>>         void ddi_taskq_dispatch_prealloc(ddi_taskq_t *, void<br>>         (*func)(void *),<br>>         void *arg, uint_t flags, taskq_ent_t *);<br>>         <br>>         Note that from a simple matter of ease of implementation, this<br>>         interface<br>>         would *only* be available to non-DYNAMIC taskqs.  (With the<br>>         potential to<br>>         allocate new threads, etc. dynamic taskqs don't seem well<br>>         suited to<br>>         preallocation.)<br>>         <br>>         Note that IIRC NetBSD taskqs work much like I'm suggesting<br>>         here, except<br>>         that they are *always* prealloc style.  (That may have changed<br>>         since I<br>>         last looked though.)<br>>         <br>>         Thoughts?<br>>         <br>>                - Garrett<br>>         <br>>         <br>>         _______________________________________________<br>>         Developer mailing list<br>>         Developer@lists.illumos.org<br>>         <a href="http://lists.illumos.org/m/listinfo/developer">http://lists.illumos.org/m/listinfo/developer</a><br>> <br>> <br>> <br>> -- <br>> Eric Schrock<br>> Delphix<br>> <br>> <br>> 275 Middlefield Road, Suite 50<br>> Menlo Park, CA 94025<br>> <a href="http://www.delphix.com">http://www.delphix.com</a><br>> <br>> <br><br><br><br>_______________________________________________<br>Developer mailing list<br>Developer@lists.illumos.org<br><a href="http://lists.illumos.org/m/listinfo/developer">http://lists.illumos.org/m/listinfo/developer</a><br><br><br>