Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/xen/xen Add back non-512-byte aligned buffers suppo...
details: https://anonhg.NetBSD.org/src/rev/a09c309975b6
branches: trunk
changeset: 365654:a09c309975b6
user: bouyer <bouyer%NetBSD.org@localhost>
date: Sun Aug 26 11:31:56 2018 +0000
description:
Add back non-512-byte aligned buffers support (reverting 1.84).
Userland users of raw devices don't have to use sector-aligned buffers,
and e.g. disklabel doesn't.
anita tests on Xen should at last complete the install phase again.
diffstat:
sys/arch/xen/xen/xbd_xenbus.c | 62 +++++++++++++++++++++++++++++++++++-------
1 files changed, 51 insertions(+), 11 deletions(-)
diffs (132 lines):
diff -r 303b9f3ae654 -r a09c309975b6 sys/arch/xen/xen/xbd_xenbus.c
--- a/sys/arch/xen/xen/xbd_xenbus.c Sun Aug 26 08:54:03 2018 +0000
+++ b/sys/arch/xen/xen/xbd_xenbus.c Sun Aug 26 11:31:56 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xbd_xenbus.c,v 1.86 2018/08/21 18:55:08 jdolecek Exp $ */
+/* $NetBSD: xbd_xenbus.c,v 1.87 2018/08/26 11:31:56 bouyer Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xbd_xenbus.c,v 1.86 2018/08/21 18:55:08 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xbd_xenbus.c,v 1.87 2018/08/26 11:31:56 bouyer Exp $");
#include "opt_xen.h"
@@ -105,6 +105,7 @@
grant_ref_t req_gntref[BLKIF_MAX_SEGMENTS_PER_REQUEST];
int req_nr_segments; /* number of segments in this request */
struct buf *req_bp; /* buffer associated with this request */
+ void *req_data; /* pointer to the data buffer */
} req_rw;
struct {
int s_error;
@@ -115,6 +116,7 @@
#define req_gntref u.req_rw.req_gntref
#define req_nr_segments u.req_rw.req_nr_segments
#define req_bp u.req_rw.req_bp
+#define req_data u.req_rw.req_data
#define req_sync u.req_sync
struct xbd_xenbus_softc {
@@ -169,6 +171,9 @@
static void xbd_backend_changed(void *, XenbusState);
static void xbd_connect(struct xbd_xenbus_softc *);
+static int xbd_map_align(struct xbd_req *);
+static void xbd_unmap_align(struct xbd_req *);
+
static void xbdminphys(struct buf *);
CFATTACH_DECL3_NEW(xbd, sizeof(struct xbd_xenbus_softc),
@@ -694,7 +699,6 @@
bp = xbdreq->req_bp;
KASSERT(bp != NULL);
- xbdreq->req_bp = NULL;
DPRINTF(("%s(%p): b_bcount = %ld\n", __func__,
bp, (long)bp->b_bcount));
@@ -704,7 +708,11 @@
goto next;
}
/* b_resid was set in dk_start */
+ if (__predict_false(
+ xbdreq->req_data != NULL && bp->b_data != xbdreq->req_data))
+ xbd_unmap_align(xbdreq);
next:
+ xbdreq->req_bp = NULL;
dk_done(&sc->sc_dksc, bp);
SLIST_INSERT_HEAD(&sc->sc_xbdreq_head, xbdreq, req_next);
@@ -971,14 +979,16 @@
goto out;
}
- if ((vaddr_t)bp->b_data & (XEN_BSIZE - 1)) {
- DPRINTF(("xbd_diskstart: no align\n"));
- error = EINVAL;
- goto out;
+ xbdreq->req_bp = bp;
+ xbdreq->req_data = bp->b_data;
+ if (__predict_false((vaddr_t)bp->b_data & (XEN_BSIZE - 1))) {
+ if (__predict_false(xbd_map_align(xbdreq) != 0)) {
+ DPRINTF(("xbd_diskstart: no align\n"));
+ error = EAGAIN;
+ goto out;
+ }
}
- xbdreq->req_bp = bp;
-
SLIST_REMOVE_HEAD(&sc->sc_xbdreq_head, req_next);
req = RING_GET_REQUEST(&sc->sc_ring, sc->sc_ring.req_prod_pvt);
req->id = xbdreq->req_id;
@@ -987,8 +997,8 @@
req->sector_number = bp->b_rawblkno;
req->handle = sc->sc_handle;
- va = (vaddr_t)bp->b_data & ~PAGE_MASK;
- off = (vaddr_t)bp->b_data & PAGE_MASK;
+ va = (vaddr_t)xbdreq->req_data & ~PAGE_MASK;
+ off = (vaddr_t)xbdreq->req_data & PAGE_MASK;
bcount = bp->b_bcount;
bp->b_resid = 0;
for (seg = 0; bcount > 0;) {
@@ -1028,3 +1038,33 @@
err:
return error;
}
+
+static int
+xbd_map_align(struct xbd_req *req)
+{
+ int s = splvm(); /* XXXSMP - bogus? */
+ int rc;
+
+ rc = uvm_km_kmem_alloc(kmem_va_arena,
+ req->req_bp->b_bcount, (VM_NOSLEEP | VM_INSTANTFIT),
+ (vmem_addr_t *)&req->req_data);
+ splx(s);
+ if (__predict_false(rc != 0))
+ return ENOMEM;
+ if ((req->req_bp->b_flags & B_READ) == 0)
+ memcpy(req->req_data, req->req_bp->b_data,
+ req->req_bp->b_bcount);
+ return 0;
+}
+
+static void
+xbd_unmap_align(struct xbd_req *req)
+{
+ int s;
+ if (req->req_bp->b_flags & B_READ)
+ memcpy(req->req_bp->b_data, req->req_data,
+ req->req_bp->b_bcount);
+ s = splvm(); /* XXXSMP - bogus? */
+ uvm_km_kmem_free(kmem_va_arena, (vaddr_t)req->req_data, req->req_bp->b_bcount);
+ splx(s);
+}
Home |
Main Index |
Thread Index |
Old Index