* [PATCH v2 08/21] dm-crypt: Make use of the new sg_map helper in 4 call sites
From: Logan Gunthorpe @ 2017-04-25 18:20 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-raid-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA,
linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-scsi-u79uwXL29TY76Z2rM5mHXA,
open-iscsi-/JYPxA39Uh5TLH3MbocFFw,
megaraidlinux.pdl-dY08KVG/lbpWk0Htik3J/w,
sparmaintainer-GLv8BlqOqDDQT0dZR+AlfA,
devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
target-devel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
dm-devel-H+wXaHxf7aLQT0dZR+AlfA
Cc: Jens Axboe, James E.J. Bottomley, Mike Snitzer,
Martin K. Petersen, Matthew Wilcox, Greg Kroah-Hartman,
Sumit Semwal, Christoph Hellwig, Alasdair Kergon
In-Reply-To: <1493144468-22493-1-git-send-email-logang-OTvnGxWRz7hWk0Htik3J/w@public.gmane.org>
Very straightforward conversion to the new function in all four spots.
Signed-off-by: Logan Gunthorpe <logang-OTvnGxWRz7hWk0Htik3J/w@public.gmane.org>
Cc: Alasdair Kergon <agk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Mike Snitzer <snitzer-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
drivers/md/dm-crypt.c | 39 ++++++++++++++++++++++++++-------------
1 file changed, 26 insertions(+), 13 deletions(-)
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 8dbecf1..841f1fc 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -635,9 +635,12 @@ static int crypt_iv_lmk_gen(struct crypt_config *cc, u8 *iv,
if (bio_data_dir(dmreq->ctx->bio_in) == WRITE) {
sg = crypt_get_sg_data(cc, dmreq->sg_in);
- src = kmap_atomic(sg_page(sg));
- r = crypt_iv_lmk_one(cc, iv, dmreq, src + sg->offset);
- kunmap_atomic(src);
+ src = sg_map(sg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(src))
+ return PTR_ERR(src);
+
+ r = crypt_iv_lmk_one(cc, iv, dmreq, src);
+ sg_unmap(sg, src, 0, SG_KMAP_ATOMIC);
} else
memset(iv, 0, cc->iv_size);
@@ -655,14 +658,18 @@ static int crypt_iv_lmk_post(struct crypt_config *cc, u8 *iv,
return 0;
sg = crypt_get_sg_data(cc, dmreq->sg_out);
- dst = kmap_atomic(sg_page(sg));
- r = crypt_iv_lmk_one(cc, iv, dmreq, dst + sg->offset);
+ dst = sg_map(sg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(dst))
+ return PTR_ERR(dst);
+
+ r = crypt_iv_lmk_one(cc, iv, dmreq, dst);
/* Tweak the first block of plaintext sector */
if (!r)
- crypto_xor(dst + sg->offset, iv, cc->iv_size);
+ crypto_xor(dst, iv, cc->iv_size);
+
+ sg_unmap(sg, dst, 0, SG_KMAP_ATOMIC);
- kunmap_atomic(dst);
return r;
}
@@ -786,9 +793,12 @@ static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv,
/* Remove whitening from ciphertext */
if (bio_data_dir(dmreq->ctx->bio_in) != WRITE) {
sg = crypt_get_sg_data(cc, dmreq->sg_in);
- src = kmap_atomic(sg_page(sg));
- r = crypt_iv_tcw_whitening(cc, dmreq, src + sg->offset);
- kunmap_atomic(src);
+ src = sg_map(sg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(src))
+ return PTR_ERR(src);
+
+ r = crypt_iv_tcw_whitening(cc, dmreq, src);
+ sg_unmap(sg, src, 0, SG_KMAP_ATOMIC);
}
/* Calculate IV */
@@ -812,9 +822,12 @@ static int crypt_iv_tcw_post(struct crypt_config *cc, u8 *iv,
/* Apply whitening on ciphertext */
sg = crypt_get_sg_data(cc, dmreq->sg_out);
- dst = kmap_atomic(sg_page(sg));
- r = crypt_iv_tcw_whitening(cc, dmreq, dst + sg->offset);
- kunmap_atomic(dst);
+ dst = sg_map(sg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(dst))
+ return PTR_ERR(dst);
+
+ r = crypt_iv_tcw_whitening(cc, dmreq, dst);
+ sg_unmap(sg, dst, 0, SG_KMAP_ATOMIC);
return r;
}
--
2.1.4
^ permalink raw reply related
* [PATCH v2 07/21] crypto: shash, caam: Make use of the new sg_map helper function
From: Logan Gunthorpe @ 2017-04-25 18:20 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-raid-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA,
linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-scsi-u79uwXL29TY76Z2rM5mHXA,
open-iscsi-/JYPxA39Uh5TLH3MbocFFw,
megaraidlinux.pdl-dY08KVG/lbpWk0Htik3J/w,
sparmaintainer-GLv8BlqOqDDQT0dZR+AlfA,
devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
target-devel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
dm-devel-H+wXaHxf7aLQT0dZR+AlfA
Cc: Jens Axboe, James E.J. Bottomley, Herbert Xu, Martin K. Petersen,
Matthew Wilcox, Greg Kroah-Hartman, Sumit Semwal, David S. Miller,
Christoph Hellwig
In-Reply-To: <1493144468-22493-1-git-send-email-logang-OTvnGxWRz7hWk0Htik3J/w@public.gmane.org>
Very straightforward conversion to the new function in the caam driver
and shash library.
Signed-off-by: Logan Gunthorpe <logang-OTvnGxWRz7hWk0Htik3J/w@public.gmane.org>
Cc: Herbert Xu <herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
---
crypto/shash.c | 9 ++++++---
drivers/crypto/caam/caamalg.c | 8 +++-----
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/crypto/shash.c b/crypto/shash.c
index 5e31c8d..5914881 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -283,10 +283,13 @@ int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc)
if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
void *data;
- data = kmap_atomic(sg_page(sg));
- err = crypto_shash_digest(desc, data + offset, nbytes,
+ data = sg_map(sg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ err = crypto_shash_digest(desc, data, nbytes,
req->result);
- kunmap_atomic(data);
+ sg_unmap(sg, data, 0, SG_KMAP_ATOMIC);
crypto_yield(desc->flags);
} else
err = crypto_shash_init(desc) ?:
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 398807d..62d2f5d 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -89,7 +89,6 @@ static void dbg_dump_sg(const char *level, const char *prefix_str,
struct scatterlist *sg, size_t tlen, bool ascii)
{
struct scatterlist *it;
- void *it_page;
size_t len;
void *buf;
@@ -98,19 +97,18 @@ static void dbg_dump_sg(const char *level, const char *prefix_str,
* make sure the scatterlist's page
* has a valid virtual memory mapping
*/
- it_page = kmap_atomic(sg_page(it));
- if (unlikely(!it_page)) {
+ buf = sg_map(it, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(buf)) {
printk(KERN_ERR "dbg_dump_sg: kmap failed\n");
return;
}
- buf = it_page + it->offset;
len = min_t(size_t, tlen, it->length);
print_hex_dump(level, prefix_str, prefix_type, rowsize,
groupsize, buf, len, ascii);
tlen -= len;
- kunmap_atomic(it_page);
+ sg_unmap(it, buf, 0, SG_KMAP_ATOMIC);
}
}
#endif
--
2.1.4
^ permalink raw reply related
* [PATCH v2 06/21] crypto: hifn_795x: Make use of the new sg_map helper function
From: Logan Gunthorpe @ 2017-04-25 18:20 UTC (permalink / raw)
To: linux-kernel, linux-crypto, linux-media, dri-devel, intel-gfx,
linux-raid, linux-mmc, linux-nvdimm, linux-scsi, open-iscsi,
megaraidlinux.pdl, sparmaintainer, devel, target-devel, netdev,
linux-rdma, dm-devel
Cc: Jens Axboe, James E.J. Bottomley, Herbert Xu, Martin K. Petersen,
Matthew Wilcox, Greg Kroah-Hartman, Sumit Semwal, David S. Miller,
Ross Zwisler, Dan Williams, Stephen Bates, Logan Gunthorpe,
Christoph Hellwig
In-Reply-To: <1493144468-22493-1-git-send-email-logang@deltatee.com>
Conversion of a couple kmap_atomic instances to the sg_map helper
function.
However, it looks like there was a bug in the original code: the source
scatter lists offset (t->offset) was passed to ablkcipher_get which
added it to the destination address. This doesn't make a lot of
sense, but t->offset is likely always zero anyway. So, this patch cleans
that brokeness up.
Also, a change to the error path: if ablkcipher_get failed, everything
seemed to proceed as if it hadn't. Setting 'error' should hopefully
clear that up.
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
---
drivers/crypto/hifn_795x.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index e09d405..34b1870 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -1619,7 +1619,7 @@ static int hifn_start_device(struct hifn_device *dev)
return 0;
}
-static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset,
+static int ablkcipher_get(void *saddr, unsigned int *srestp,
struct scatterlist *dst, unsigned int size, unsigned int *nbytesp)
{
unsigned int srest = *srestp, nbytes = *nbytesp, copy;
@@ -1632,15 +1632,17 @@ static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset
while (size) {
copy = min3(srest, dst->length, size);
- daddr = kmap_atomic(sg_page(dst));
- memcpy(daddr + dst->offset + offset, saddr, copy);
- kunmap_atomic(daddr);
+ daddr = sg_map(dst, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(daddr))
+ return PTR_ERR(daddr);
+
+ memcpy(daddr, saddr, copy);
+ sg_unmap(dst, daddr, 0, SG_KMAP_ATOMIC);
nbytes -= copy;
size -= copy;
srest -= copy;
saddr += copy;
- offset = 0;
pr_debug("%s: copy: %u, size: %u, srest: %u, nbytes: %u.\n",
__func__, copy, size, srest, nbytes);
@@ -1671,11 +1673,12 @@ static inline void hifn_complete_sa(struct hifn_device *dev, int i)
static void hifn_process_ready(struct ablkcipher_request *req, int error)
{
+ int err;
struct hifn_request_context *rctx = ablkcipher_request_ctx(req);
if (rctx->walk.flags & ASYNC_FLAGS_MISALIGNED) {
unsigned int nbytes = req->nbytes;
- int idx = 0, err;
+ int idx = 0;
struct scatterlist *dst, *t;
void *saddr;
@@ -1695,17 +1698,24 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
continue;
}
- saddr = kmap_atomic(sg_page(t));
+ saddr = sg_map(t, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(saddr)) {
+ if (!error)
+ error = PTR_ERR(saddr);
+ break;
+ }
+
+ err = ablkcipher_get(saddr, &t->length,
+ dst, nbytes, &nbytes);
+ sg_unmap(t, saddr, 0, SG_KMAP_ATOMIC);
- err = ablkcipher_get(saddr, &t->length, t->offset,
- dst, nbytes, &nbytes);
if (err < 0) {
- kunmap_atomic(saddr);
+ if (!error)
+ error = err;
break;
}
idx += err;
- kunmap_atomic(saddr);
}
hifn_cipher_walk_exit(&rctx->walk);
--
2.1.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [PATCH v2 05/21] drm/i915: Make use of the new sg_map helper function
From: Logan Gunthorpe @ 2017-04-25 18:20 UTC (permalink / raw)
To: linux-kernel, linux-crypto, linux-media, dri-devel, intel-gfx,
linux-raid, linux-mmc, linux-nvdimm, linux-scsi, open-iscsi,
megaraidlinux.pdl, sparmaintainer, devel, target-devel, netdev,
linux-rdma, dm-devel
Cc: Jens Axboe, James E.J. Bottomley, Martin K. Petersen,
Matthew Wilcox, Greg Kroah-Hartman, Sumit Semwal, Ross Zwisler,
Dan Williams, Stephen Bates, Logan Gunthorpe, Christoph Hellwig
In-Reply-To: <1493144468-22493-1-git-send-email-logang@deltatee.com>
This is a single straightforward conversion from kmap to sg_map.
We also create the i915_gem_object_unmap function to common up the
unmap code.
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/i915_gem.c | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 07e9b27..2c33000 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2202,6 +2202,15 @@ static void __i915_gem_object_reset_page_iter(struct drm_i915_gem_object *obj)
radix_tree_delete(&obj->mm.get_page.radix, iter.index);
}
+static void i915_gem_object_unmap(const struct drm_i915_gem_object *obj,
+ void *ptr)
+{
+ if (is_vmalloc_addr(ptr))
+ vunmap(ptr);
+ else
+ sg_unmap(obj->mm.pages->sgl, ptr, 0, SG_KMAP);
+}
+
void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
enum i915_mm_subclass subclass)
{
@@ -2229,10 +2238,7 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
void *ptr;
ptr = ptr_mask_bits(obj->mm.mapping);
- if (is_vmalloc_addr(ptr))
- vunmap(ptr);
- else
- kunmap(kmap_to_page(ptr));
+ i915_gem_object_unmap(obj, ptr);
obj->mm.mapping = NULL;
}
@@ -2499,8 +2505,11 @@ static void *i915_gem_object_map(const struct drm_i915_gem_object *obj,
void *addr;
/* A single page can always be kmapped */
- if (n_pages == 1 && type == I915_MAP_WB)
- return kmap(sg_page(sgt->sgl));
+ if (n_pages == 1 && type == I915_MAP_WB) {
+ addr = sg_map(sgt->sgl, 0, SG_KMAP);
+ if (IS_ERR(addr))
+ return NULL;
+ }
if (n_pages > ARRAY_SIZE(stack_pages)) {
/* Too big for stack -- allocate temporary array instead */
@@ -2567,11 +2576,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
goto err_unpin;
}
- if (is_vmalloc_addr(ptr))
- vunmap(ptr);
- else
- kunmap(kmap_to_page(ptr));
-
+ i915_gem_object_unmap(obj, ptr);
ptr = obj->mm.mapping = NULL;
}
--
2.1.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [PATCH v2 04/21] target: Make use of the new sg_map function at 16 call sites
From: Logan Gunthorpe @ 2017-04-25 18:20 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-raid-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA,
linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-scsi-u79uwXL29TY76Z2rM5mHXA,
open-iscsi-/JYPxA39Uh5TLH3MbocFFw,
megaraidlinux.pdl-dY08KVG/lbpWk0Htik3J/w,
sparmaintainer-GLv8BlqOqDDQT0dZR+AlfA,
devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
target-devel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
dm-devel-H+wXaHxf7aLQT0dZR+AlfA
Cc: Jens Axboe, James E.J. Bottomley, Martin K. Petersen,
Matthew Wilcox, Greg Kroah-Hartman, Nicholas A. Bellinger,
Sumit Semwal, Christoph Hellwig
In-Reply-To: <1493144468-22493-1-git-send-email-logang-OTvnGxWRz7hWk0Htik3J/w@public.gmane.org>
Fairly straightforward conversions in all spots. In a couple of cases
any error gets propogated up should sg_map fail. In other
cases a warning is issued if the kmap fails seeing there's no
clear error path. This should not be an issue until someone tries to
use unmappable memory in the sgl with this driver.
Signed-off-by: Logan Gunthorpe <logang-OTvnGxWRz7hWk0Htik3J/w@public.gmane.org>
Cc: "Nicholas A. Bellinger" <nab-IzHhD5pYlfBP7FQvKIMDCQ@public.gmane.org>
---
drivers/target/iscsi/iscsi_target.c | 29 +++++++---
drivers/target/target_core_rd.c | 3 +-
drivers/target/target_core_sbc.c | 103 +++++++++++++++++++++------------
drivers/target/target_core_transport.c | 18 ++++--
drivers/target/target_core_user.c | 45 +++++++++-----
include/target/target_core_backend.h | 4 +-
6 files changed, 134 insertions(+), 68 deletions(-)
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index e3f9ed3..3ab8d21 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -578,7 +578,7 @@ iscsit_xmit_nondatain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
}
static int iscsit_map_iovec(struct iscsi_cmd *, struct kvec *, u32, u32);
-static void iscsit_unmap_iovec(struct iscsi_cmd *);
+static void iscsit_unmap_iovec(struct iscsi_cmd *, struct kvec *);
static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsi_cmd *,
u32, u32, u32, u8 *);
static int
@@ -645,7 +645,7 @@ iscsit_xmit_datain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
ret = iscsit_fe_sendpage_sg(cmd, conn);
- iscsit_unmap_iovec(cmd);
+ iscsit_unmap_iovec(cmd, &cmd->iov_data[1]);
if (ret < 0) {
iscsit_tx_thread_wait_for_tcp(conn);
@@ -924,7 +924,10 @@ static int iscsit_map_iovec(
while (data_length) {
u32 cur_len = min_t(u32, data_length, sg->length - page_off);
- iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off;
+ iov[i].iov_base = sg_map(sg, page_off, SG_KMAP);
+ if (IS_ERR(iov[i].iov_base))
+ goto map_err;
+
iov[i].iov_len = cur_len;
data_length -= cur_len;
@@ -936,17 +939,25 @@ static int iscsit_map_iovec(
cmd->kmapped_nents = i;
return i;
+
+map_err:
+ cmd->kmapped_nents = i - 1;
+ iscsit_unmap_iovec(cmd, iov);
+ return -1;
}
-static void iscsit_unmap_iovec(struct iscsi_cmd *cmd)
+static void iscsit_unmap_iovec(struct iscsi_cmd *cmd, struct kvec *iov)
{
u32 i;
struct scatterlist *sg;
+ unsigned int page_off = cmd->first_data_sg_off;
sg = cmd->first_data_sg;
- for (i = 0; i < cmd->kmapped_nents; i++)
- kunmap(sg_page(&sg[i]));
+ for (i = 0; i < cmd->kmapped_nents; i++) {
+ sg_unmap(&sg[i], iov[i].iov_base, page_off, SG_KMAP);
+ page_off = 0;
+ }
}
static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn)
@@ -1609,7 +1620,7 @@ iscsit_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
- iscsit_unmap_iovec(cmd);
+ iscsit_unmap_iovec(cmd, iov);
if (rx_got != rx_size)
return -1;
@@ -1710,7 +1721,7 @@ int iscsit_setup_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
if (!cmd)
return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
(unsigned char *)hdr);
-
+
return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
(unsigned char *)hdr);
}
@@ -2625,7 +2636,7 @@ static int iscsit_handle_immediate_data(
rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
- iscsit_unmap_iovec(cmd);
+ iscsit_unmap_iovec(cmd, cmd->iov_data);
if (rx_got != rx_size) {
iscsit_rx_thread_wait_for_tcp(conn);
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index 5f23f34..348211c 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -432,7 +432,8 @@ static sense_reason_t rd_do_prot_rw(struct se_cmd *cmd, bool is_read)
cmd->t_prot_sg, 0);
}
if (!rc)
- sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg, prot_offset);
+ rc = sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg,
+ prot_offset);
return rc;
}
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index ee35c90..8ac07c6 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -420,17 +420,17 @@ static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd, bool success,
offset = 0;
for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, count) {
- addr = kmap_atomic(sg_page(sg));
- if (!addr) {
+ addr = sg_map(sg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(addr)) {
ret = TCM_OUT_OF_RESOURCES;
goto out;
}
for (i = 0; i < sg->length; i++)
- *(addr + sg->offset + i) ^= *(buf + offset + i);
+ *(addr + i) ^= *(buf + offset + i);
offset += sg->length;
- kunmap_atomic(addr);
+ sg_unmap(sg, addr, 0, SG_KMAP_ATOMIC);
}
out:
@@ -541,8 +541,8 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes
* Compare against SCSI READ payload against verify payload
*/
for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, i) {
- addr = (unsigned char *)kmap_atomic(sg_page(sg));
- if (!addr) {
+ addr = sg_map(sg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(addr)) {
ret = TCM_OUT_OF_RESOURCES;
goto out;
}
@@ -552,10 +552,10 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes
if (memcmp(addr, buf + offset, len)) {
pr_warn("Detected MISCOMPARE for addr: %p buf: %p\n",
addr, buf + offset);
- kunmap_atomic(addr);
+ sg_unmap(sg, addr, 0, SG_KMAP_ATOMIC);
goto miscompare;
}
- kunmap_atomic(addr);
+ sg_unmap(sg, addr, 0, SG_KMAP_ATOMIC);
offset += len;
compare_len -= len;
@@ -1315,8 +1315,8 @@ sbc_dif_generate(struct se_cmd *cmd)
unsigned int block_size = dev->dev_attrib.block_size;
for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) {
- paddr = kmap_atomic(sg_page(psg)) + psg->offset;
- daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+ paddr = sg_map(psg, 0, SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL);
+ daddr = sg_map(dsg, 0, SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL);
for (j = 0; j < psg->length;
j += sizeof(*sdt)) {
@@ -1325,26 +1325,30 @@ sbc_dif_generate(struct se_cmd *cmd)
if (offset >= dsg->length) {
offset -= dsg->length;
- kunmap_atomic(daddr - dsg->offset);
+ sg_unmap(dsg, daddr, 0, SG_KMAP_ATOMIC);
dsg = sg_next(dsg);
if (!dsg) {
- kunmap_atomic(paddr - psg->offset);
+ sg_unmap(psg, paddr, 0, SG_KMAP_ATOMIC);
return;
}
- daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+ daddr = sg_map(dsg, 0, SG_KMAP_ATOMIC |
+ SG_MAP_MUST_NOT_FAIL);
}
sdt = paddr + j;
avail = min(block_size, dsg->length - offset);
crc = crc_t10dif(daddr + offset, avail);
if (avail < block_size) {
- kunmap_atomic(daddr - dsg->offset);
+ sg_unmap(dsg, daddr, 0, SG_KMAP_ATOMIC);
dsg = sg_next(dsg);
if (!dsg) {
- kunmap_atomic(paddr - psg->offset);
+ sg_unmap(psg, paddr, 0, SG_KMAP_ATOMIC);
return;
}
- daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+
+ daddr = sg_map(dsg, 0, SG_KMAP_ATOMIC |
+ SG_MAP_MUST_NOT_FAIL);
+
offset = block_size - avail;
crc = crc_t10dif_update(crc, daddr, offset);
} else {
@@ -1366,8 +1370,8 @@ sbc_dif_generate(struct se_cmd *cmd)
sector++;
}
- kunmap_atomic(daddr - dsg->offset);
- kunmap_atomic(paddr - psg->offset);
+ sg_unmap(dsg, daddr, 0, SG_KMAP_ATOMIC);
+ sg_unmap(psg, paddr, 0, SG_KMAP_ATOMIC);
}
}
@@ -1412,8 +1416,8 @@ sbc_dif_v1_verify(struct se_cmd *cmd, struct t10_pi_tuple *sdt,
return 0;
}
-void sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
- struct scatterlist *sg, int sg_off)
+int sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
+ struct scatterlist *sg, int sg_off)
{
struct se_device *dev = cmd->se_dev;
struct scatterlist *psg;
@@ -1422,18 +1426,25 @@ void sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
unsigned int offset = sg_off;
if (!sg)
- return;
+ return 0;
left = sectors * dev->prot_length;
for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) {
unsigned int psg_len, copied = 0;
- paddr = kmap_atomic(sg_page(psg)) + psg->offset;
+ paddr = sg_map(psg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(paddr))
+ return TCM_OUT_OF_RESOURCES;
+
psg_len = min(left, psg->length);
while (psg_len) {
len = min(psg_len, sg->length - offset);
- addr = kmap_atomic(sg_page(sg)) + sg->offset + offset;
+ addr = sg_map(sg, offset, SG_KMAP_ATOMIC);
+ if (IS_ERR(addr)) {
+ sg_unmap(psg, paddr, 0, SG_KMAP_ATOMIC);
+ return TCM_OUT_OF_RESOURCES;
+ }
if (read)
memcpy(paddr + copied, addr, len);
@@ -1445,15 +1456,17 @@ void sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
copied += len;
psg_len -= len;
- kunmap_atomic(addr - sg->offset - offset);
+ sg_unmap(sg, addr, offset, SG_KMAP_ATOMIC);
if (offset >= sg->length) {
sg = sg_next(sg);
offset = 0;
}
}
- kunmap_atomic(paddr - psg->offset);
+ sg_unmap(psg, paddr, 0, SG_KMAP_ATOMIC);
}
+
+ return 0;
}
EXPORT_SYMBOL(sbc_dif_copy_prot);
@@ -1472,8 +1485,13 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
unsigned int block_size = dev->dev_attrib.block_size;
for (; psg && sector < start + sectors; psg = sg_next(psg)) {
- paddr = kmap_atomic(sg_page(psg)) + psg->offset;
- daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+ paddr = sg_map(psg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(paddr))
+ goto sg_map_err;
+
+ daddr = sg_map(dsg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(daddr))
+ goto sg_map_err;
for (i = psg_off; i < psg->length &&
sector < start + sectors;
@@ -1483,13 +1501,15 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
if (dsg_off >= dsg->length) {
dsg_off -= dsg->length;
- kunmap_atomic(daddr - dsg->offset);
+ sg_unmap(dsg, daddr, 0, SG_KMAP_ATOMIC);
dsg = sg_next(dsg);
if (!dsg) {
- kunmap_atomic(paddr - psg->offset);
+ sg_unmap(psg, paddr, 0, SG_KMAP_ATOMIC);
return 0;
}
- daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+ daddr = sg_map(dsg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(daddr))
+ goto sg_map_err;
}
sdt = paddr + i;
@@ -1507,13 +1527,16 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
avail = min(block_size, dsg->length - dsg_off);
crc = crc_t10dif(daddr + dsg_off, avail);
if (avail < block_size) {
- kunmap_atomic(daddr - dsg->offset);
+ sg_unmap(dsg, daddr, 0, SG_KMAP_ATOMIC);
dsg = sg_next(dsg);
if (!dsg) {
- kunmap_atomic(paddr - psg->offset);
+ sg_unmap(psg, paddr, 0, SG_KMAP_ATOMIC);
return 0;
}
- daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+ daddr = sg_map(dsg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(daddr))
+ goto sg_map_err;
+
dsg_off = block_size - avail;
crc = crc_t10dif_update(crc, daddr, dsg_off);
} else {
@@ -1522,8 +1545,8 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
rc = sbc_dif_v1_verify(cmd, sdt, crc, sector, ei_lba);
if (rc) {
- kunmap_atomic(daddr - dsg->offset);
- kunmap_atomic(paddr - psg->offset);
+ sg_unmap(dsg, daddr, 0, SG_KMAP_ATOMIC);
+ sg_unmap(psg, paddr, 0, SG_KMAP_ATOMIC);
cmd->bad_sector = sector;
return rc;
}
@@ -1533,10 +1556,16 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
}
psg_off = 0;
- kunmap_atomic(daddr - dsg->offset);
- kunmap_atomic(paddr - psg->offset);
+ sg_unmap(dsg, daddr, 0, SG_KMAP_ATOMIC);
+ sg_unmap(psg, paddr, 0, SG_KMAP_ATOMIC);
}
return 0;
+
+sg_map_err:
+ if (!IS_ERR_OR_NULL(paddr))
+ sg_unmap(psg, paddr, 0, SG_KMAP_ATOMIC);
+
+ return TCM_OUT_OF_RESOURCES;
}
EXPORT_SYMBOL(sbc_dif_verify);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index a0cd56e..345e547 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1506,11 +1506,11 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
unsigned char *buf = NULL;
if (sgl)
- buf = kmap(sg_page(sgl)) + sgl->offset;
+ buf = sg_map(sgl, 0, SG_KMAP);
- if (buf) {
+ if (buf && !IS_ERR(buf)) {
memset(buf, 0, sgl->length);
- kunmap(sg_page(sgl));
+ sg_unmap(sgl, buf, 0, SG_KMAP);
}
}
@@ -2307,8 +2307,14 @@ void *transport_kmap_data_sg(struct se_cmd *cmd)
return NULL;
BUG_ON(!sg);
- if (cmd->t_data_nents == 1)
- return kmap(sg_page(sg)) + sg->offset;
+ if (cmd->t_data_nents == 1) {
+ cmd->t_data_vmap = sg_map(sg, 0, SG_KMAP);
+ if (IS_ERR(cmd->t_data_vmap)) {
+ cmd->t_data_vmap = NULL;
+ return NULL;
+ }
+ return cmd->t_data_vmap;
+ }
/* >1 page. use vmap */
pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL);
@@ -2334,7 +2340,7 @@ void transport_kunmap_data_sg(struct se_cmd *cmd)
if (!cmd->t_data_nents) {
return;
} else if (cmd->t_data_nents == 1) {
- kunmap(sg_page(cmd->t_data_sg));
+ sg_unmap(cmd->t_data_sg, cmd->t_data_vmap, 0, SG_KMAP);
return;
}
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index f615c3b..b55f7e2 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -260,7 +260,7 @@ static inline size_t iov_tail(struct tcmu_dev *udev, struct iovec *iov)
return (size_t)iov->iov_base + iov->iov_len;
}
-static void alloc_and_scatter_data_area(struct tcmu_dev *udev,
+static int alloc_and_scatter_data_area(struct tcmu_dev *udev,
struct scatterlist *data_sg, unsigned int data_nents,
struct iovec **iov, int *iov_cnt, bool copy_data)
{
@@ -272,7 +272,10 @@ static void alloc_and_scatter_data_area(struct tcmu_dev *udev,
for_each_sg(data_sg, sg, data_nents, i) {
int sg_remaining = sg->length;
- from = kmap_atomic(sg_page(sg)) + sg->offset;
+ from = sg_map(sg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(from))
+ return PTR_ERR(from);
+
while (sg_remaining > 0) {
if (block_remaining == 0) {
block = find_first_zero_bit(udev->data_bitmap,
@@ -301,8 +304,10 @@ static void alloc_and_scatter_data_area(struct tcmu_dev *udev,
sg_remaining -= copy_bytes;
block_remaining -= copy_bytes;
}
- kunmap_atomic(from - sg->offset);
+ sg_unmap(sg, from, 0, SG_KMAP_ATOMIC);
}
+
+ return 0;
}
static void free_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd)
@@ -311,8 +316,8 @@ static void free_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd)
DATA_BLOCK_BITS);
}
-static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd,
- bool bidi)
+static int gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd,
+ bool bidi)
{
struct se_cmd *se_cmd = cmd->se_cmd;
int i, block;
@@ -348,7 +353,10 @@ static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd,
for_each_sg(data_sg, sg, data_nents, i) {
int sg_remaining = sg->length;
- to = kmap_atomic(sg_page(sg)) + sg->offset;
+ to = sg_map(sg, 0, SG_KMAP_ATOMIC);
+ if (IS_ERR(to))
+ return PTR_ERR(to);
+
while (sg_remaining > 0) {
if (block_remaining == 0) {
block = find_first_bit(bitmap,
@@ -368,8 +376,10 @@ static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd,
sg_remaining -= copy_bytes;
block_remaining -= copy_bytes;
}
- kunmap_atomic(to - sg->offset);
+ sg_unmap(sg, to, 0, SG_KMAP_ATOMIC);
}
+
+ return 0;
}
static inline size_t spc_bitmap_free(unsigned long *bitmap)
@@ -546,8 +556,12 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
iov_cnt = 0;
copy_to_data_area = (se_cmd->data_direction == DMA_TO_DEVICE
|| se_cmd->se_cmd_flags & SCF_BIDI);
- alloc_and_scatter_data_area(udev, se_cmd->t_data_sg,
- se_cmd->t_data_nents, &iov, &iov_cnt, copy_to_data_area);
+ if (alloc_and_scatter_data_area(udev, se_cmd->t_data_sg,
+ se_cmd->t_data_nents, &iov, &iov_cnt, copy_to_data_area)) {
+ spin_unlock_irq(&udev->cmdr_lock);
+ return TCM_OUT_OF_RESOURCES;
+ }
+
entry->req.iov_cnt = iov_cnt;
entry->req.iov_dif_cnt = 0;
@@ -555,9 +569,12 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
if (se_cmd->se_cmd_flags & SCF_BIDI) {
iov_cnt = 0;
iov++;
- alloc_and_scatter_data_area(udev, se_cmd->t_bidi_data_sg,
+ if (alloc_and_scatter_data_area(udev, se_cmd->t_bidi_data_sg,
se_cmd->t_bidi_data_nents, &iov, &iov_cnt,
- false);
+ false)) {
+ spin_unlock_irq(&udev->cmdr_lock);
+ return TCM_OUT_OF_RESOURCES;
+ }
entry->req.iov_bidi_cnt = iov_cnt;
}
/* cmd's data_bitmap is what changed in process */
@@ -637,10 +654,12 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry *
free_data_area(udev, cmd);
} else if (se_cmd->se_cmd_flags & SCF_BIDI) {
/* Get Data-In buffer before clean up */
- gather_data_area(udev, cmd, true);
+ if (gather_data_area(udev, cmd, true))
+ entry->rsp.scsi_status = SAM_STAT_CHECK_CONDITION;
free_data_area(udev, cmd);
} else if (se_cmd->data_direction == DMA_FROM_DEVICE) {
- gather_data_area(udev, cmd, false);
+ if (gather_data_area(udev, cmd, false))
+ entry->rsp.scsi_status = SAM_STAT_CHECK_CONDITION;
free_data_area(udev, cmd);
} else if (se_cmd->data_direction == DMA_TO_DEVICE) {
free_data_area(udev, cmd);
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h
index 1b0f447..c39ecd9 100644
--- a/include/target/target_core_backend.h
+++ b/include/target/target_core_backend.h
@@ -82,8 +82,8 @@ sector_t sbc_get_write_same_sectors(struct se_cmd *cmd);
void sbc_dif_generate(struct se_cmd *);
sense_reason_t sbc_dif_verify(struct se_cmd *, sector_t, unsigned int,
unsigned int, struct scatterlist *, int);
-void sbc_dif_copy_prot(struct se_cmd *, unsigned int, bool,
- struct scatterlist *, int);
+int sbc_dif_copy_prot(struct se_cmd *, unsigned int, bool,
+ struct scatterlist *, int);
void transport_set_vpd_proto_id(struct t10_vpd *, unsigned char *);
int transport_set_vpd_assoc(struct t10_vpd *, unsigned char *);
int transport_set_vpd_ident_type(struct t10_vpd *, unsigned char *);
--
2.1.4
^ permalink raw reply related
* [PATCH v2 03/21] libiscsi: Make use of new the sg_map helper function
From: Logan Gunthorpe @ 2017-04-25 18:20 UTC (permalink / raw)
To: linux-kernel, linux-crypto, linux-media, dri-devel, intel-gfx,
linux-raid, linux-mmc, linux-nvdimm, linux-scsi, open-iscsi,
megaraidlinux.pdl, sparmaintainer, devel, target-devel, netdev,
linux-rdma, dm-devel
Cc: Jens Axboe, Chris Leech, James E.J. Bottomley, Martin K. Petersen,
Matthew Wilcox, Greg Kroah-Hartman, Sumit Semwal, Lee Duncan,
Ross Zwisler, Dan Williams, Stephen Bates, Logan Gunthorpe,
Christoph Hellwig
In-Reply-To: <1493144468-22493-1-git-send-email-logang@deltatee.com>
Convert the kmap and kmap_atomic uses to the sg_map function. We now
store the flags for the kmap instead of a boolean to indicate
atomicitiy. We use ISCSI_TCP_INTERNAL_ERR error type that was prepared
earlier for this.
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Cc: Lee Duncan <lduncan@suse.com>
Cc: Chris Leech <cleech@redhat.com>
---
drivers/scsi/libiscsi_tcp.c | 32 ++++++++++++++++++++------------
include/scsi/libiscsi_tcp.h | 2 +-
2 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index 63a1d69..a34e25c 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -133,25 +133,23 @@ static void iscsi_tcp_segment_map(struct iscsi_segment *segment, int recv)
if (page_count(sg_page(sg)) >= 1 && !recv)
return;
- if (recv) {
- segment->atomic_mapped = true;
- segment->sg_mapped = kmap_atomic(sg_page(sg));
- } else {
- segment->atomic_mapped = false;
- /* the xmit path can sleep with the page mapped so use kmap */
- segment->sg_mapped = kmap(sg_page(sg));
+ /* the xmit path can sleep with the page mapped so don't use atomic */
+ segment->sg_map_flags = recv ? SG_KMAP_ATOMIC : SG_KMAP;
+ segment->sg_mapped = sg_map(sg, 0, segment->sg_map_flags);
+
+ if (IS_ERR(segment->sg_mapped)) {
+ segment->sg_mapped = NULL;
+ return;
}
- segment->data = segment->sg_mapped + sg->offset + segment->sg_offset;
+ segment->data = segment->sg_mapped + segment->sg_offset;
}
void iscsi_tcp_segment_unmap(struct iscsi_segment *segment)
{
if (segment->sg_mapped) {
- if (segment->atomic_mapped)
- kunmap_atomic(segment->sg_mapped);
- else
- kunmap(sg_page(segment->sg));
+ sg_unmap(segment->sg, segment->sg_mapped, 0,
+ segment->sg_map_flags);
segment->sg_mapped = NULL;
segment->data = NULL;
}
@@ -304,6 +302,9 @@ iscsi_tcp_segment_recv(struct iscsi_tcp_conn *tcp_conn,
break;
}
+ if (segment->data)
+ return -EFAULT;
+
copy = min(len - copied, segment->size - segment->copied);
ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "copying %d\n", copy);
memcpy(segment->data + segment->copied, ptr + copied, copy);
@@ -927,6 +928,13 @@ int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb,
avail);
rc = iscsi_tcp_segment_recv(tcp_conn, segment, ptr, avail);
BUG_ON(rc == 0);
+ if (rc < 0) {
+ ISCSI_DBG_TCP(conn, "memory fault. Consumed %d\n",
+ consumed);
+ *status = ISCSI_TCP_INTERNAL_ERR;
+ goto skb_done;
+ }
+
consumed += rc;
if (segment->total_copied >= segment->total_size) {
diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h
index 90691ad..58c79af 100644
--- a/include/scsi/libiscsi_tcp.h
+++ b/include/scsi/libiscsi_tcp.h
@@ -47,7 +47,7 @@ struct iscsi_segment {
struct scatterlist *sg;
void *sg_mapped;
unsigned int sg_offset;
- bool atomic_mapped;
+ int sg_map_flags;
iscsi_segment_done_fn_t *done;
};
--
2.1.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [PATCH v2 02/21] libiscsi: Add an internal error code
From: Logan Gunthorpe @ 2017-04-25 18:20 UTC (permalink / raw)
To: linux-kernel, linux-crypto, linux-media, dri-devel, intel-gfx,
linux-raid, linux-mmc, linux-nvdimm, linux-scsi, open-iscsi,
megaraidlinux.pdl, sparmaintainer, devel, target-devel, netdev,
linux-rdma, dm-devel
Cc: Jens Axboe, James E.J. Bottomley, Martin K. Petersen,
Matthew Wilcox, Greg Kroah-Hartman, Sumit Semwal, Ross Zwisler,
Dan Williams, Stephen Bates, Logan Gunthorpe, Christoph Hellwig
In-Reply-To: <1493144468-22493-1-git-send-email-logang@deltatee.com>
This is a prep patch to add a new error code to libiscsi. We want to
rework some kmap calls to be able to fail. When we do, we'd like to
use this error code.
This patch simply introduces ISCSI_TCP_INTERNAL_ERR and prints
"Internal Error." when it gets hit.
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
drivers/scsi/cxgbi/libcxgbi.c | 5 +++++
include/scsi/libiscsi_tcp.h | 1 +
2 files changed, 6 insertions(+)
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index bd7d39e..e38d0c1 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -1556,6 +1556,11 @@ static inline int read_pdu_skb(struct iscsi_conn *conn,
*/
iscsi_conn_printk(KERN_ERR, conn, "Invalid pdu or skb.");
return -EFAULT;
+ case ISCSI_TCP_INTERNAL_ERR:
+ pr_info("skb 0x%p, off %u, %d, TCP_INTERNAL_ERR.\n",
+ skb, offset, offloaded);
+ iscsi_conn_printk(KERN_ERR, conn, "Internal error.");
+ return -EFAULT;
case ISCSI_TCP_SEGMENT_DONE:
log_debug(1 << CXGBI_DBG_PDU_RX,
"skb 0x%p, off %u, %d, TCP_SEG_DONE, rc %d.\n",
diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h
index 30520d5..90691ad 100644
--- a/include/scsi/libiscsi_tcp.h
+++ b/include/scsi/libiscsi_tcp.h
@@ -92,6 +92,7 @@ enum {
ISCSI_TCP_SKB_DONE, /* skb is out of data */
ISCSI_TCP_CONN_ERR, /* iscsi layer has fired a conn err */
ISCSI_TCP_SUSPENDED, /* conn is suspended */
+ ISCSI_TCP_INTERNAL_ERR, /* an internal error occurred */
};
extern void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn);
--
2.1.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [PATCH v2 01/21] scatterlist: Introduce sg_map helper functions
From: Logan Gunthorpe @ 2017-04-25 18:20 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-raid-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA,
linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-scsi-u79uwXL29TY76Z2rM5mHXA,
open-iscsi-/JYPxA39Uh5TLH3MbocFFw,
megaraidlinux.pdl-dY08KVG/lbpWk0Htik3J/w,
sparmaintainer-GLv8BlqOqDDQT0dZR+AlfA,
devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
target-devel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
dm-devel-H+wXaHxf7aLQT0dZR+AlfA
Cc: Jens Axboe, James E.J. Bottomley, Martin K. Petersen,
Matthew Wilcox, Greg Kroah-Hartman, Sumit Semwal,
Christoph Hellwig
In-Reply-To: <1493144468-22493-1-git-send-email-logang-OTvnGxWRz7hWk0Htik3J/w@public.gmane.org>
This patch introduces functions which kmap the pages inside an sgl.
These functions replace a common pattern of kmap(sg_page(sg)) that is
used in more than 50 places within the kernel.
The motivation for this work is to eventually safely support sgls that
contain io memory. In order for that to work, any access to the contents
of an iomem SGL will need to be done with iomemcpy or hit some warning.
(The exact details of how this will work have yet to be worked out.)
Having all the kmaps in one place is just a first step in that
direction. Additionally, seeing this helps cut down the users of sg_page,
it should make any effort to go to struct-page-less DMAs a little
easier (should that idea ever swing back into favour again).
A flags option is added to select between a regular or atomic mapping so
these functions can replace kmap(sg_page or kmap_atomic(sg_page.
Future work may expand this to have flags for using page_address or
vmap. We include a flag to require the function not to fail to
support legacy code that has no easy error path. Much further in the
future, there may be a flag to allocate memory and copy the data
from/to iomem.
We also add the semantic that sg_map can fail to create a mapping,
despite the fact that the current code this is replacing is assumed to
never fail and the current version of these functions cannot fail. This
is to support iomem which may either have to fail to create the mapping or
allocate memory as a bounce buffer which itself can fail.
Also, in terms of cleanup, a few of the existing kmap(sg_page) users
play things a bit loose in terms of whether they apply sg->offset
so using these helper functions should help avoid such issues.
Signed-off-by: Logan Gunthorpe <logang-OTvnGxWRz7hWk0Htik3J/w@public.gmane.org>
---
include/linux/scatterlist.h | 85 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index cb3c8fe..fad170b 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -5,6 +5,7 @@
#include <linux/types.h>
#include <linux/bug.h>
#include <linux/mm.h>
+#include <linux/highmem.h>
#include <asm/io.h>
struct scatterlist {
@@ -126,6 +127,90 @@ static inline struct page *sg_page(struct scatterlist *sg)
return (struct page *)((sg)->page_link & ~0x3);
}
+#define SG_KMAP (1 << 0) /* create a mapping with kmap */
+#define SG_KMAP_ATOMIC (1 << 1) /* create a mapping with kmap_atomic */
+#define SG_MAP_MUST_NOT_FAIL (1 << 2) /* indicate sg_map should not fail */
+
+/**
+ * sg_map - kmap a page inside an sgl
+ * @sg: SG entry
+ * @offset: Offset into entry
+ * @flags: Flags for creating the mapping
+ *
+ * Description:
+ * Use this function to map a page in the scatterlist at the specified
+ * offset. sg->offset is already added for you. Note: the semantics of
+ * this function are that it may fail. Thus, its output should be checked
+ * with IS_ERR and PTR_ERR. Otherwise, a pointer to the specified offset
+ * in the mapped page is returned.
+ *
+ * Flags can be any of:
+ * * SG_KMAP - Use kmap to create the mapping
+ * * SG_KMAP_ATOMIC - Use kmap_atomic to map the page atommically.
+ * Thus, the rules of that function apply: the
+ * cpu may not sleep until it is unmaped.
+ * * SG_MAP_MUST_NOT_FAIL - Indicate that sg_map must not fail.
+ * If it does, it will issue a BUG_ON instead.
+ * This is intended for legacy code only, it
+ * is not to be used in new code.
+ *
+ * Also, consider carefully whether this function is appropriate. It is
+ * largely not recommended for new code and if the sgl came from another
+ * subsystem and you don't know what kind of memory might be in the list
+ * then you definitely should not call it. Non-mappable memory may be in
+ * the sgl and thus this function may fail unexpectedly. Consider using
+ * sg_copy_to_buffer instead.
+ **/
+static inline void *sg_map(struct scatterlist *sg, size_t offset, int flags)
+{
+ struct page *pg;
+ unsigned int pg_off;
+ void *ret;
+
+ offset += sg->offset;
+ pg = nth_page(sg_page(sg), offset >> PAGE_SHIFT);
+ pg_off = offset_in_page(offset);
+
+ if (flags & SG_KMAP_ATOMIC)
+ ret = kmap_atomic(pg) + pg_off;
+ else if (flags & SG_KMAP)
+ ret = kmap(pg) + pg_off;
+ else
+ ret = ERR_PTR(-EINVAL);
+
+ /*
+ * In theory, this can't happen yet. Once we start adding
+ * unmapable memory, it also shouldn't happen unless developers
+ * start putting unmappable struct pages in sgls and passing
+ * it to code that doesn't support it.
+ */
+ BUG_ON(flags & SG_MAP_MUST_NOT_FAIL && IS_ERR(ret));
+
+ return ret;
+}
+
+/**
+ * sg_unmap - unmap a page that was mapped with sg_map_offset
+ * @sg: SG entry
+ * @addr: address returned by sg_map_offset
+ * @offset: Offset into entry (same as specified for sg_map)
+ * @flags: Flags, which are the same specified for sg_map
+ *
+ * Description:
+ * Unmap the page that was mapped with sg_map_offset
+ **/
+static inline void sg_unmap(struct scatterlist *sg, void *addr,
+ size_t offset, int flags)
+{
+ struct page *pg = nth_page(sg_page(sg), offset >> PAGE_SHIFT);
+ unsigned int pg_off = offset_in_page(offset);
+
+ if (flags & SG_KMAP_ATOMIC)
+ kunmap_atomic(addr - sg->offset - pg_off);
+ else if (flags & SG_KMAP)
+ kunmap(pg);
+}
+
/**
* sg_set_buf - Set sg entry to point at given data
* @sg: SG entry
--
2.1.4
^ permalink raw reply related
* [PATCH v2 00/21] Introduce common scatterlist map function
From: Logan Gunthorpe @ 2017-04-25 18:20 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-raid-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA,
linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-scsi-u79uwXL29TY76Z2rM5mHXA,
open-iscsi-/JYPxA39Uh5TLH3MbocFFw,
megaraidlinux.pdl-dY08KVG/lbpWk0Htik3J/w,
sparmaintainer-GLv8BlqOqDDQT0dZR+AlfA,
devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
target-devel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
dm-devel-H+wXaHxf7aLQT0dZR+AlfA
Cc: Jens Axboe, James E.J. Bottomley, Martin K. Petersen,
Matthew Wilcox, Greg Kroah-Hartman, Sumit Semwal,
Christoph Hellwig
Changes since v1:
* Rebased onto next-20170424
* Removed the _offset version of these functions per Christoph's
suggestion
* Added an SG_MAP_MUST_NOT_FAIL flag which will BUG_ON in future cases
that can't gracefully fail. This removes a bunch of the noise added
in v1 to a couple of the drivers. (Per David Laight's suggestion)
This flag is only meant for old code
* Split the libiscsi patch into two (per Christoph's suggestion)
the prep patch (patch 2 in this series) has already been
sent separately
* Fixed a locking mistake in the target patch (pointed out by a bot)
* Dropped the nvmet patch and handled it with a different patch
that has been sent separately
* Dropped the chcr patch as they have already removed the code that
needed to be changed
I'm still hoping to only get Patch 1 in the series merged. (Any
volunteers?) I'm willing to chase down the maintainers for the remaining
patches separately after the first patch is in.
The patchset is based on next-20170424 and can be found in the sg_map_v2
branch from this git tree:
https://github.com/sbates130272/linux-p2pmem.git
--
Hi Everyone,
As part of my effort to enable P2P DMA transactions with PCI cards,
we've identified the need to be able to safely put IO memory into
scatterlists (and eventually other spots). This probably involves a
conversion from struct page to pfn_t but that migration is a ways off
and those decisions are yet to be made.
As an initial step in that direction, I've started cleaning up some of the
scatterlist code by trying to carve out a better defined layer between it
and it's users. The longer term goal would be to remove sg_page or replace
it with something that can potentially fail.
This patchset is the first step in that effort. I've introduced
a common function to map scatterlist memory and converted all the common
kmap(sg_page()) cases. This removes about 66 sg_page calls (of ~331).
Seeing this is a fairly large cleanup set that touches a wide swath of
the kernel I have limited the people I've sent this to. I'd suggest we look
toward merging the first patch and then I can send the individual subsystem
patches on to their respective maintainers and get them merged
independantly. (This is to avoid the conflicts I created with my last
cleanup set... Sorry) Though, I'm certainly open to other suggestions to get
it merged.
Logan Gunthorpe (21):
scatterlist: Introduce sg_map helper functions
libiscsi: Add an internal error code
libiscsi: Make use of new the sg_map helper function
target: Make use of the new sg_map function at 16 call sites
drm/i915: Make use of the new sg_map helper function
crypto: hifn_795x: Make use of the new sg_map helper function
crypto: shash, caam: Make use of the new sg_map helper function
dm-crypt: Make use of the new sg_map helper in 4 call sites
staging: unisys: visorbus: Make use of the new sg_map helper function
RDS: Make use of the new sg_map helper function
scsi: ipr, pmcraid, isci: Make use of the new sg_map helper
scsi: hisi_sas, mvsas, gdth: Make use of the new sg_map helper
function
scsi: arcmsr, ips, megaraid: Make use of the new sg_map helper
function
scsi: libfc, csiostor: Change to sg_copy_buffer in two drivers
xen-blkfront: Make use of the new sg_map helper function
mmc: sdhci: Make use of the new sg_map helper function
mmc: spi: Make use of the new sg_map helper function
mmc: tmio: Make use of the new sg_map helper function
mmc: sdricoh_cs: Make use of the new sg_map helper function
mmc: tifm_sd: Make use of the new sg_map helper function
memstick: Make use of the new sg_map helper function
crypto/shash.c | 9 ++-
drivers/block/xen-blkfront.c | 20 ++---
drivers/crypto/caam/caamalg.c | 8 +-
drivers/crypto/hifn_795x.c | 32 +++++---
drivers/gpu/drm/i915/i915_gem.c | 27 ++++---
drivers/md/dm-crypt.c | 39 ++++++---
drivers/memstick/host/jmb38x_ms.c | 11 +--
drivers/memstick/host/tifm_ms.c | 11 +--
drivers/mmc/host/mmc_spi.c | 26 ++++--
drivers/mmc/host/sdhci.c | 14 ++--
drivers/mmc/host/sdricoh_cs.c | 14 ++--
drivers/mmc/host/tifm_sd.c | 50 +++++++-----
drivers/mmc/host/tmio_mmc.h | 7 +-
drivers/mmc/host/tmio_mmc_pio.c | 12 +++
drivers/scsi/arcmsr/arcmsr_hba.c | 16 +++-
drivers/scsi/csiostor/csio_scsi.c | 54 +------------
drivers/scsi/cxgbi/libcxgbi.c | 5 ++
drivers/scsi/gdth.c | 9 ++-
drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 14 ++--
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 13 ++-
drivers/scsi/ipr.c | 27 ++++---
drivers/scsi/ips.c | 8 +-
drivers/scsi/isci/request.c | 42 ++++++----
drivers/scsi/libfc/fc_libfc.c | 49 +++--------
drivers/scsi/libiscsi_tcp.c | 32 +++++---
drivers/scsi/megaraid.c | 9 ++-
drivers/scsi/mvsas/mv_sas.c | 10 +--
drivers/scsi/pmcraid.c | 19 +++--
drivers/staging/unisys/visorhba/visorhba_main.c | 12 +--
drivers/target/iscsi/iscsi_target.c | 29 ++++---
drivers/target/target_core_rd.c | 3 +-
drivers/target/target_core_sbc.c | 103 +++++++++++++++---------
drivers/target/target_core_transport.c | 18 +++--
drivers/target/target_core_user.c | 45 ++++++++---
include/linux/scatterlist.h | 85 +++++++++++++++++++
include/scsi/libiscsi_tcp.h | 3 +-
include/target/target_core_backend.h | 4 +-
net/rds/ib_recv.c | 8 +-
38 files changed, 553 insertions(+), 344 deletions(-)
--
2.1.4
^ permalink raw reply
* Re: [PATCH] ipv6: ensure message length for raw socket is at least sizeof(ipv6hdr)
From: Eric Dumazet @ 2017-04-25 18:10 UTC (permalink / raw)
To: David Miller
Cc: Alexander Potapenko, Dmitry Vyukov, Kostya Serebryany,
Alexey Kuznetsov, LKML, netdev
In-Reply-To: <20170425.135543.1706004185593424024.davem@davemloft.net>
On Tue, Apr 25, 2017 at 10:55 AM, David Miller <davem@davemloft.net> wrote:
> From: Alexander Potapenko <glider@google.com>
> Date: Tue, 25 Apr 2017 15:18:27 +0200
>
>> rawv6_send_hdrinc() expects that the buffer copied from the userspace
>> contains the IPv6 header, so if too few bytes are copied parts of the
>> header may remain uninitialized.
>>
>> This bug has been detected with KMSAN.
>>
>> Signed-off-by: Alexander Potapenko <glider@google.com>
>
> Hmmm, ipv4 seems to lack this check as well.
>
> I think we need to be careful here and fully understand why KMSAN doesn't
> seem to be triggering in the ipv4 case but for ipv6 it is before I apply
> this.
This could be a bug in nf_ct_frag6_gather() missing one pskb_may_pull()
^ permalink raw reply
* Re: [PATCH] net/packet: check length in getsockopt() called with PACKET_HDRLEN
From: David Miller @ 2017-04-25 18:06 UTC (permalink / raw)
To: glider; +Cc: dvyukov, kcc, edumazet, kuznet, linux-kernel, netdev
In-Reply-To: <20170425165146.25075-1-glider@google.com>
From: Alexander Potapenko <glider@google.com>
Date: Tue, 25 Apr 2017 18:51:46 +0200
> In the case getsockopt() is called with PACKET_HDRLEN and optlen < 4
> |val| remains uninitialized and the syscall may behave differently
> depending on its value, and even copy garbage to userspace on certain
> architectures. To fix this we now return -EINVAL if optlen is too small.
>
> This bug has been detected with KMSAN.
>
> Signed-off-by: Alexander Potapenko <glider@google.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH v4 net] net: ipv6: regenerate host route if moved to gc list
From: David Miller @ 2017-04-25 18:05 UTC (permalink / raw)
To: dsa; +Cc: netdev, dvyukov, andreyknvl, mmanning, kafai, eric.dumazet
In-Reply-To: <1493137049-16465-1-git-send-email-dsa@cumulusnetworks.com>
From: David Ahern <dsa@cumulusnetworks.com>
Date: Tue, 25 Apr 2017 09:17:29 -0700
> Taking down the loopback device wreaks havoc on IPv6 routing. By
> extension, taking down a VRF device wreaks havoc on its table.
>
> Dmitry and Andrey both reported heap out-of-bounds reports in the IPv6
> FIB code while running syzkaller fuzzer. The root cause is a dead dst
> that is on the garbage list gets reinserted into the IPv6 FIB. While on
> the gc (or perhaps when it gets added to the gc list) the dst->next is
> set to an IPv4 dst. A subsequent walk of the ipv6 tables causes the
> out-of-bounds access.
>
> Andrey's reproducer was the key to getting to the bottom of this.
>
> With IPv6, host routes for an address have the dst->dev set to the
> loopback device. When the 'lo' device is taken down, rt6_ifdown initiates
> a walk of the fib evicting routes with the 'lo' device which means all
> host routes are removed. That process moves the dst which is attached to
> an inet6_ifaddr to the gc list and marks it as dead.
>
> The recent change to keep global IPv6 addresses added a new function,
> fixup_permanent_addr, that is called on admin up. That function restarts
> dad for an inet6_ifaddr and when it completes the host route attached
> to it is inserted into the fib. Since the route was marked dead and
> moved to the gc list, re-inserting the route causes the reported
> out-of-bounds accesses. If the device with the address is taken down
> or the address is removed, the WARN_ON in fib6_del is triggered.
>
> All of those faults are fixed by regenerating the host route if the
> existing one has been moved to the gc list, something that can be
> determined by checking if the rt6i_ref counter is 0.
>
> Fixes: f1705ec197e7 ("net: ipv6: Make address flushing on ifdown optional")
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Reported-by: Andrey Konovalov <andreyknvl@google.com>
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Applied and queued up for -stable, thanks David!
^ permalink raw reply
* Re: [PATCHv2 net] bridge: move bridge multicast cleanup to ndo_uninit
From: David Miller @ 2017-04-25 18:02 UTC (permalink / raw)
To: lucien.xin; +Cc: netdev, nikolay, stephen
In-Reply-To: <6e156e72cb1a5e279da8ac53bdb601eee5d654fe.1493132317.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Tue, 25 Apr 2017 22:58:37 +0800
> During removing a bridge device, if the bridge is still up, a new mdb entry
> still can be added in br_multicast_add_group() after all mdb entries are
> removed in br_multicast_dev_del(). Like the path:
>
> mld_ifc_timer_expire ->
> mld_sendpack -> ...
> br_multicast_rcv ->
> br_multicast_add_group
>
> The new mp's timer will be set up. If the timer expires after the bridge
> is freed, it may cause use-after-free panic in br_multicast_group_expired.
>
> BUG: unable to handle kernel NULL pointer dereference at 0000000000000048
> IP: [<ffffffffa07ed2c8>] br_multicast_group_expired+0x28/0xb0 [bridge]
> Call Trace:
> <IRQ>
> [<ffffffff81094536>] call_timer_fn+0x36/0x110
> [<ffffffffa07ed2a0>] ? br_mdb_free+0x30/0x30 [bridge]
> [<ffffffff81096967>] run_timer_softirq+0x237/0x340
> [<ffffffff8108dcbf>] __do_softirq+0xef/0x280
> [<ffffffff8169889c>] call_softirq+0x1c/0x30
> [<ffffffff8102c275>] do_softirq+0x65/0xa0
> [<ffffffff8108e055>] irq_exit+0x115/0x120
> [<ffffffff81699515>] smp_apic_timer_interrupt+0x45/0x60
> [<ffffffff81697a5d>] apic_timer_interrupt+0x6d/0x80
>
> Nikolay also found it would cause a memory leak - the mdb hash is
> reallocated and not freed due to the mdb rehash.
>
> unreferenced object 0xffff8800540ba800 (size 2048):
> backtrace:
> [<ffffffff816e2287>] kmemleak_alloc+0x67/0xc0
> [<ffffffff81260bea>] __kmalloc+0x1ba/0x3e0
> [<ffffffffa05c60ee>] br_mdb_rehash+0x5e/0x340 [bridge]
> [<ffffffffa05c74af>] br_multicast_new_group+0x43f/0x6e0 [bridge]
> [<ffffffffa05c7aa3>] br_multicast_add_group+0x203/0x260 [bridge]
> [<ffffffffa05ca4b5>] br_multicast_rcv+0x945/0x11d0 [bridge]
> [<ffffffffa05b6b10>] br_dev_xmit+0x180/0x470 [bridge]
> [<ffffffff815c781b>] dev_hard_start_xmit+0xbb/0x3d0
> [<ffffffff815c8743>] __dev_queue_xmit+0xb13/0xc10
> [<ffffffff815c8850>] dev_queue_xmit+0x10/0x20
> [<ffffffffa02f8d7a>] ip6_finish_output2+0x5ca/0xac0 [ipv6]
> [<ffffffffa02fbfc6>] ip6_finish_output+0x126/0x2c0 [ipv6]
> [<ffffffffa02fc245>] ip6_output+0xe5/0x390 [ipv6]
> [<ffffffffa032b92c>] NF_HOOK.constprop.44+0x6c/0x240 [ipv6]
> [<ffffffffa032bd16>] mld_sendpack+0x216/0x3e0 [ipv6]
> [<ffffffffa032d5eb>] mld_ifc_timer_expire+0x18b/0x2b0 [ipv6]
>
> This could happen when ip link remove a bridge or destroy a netns with a
> bridge device inside.
>
> With Nikolay's suggestion, this patch is to clean up bridge multicast in
> ndo_uninit after bridge dev is shutdown, instead of br_dev_delete, so
> that netif_running check in br_multicast_add_group can avoid this issue.
>
> v1->v2:
> - fix this issue by moving br_multicast_dev_del to ndo_uninit, instead
> of calling dev_close in br_dev_delete.
>
> Reported-by: Jianwen Ji <jiji@redhat.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [PATCH net] ipv6: fix source routing
From: David Miller @ 2017-04-25 17:59 UTC (permalink / raw)
To: sd; +Cc: netdev, hannes, david.lebrun
In-Reply-To: <1d451d4d6c04c259280dee65caeabf3e00e0eb94.1493128459.git.sd@queasysnail.net>
From: Sabrina Dubroca <sd@queasysnail.net>
Date: Tue, 25 Apr 2017 15:56:50 +0200
> Commit a149e7c7ce81 ("ipv6: sr: add support for SRH injection through
> setsockopt") introduced handling of IPV6_SRCRT_TYPE_4, but at the same
> time restricted it to only IPV6_SRCRT_TYPE_0 and
> IPV6_SRCRT_TYPE_4. Previously, ipv6_push_exthdr() and fl6_update_dst()
> would also handle other values (ie STRICT and TYPE_2).
>
> Restore previous source routing behavior, by handling IPV6_SRCRT_STRICT
> and IPV6_SRCRT_TYPE_2 the same way as IPV6_SRCRT_TYPE_0 in
> ipv6_push_exthdr() and fl6_update_dst().
>
> Fixes: a149e7c7ce81 ("ipv6: sr: add support for SRH injection through setsockopt")
> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
> Reviewed-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] ipv6: ensure message length for raw socket is at least sizeof(ipv6hdr)
From: David Miller @ 2017-04-25 17:55 UTC (permalink / raw)
To: glider; +Cc: dvyukov, kcc, edumazet, kuznet, linux-kernel, netdev
In-Reply-To: <20170425131827.66498-1-glider@google.com>
From: Alexander Potapenko <glider@google.com>
Date: Tue, 25 Apr 2017 15:18:27 +0200
> rawv6_send_hdrinc() expects that the buffer copied from the userspace
> contains the IPv6 header, so if too few bytes are copied parts of the
> header may remain uninitialized.
>
> This bug has been detected with KMSAN.
>
> Signed-off-by: Alexander Potapenko <glider@google.com>
Hmmm, ipv4 seems to lack this check as well.
I think we need to be careful here and fully understand why KMSAN doesn't
seem to be triggering in the ipv4 case but for ipv6 it is before I apply
this.
Thanks.
^ permalink raw reply
* Re: [PATCH net-next 10/10] tcp: switch rcv_rtt_est and rcvq_space to high resolution timestamps
From: Neal Cardwell @ 2017-04-25 17:54 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, netdev, Soheil Hassas Yeganeh, Eric Dumazet
In-Reply-To: <20170425171541.3417-11-edumazet@google.com>
On Tue, Apr 25, 2017 at 1:15 PM, Eric Dumazet <edumazet@google.com> wrote:
> Some devices or distributions use HZ=100 or HZ=250
>
> TCP receive buffer autotuning has poor behavior caused by this choice.
> Since autotuning happens after 4 ms or 10 ms, short distance flows
> get their receive buffer tuned to a very high value, but after an initial
> period where it was frozen to (too small) initial value.
>
> With tp->tcp_mstamp introduction, we can switch to high resolution
> timestamps almost for free (at the expense of 8 additional bytes per
> TCP structure)
>
> Note that some TCP stacks use usec TCP timestamps where this
> patch makes even more sense : Many TCP flows have < 500 usec RTT.
> Hopefully this finer TS option can be standardized soon.
>
> Tested:
> HZ=100 kernel
> ./netperf -H lpaa24 -t TCP_RR -l 1000 -- -r 10000,10000 &
>
> Peer without patch :
> lpaa24:~# ss -tmi dst lpaa23
> ...
> skmem:(r0,rb8388608,...)
> rcv_rtt:10 rcv_space:3210000 minrtt:0.017
>
> Peer with the patch :
> lpaa23:~# ss -tmi dst lpaa24
> ...
> skmem:(r0,rb428800,...)
> rcv_rtt:0.069 rcv_space:30000 minrtt:0.017
>
> We can see saner RCVBUF, and more precise rcv_rtt information.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
neal
^ permalink raw reply
* Re: [Intel-wired-lan] [PATCH 1/2] e1000e: Don't return uninitialized stats
From: Benjamin Poirier @ 2017-04-25 17:54 UTC (permalink / raw)
To: Jeff Kirsher
Cc: Brown, Aaron F, Neftin, Sasha, David S Miller, stephen,
netdev@vger.kernel.org, intel-wired-lan@lists.osuosl.org,
Stefan Priebe
In-Reply-To: <1493111272.68612.2.camel@intel.com>
[-- Attachment #1: Type: text/plain, Size: 2874 bytes --]
On 2017/04/25 02:07, Jeff Kirsher wrote:
[...]
> > >
> > > I don't see any memset in e1000e_get_stats64(). What kernel version
> > > are
> > > you looking at?
> >
> > The call to memset was removed from the upstream kernel with:
> > -------------------------------------------------------------------
> > -----------------
> > commit 5944701df90d9577658e2354cc27c4ceaeca30fe
> > Author: stephen hemminger <stephen@networkplumber.org>
> > Date: Fri Jan 6 19:12:53 2017 -0800
> >
> > net: remove useless memset's in drivers get_stats64
> >
> > In dev_get_stats() the statistic structure storage has already
> > been
> > zeroed. Therefore network drivers do not need to call memset()
> > again.
> > ...
> > < changes to other drivers snipped out >
> > ...
> > diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c
> > b/drivers/net/ethernet/int
> > index 723025b..79651eb 100644
> > --- a/drivers/net/ethernet/intel/e1000e/netdev.c
> > +++ b/drivers/net/ethernet/intel/e1000e/netdev.c
> > @@ -5925,7 +5925,6 @@ void e1000e_get_stats64(struct net_device
> > *netdev,
> > {
> > struct e1000_adapter *adapter = netdev_priv(netdev);
> >
> > - memset(stats, 0, sizeof(struct rtnl_link_stats64));
> > spin_lock(&adapter->stats64_lock);
> > e1000e_update_stats(adapter);
> > /* Fill out the OS statistics structure */
> > -------------------------------------------------------------------
> > -----------------
> >
> > This also is where the bad counters start to show up for e1000e for
> > my test systems. From this driver on I see (very) large values for
> > tx_dropped, rx_over_errors and tx_fifo_errors on driver load (even
> > before bringing the interface up. It seems the memset is not so
> > useless for this driver after all. Would simply reverting the e1000e
> > portion of this patch resolve the issue?
>
> Looks like Aaron beat me to the punch on pointing out that we had this
> very code in there before. It appears that Stephen's
> assertion/assumption was incorrect about the stats structure being
> zero'd out, which is why we are seeing the issue.
>
> I have no issue reverting Stephen's earlier patch, or do we want to
> pursue why the stats structure is not zero'd out and resolve that
> instead. Either way, just want to make sure we are all on the same
> page as to the right solution so that we do not end up repeating this
> in the future.
If you revert the e1000e part of 5944701df90d ("net: remove useless
memset's in drivers get_stats64", v4.11-rc1) it will fix the issue with
ethtool but memset will be done twice for code paths that call
dev_get_stats() (sysfs, rtnl, ...). Not a big deal but this is not a
problem in the approach I initially suggested. Alternatively, we could
put a memset in e1000_get_ethtool_stats().
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH net-next 09/10] tcp: remove ack_time from struct tcp_sacktag_state
From: Neal Cardwell @ 2017-04-25 17:53 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, netdev, Soheil Hassas Yeganeh, Eric Dumazet
In-Reply-To: <20170425171541.3417-10-edumazet@google.com>
On Tue, Apr 25, 2017 at 1:15 PM, Eric Dumazet <edumazet@google.com> wrote:
> It is no longer needed, everything uses tp->tcp_mstamp instead.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
neal
^ permalink raw reply
* Re: [PATCH net-next 08/10] tcp: use tp->tcp_mstamp in tcp_clean_rtx_queue()
From: Neal Cardwell @ 2017-04-25 17:53 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, netdev, Soheil Hassas Yeganeh, Eric Dumazet
In-Reply-To: <20170425171541.3417-9-edumazet@google.com>
On Tue, Apr 25, 2017 at 1:15 PM, Eric Dumazet <edumazet@google.com> wrote:
> Following patch will remove ack_time from struct tcp_sacktag_state
>
> Same info is now found in tp->tcp_mstamp
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
neal
^ permalink raw reply
* Re: [PATCH net-next 07/10] tcp: do not pass timestamp to tcp_rack_advance()
From: Neal Cardwell @ 2017-04-25 17:53 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, netdev, Soheil Hassas Yeganeh, Eric Dumazet
In-Reply-To: <20170425171541.3417-8-edumazet@google.com>
On Tue, Apr 25, 2017 at 1:15 PM, Eric Dumazet <edumazet@google.com> wrote:
> No longer needed, since tp->tcp_mstamp holds the information.
>
> This is needed to remove sack_state.ack_time in a following patch.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
neal
^ permalink raw reply
* Re: [PATCH net-next 06/10] tcp: do not pass timestamp to tcp_rate_gen()
From: Neal Cardwell @ 2017-04-25 17:53 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, netdev, Soheil Hassas Yeganeh, Eric Dumazet
In-Reply-To: <20170425171541.3417-7-edumazet@google.com>
On Tue, Apr 25, 2017 at 1:15 PM, Eric Dumazet <edumazet@google.com> wrote:
> No longer needed, since tp->tcp_mstamp holds the information.
>
> This is needed to remove sack_state.ack_time in a following patch.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
neal
^ permalink raw reply
* Re: [PATCH net-next 05/10] tcp: do not pass timestamp to tcp_fastretrans_alert()
From: Neal Cardwell @ 2017-04-25 17:52 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, netdev, Soheil Hassas Yeganeh, Eric Dumazet
In-Reply-To: <20170425171541.3417-6-edumazet@google.com>
On Tue, Apr 25, 2017 at 1:15 PM, Eric Dumazet <edumazet@google.com> wrote:
> Not used anymore now tp->tcp_mstamp holds the information.
>
> This is needed to remove sack_state.ack_time in a following patch.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
neal
^ permalink raw reply
* Re: [PATCH net-next 04/10] tcp: do not pass timestamp to tcp_rack_identify_loss()
From: Neal Cardwell @ 2017-04-25 17:52 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, netdev, Soheil Hassas Yeganeh, Eric Dumazet
In-Reply-To: <20170425171541.3417-5-edumazet@google.com>
On Tue, Apr 25, 2017 at 1:15 PM, Eric Dumazet <edumazet@google.com> wrote:
> Not used anymore now tp->tcp_mstamp holds the information.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
neal
^ permalink raw reply
* Re: [PATCH net-next 03/10] tcp: do not pass timestamp to tcp_rack_mark_lost()
From: Neal Cardwell @ 2017-04-25 17:51 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, netdev, Soheil Hassas Yeganeh, Eric Dumazet
In-Reply-To: <20170425171541.3417-4-edumazet@google.com>
On Tue, Apr 25, 2017 at 1:15 PM, Eric Dumazet <edumazet@google.com> wrote:
> This is no longer used, since tcp_rack_detect_loss() takes
> the timestamp from tp->tcp_mstamp
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
neal
^ permalink raw reply
* Re: [PATCH net-next 02/10] tcp: do not pass timestamp to tcp_rack_detect_loss()
From: Neal Cardwell @ 2017-04-25 17:51 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, netdev, Soheil Hassas Yeganeh, Eric Dumazet
In-Reply-To: <20170425171541.3417-3-edumazet@google.com>
On Tue, Apr 25, 2017 at 1:15 PM, Eric Dumazet <edumazet@google.com> wrote:
> We can use tp->tcp_mstamp as it contains a recent timestamp.
>
> This removes a call to skb_mstamp_get() from tcp_rack_reo_timeout()
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
neal
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox