summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2017-09-21 23:10:59 +0000
committerjhb <jhb@FreeBSD.org>2017-09-21 23:10:59 +0000
commitfce10b30fadda47ff6a223a77a8c07e13756f642 (patch)
tree96eded014d1cee59433886a120f51908c04db731
parent82925f9c9f03b31d8520c344e2f5b3da8b4707ff (diff)
downloadFreeBSD-src-fce10b30fadda47ff6a223a77a8c07e13756f642.zip
FreeBSD-src-fce10b30fadda47ff6a223a77a8c07e13756f642.tar.gz
MFC 323630: Avoid reusing the wrong buffer for a DDP AIO request.
To optimize the case of ping-ponging between two buffers, the DDP code caches the last two buffers used keeping the pages wired and page pods stored in the NIC's RAM. If a new aio_read() request uses one of the same buffers, then the work of holding pages, etc. can be avoided. However, the starting virtual address of an aio buffer was not saved, only the page count, length, and initial page offset. Thus, an aio_read() request could match a different buffer in the address space. (Earlier during development vm_fault_hold_quick_pages() was always called and the vm_page_t values were compared, but that was eventually removed without being adequately replaced.) Fix by storing the starting virtual address and comparing that (along with other fields) to determine if a buffer can be reused. Sponsored by: Chelsio Communications
-rw-r--r--sys/dev/cxgbe/tom/t4_ddp.c4
-rw-r--r--sys/dev/cxgbe/tom/t4_tom.h1
2 files changed, 4 insertions, 1 deletions
diff --git a/sys/dev/cxgbe/tom/t4_ddp.c b/sys/dev/cxgbe/tom/t4_ddp.c
index 762eb2e..0cd9fd4 100644
--- a/sys/dev/cxgbe/tom/t4_ddp.c
+++ b/sys/dev/cxgbe/tom/t4_ddp.c
@@ -1277,7 +1277,8 @@ pscmp(struct pageset *ps, struct vmspace *vm, vm_offset_t start, int npages,
int pgoff, int len)
{
- if (ps->npages != npages || ps->offset != pgoff || ps->len != len)
+ if (ps->start != start || ps->npages != npages ||
+ ps->offset != pgoff || ps->len != len)
return (1);
return (ps->vm != vm || ps->vm_timestamp != vm->vm_map.timestamp);
@@ -1378,6 +1379,7 @@ hold_aio(struct toepcb *toep, struct kaiocb *job, struct pageset **pps)
ps->len = job->uaiocb.aio_nbytes;
atomic_add_int(&vm->vm_refcnt, 1);
ps->vm = vm;
+ ps->start = start;
CTR5(KTR_CXGBE, "%s: tid %d, new pageset %p for job %p, npages %d",
__func__, toep->tid, ps, job, ps->npages);
diff --git a/sys/dev/cxgbe/tom/t4_tom.h b/sys/dev/cxgbe/tom/t4_tom.h
index 5a774fd..537b698 100644
--- a/sys/dev/cxgbe/tom/t4_tom.h
+++ b/sys/dev/cxgbe/tom/t4_tom.h
@@ -112,6 +112,7 @@ struct pageset {
int len;
struct ppod_reservation prsv;
struct vmspace *vm;
+ vm_offset_t start;
u_int vm_timestamp;
};
OpenPOWER on IntegriCloud