Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linuxkpi/common/include/linux/scatterlist.h
/*- | /*- | ||||
* Copyright (c) 2010 Isilon Systems, Inc. | * Copyright (c) 2010 Isilon Systems, Inc. | ||||
* Copyright (c) 2010 iX Systems, Inc. | * Copyright (c) 2010 iX Systems, Inc. | ||||
* Copyright (c) 2010 Panasas, Inc. | * Copyright (c) 2010 Panasas, Inc. | ||||
* Copyright (c) 2013-2017 Mellanox Technologies, Ltd. | * Copyright (c) 2013-2017 Mellanox Technologies, Ltd. | ||||
* Copyright (c) 2015 Matthew Dillon <dillon@backplane.com> | * Copyright (c) 2015 Matthew Dillon <dillon@backplane.com> | ||||
* Copyright (c) 2016 Matthew Macy | |||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice unmodified, this list of conditions, and the following | * notice unmodified, this list of conditions, and the following | ||||
* disclaimer. | * disclaimer. | ||||
▲ Show 20 Lines • Show All 512 Lines • ▼ Show 20 Lines | for_each_sg_page(sgl, &piter, nents, 0) { | ||||
buflen -= len; | buflen -= len; | ||||
if (buflen == 0) | if (buflen == 0) | ||||
break; | break; | ||||
b += len; | b += len; | ||||
} | } | ||||
sched_unpin(); | sched_unpin(); | ||||
return (copied); | return (copied); | ||||
} | |||||
static inline size_t | |||||
sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents, | |||||
const void *buf, size_t buflen) | |||||
{ | |||||
return (sg_pcopy_from_buffer(sgl, nents, buf, buflen, 0)); | |||||
} | |||||
static inline size_t | |||||
sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents, | |||||
void *buf, size_t buflen, off_t offset) | |||||
{ | |||||
struct sg_page_iter iter; | |||||
struct scatterlist *sg; | |||||
struct page *page; | |||||
struct sf_buf *sf; | |||||
char *vaddr; | |||||
size_t total = 0; | |||||
size_t len; | |||||
if (!PMAP_HAS_DMAP) | |||||
sched_pin(); | |||||
for_each_sg_page(sgl, &iter, nents, 0) { | |||||
sg = iter.sg; | |||||
if (offset >= sg->length) { | |||||
offset -= sg->length; | |||||
continue; | |||||
} | |||||
len = ulmin(buflen, sg->length - offset); | |||||
markj: `min()` will truncate parameters to unsigned int. I guess it should be `ulmin()`. | |||||
Not Done Inline ActionsThere is also the MIN() macro and min_t(). hselasky: There is also the MIN() macro and min_t(). | |||||
if (len == 0) | |||||
break; | |||||
Done Inline ActionsDo you need to use kmap/kunmap here or can you not just pin the entire loop and us sf_* directly as done above? bz: Do you need to use kmap/kunmap here or can you not just pin the entire loop and us sf_*… | |||||
Done Inline Actionskmap/kunmap expands to NO-OP on most of supported archs wulf: kmap/kunmap expands to NO-OP on most of supported archs | |||||
Done Inline Actions
loop is rewritten to use pin/unpin and sf_* directly wulf: > Do you need to use kmap/kunmap here or can you not just pin the entire loop and us sf_*… | |||||
page = sg_page_iter_page(&iter); | |||||
if (!PMAP_HAS_DMAP) { | |||||
sf = sf_buf_alloc(page, SFB_CPUPRIVATE | SFB_NOWAIT); | |||||
if (sf == NULL) | |||||
break; | |||||
vaddr = (char *)sf_buf_kva(sf); | |||||
} else | |||||
vaddr = (char *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(page)); | |||||
memcpy(buf, vaddr + sg->offset + offset, len); | |||||
if (!PMAP_HAS_DMAP) | |||||
sf_buf_free(sf); | |||||
/* start at beginning of next page */ | |||||
offset = 0; | |||||
/* advance buffer */ | |||||
buf = (char *)buf + len; | |||||
buflen -= len; | |||||
total += len; | |||||
} | |||||
if (!PMAP_HAS_DMAP) | |||||
sched_unpin(); | |||||
return (total); | |||||
} | } | ||||
#endif /* _LINUX_SCATTERLIST_H_ */ | #endif /* _LINUX_SCATTERLIST_H_ */ |
min() will truncate parameters to unsigned int. I guess it should be ulmin().