On Thu, Jan 21, 2010 at 01:21:08PM +0800, Oliver Yang wrote:
> >With a large allocation (larger than 4K), your boundaries can
> >occur at unpredictable locations.  It sounds to me like this NIC
> >driver needs to bcopy the header into a preallocated
> >(ddi_dma_mem_alloc!) contiguous region, and use cookies for the
> >payload.
> >
> >Also, with LSO, the data is coming from *upstream*, so esballoc
> >might not have been used (probably won't have been!), and there
> >are *no* guarantees about how the IP stack formulates its mblks.
> This is an old issue which has been addressed with the solution you
> mentioned above, but I'm still wondering whether we could address
> this issue by improving the mblk cache.
> 
> These days I also encountered another issue which is similar with
> this issue, and I just discussed with other guys who said that slab
> can ensure the object size less than one page can not cross the page
> boundary.

Right now, the only ways to guarantee your buffers won't cross page boundaries
are:

1. Allocate exactly a page of data using kmem_alloc().  The returned buffer
   is guaranteed to be page-aligned, so there cannot be any page boundaries
   in it.

2. Create a cache with KMC_NOHASH.  This forces the slabs to be exactly a page
   in size.  It also turns off some debugging features.  This is used in
   several places in the kernel, mostly inside the HAT.

There was talk at one point about adding a "KMC_ONEPAGE" cache creation flag,
which would force the slabs to be a single page (so that you could get the
effect of KMC_NOHASH without turning off debugging features, but nothing
ever came of it.  (I'm not even sure a bug was ever filed.)

That being said, it seems like your current situation can't really rely on
anything about the input stream, so cache setting aren't really going to help.

If you're not already doing so, one way to speed it up would be to do:

        if (P2ALIGN((uintptr_t)ipheader, PAGESIZE) !=
            P2ALIGN((uintptr_t)ipheader + MAX_IPHEADER_SIZE, PAGESIZE)) {
                /* copy the ipheader aside and use a cookie */
        } else {
                /* use it in place, since it doesn't cross a page boundary */
        }

Since (as far as I can tell) an IP header is at most 60 bytes, you've got
a >90% chance that you won't have to do the copy.

Make sense?

Cheers,
- jonathan


_______________________________________________
opensolaris-code mailing list
opensolaris-code@opensolaris.org
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to