Minchan Kim <minc...@kernel.org> writes: > On Wed, May 28, 2014 at 12:04:09PM +0300, Michael S. Tsirkin wrote: >> On Wed, May 28, 2014 at 03:53:59PM +0900, Minchan Kim wrote: >> > [ 1065.604404] kworker/-5766 0d..2 1071625993us : stack_trace_call: >> > 9) 6456 80 __kmalloc+0x1cb/0x200 >> > [ 1065.604404] kworker/-5766 0d..2 1071625993us : stack_trace_call: >> > 10) 6376 376 vring_add_indirect+0x36/0x200 >> > [ 1065.604404] kworker/-5766 0d..2 1071625993us : stack_trace_call: >> > 11) 6000 144 virtqueue_add_sgs+0x2e2/0x320
Hmm, we can actually skip the vring_add_indirect if we're hurting for stack. It just means the request will try to fit linearly in the ring, rather than using indirect. diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 1e443629f76d..496e727cefc8 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -184,6 +184,13 @@ static inline int vring_add_indirect(struct vring_virtqueue *vq, return head; } +/* The Morton Technique */ +static noinline bool stack_trouble(void) +{ + unsigned long sp = (unsigned long)&sp; + return sp - (sp & ~(THREAD_SIZE - 1)) < 3000; +} + static inline int virtqueue_add(struct virtqueue *_vq, struct scatterlist *sgs[], struct scatterlist *(*next) @@ -226,7 +233,7 @@ static inline int virtqueue_add(struct virtqueue *_vq, /* If the host supports indirect descriptor tables, and we have multiple * buffers, then go indirect. FIXME: tune this threshold */ - if (vq->indirect && total_sg > 1 && vq->vq.num_free) { + if (vq->indirect && total_sg > 1 && vq->vq.num_free && !stack_trouble()) { head = vring_add_indirect(vq, sgs, next, total_sg, total_out, total_in, out_sgs, in_sgs, gfp); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/