From d3972843ae3ba829f821bd135d5ba97d4b0356f3 Mon Sep 17 00:00:00 2001 From: Prakash Surya Date: Fri, 17 Aug 2012 09:11:32 -0700 Subject: [PATCH] LU-1714 lnet: Properly initialize sg_magic value When the CONFIG_DEBUG_SG flag is enabled in the kernel, we must ensure the sg_magic field is properly initialized. Otherwise, internal kernel assertions will fail when trying to verify this field. As a result, certain calls to sg_* function had to be changed or inserted to ensure the sg_init_table function would be called, initializing the magic value. Also, we need to ensure this value isn't zeroed out in the kiblnd_setup_rd_kiov function. Signed-off-by: Prakash Surya Signed-off-by: Alexander Boyko Reviewed-by: Alexander Zarochentsev Reviewed-by: Andrew Perepechko Change-Id: I5b6b265a4a8dd37408bb78decd79ed54e0f9251b Reviewed-on: http://review.whamcloud.com/3709 Tested-by: Hudson Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Oleg Drokin --- libcfs/autoconf/lustre-libcfs.m4 | 20 +++++++++++++++++++- libcfs/include/libcfs/linux/libcfs.h | 9 +++++++++ libcfs/libcfs/linux/linux-crypto.c | 11 ++++++----- lnet/klnds/o2iblnd/o2iblnd.c | 2 ++ lnet/klnds/o2iblnd/o2iblnd_cb.c | 1 - 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4 index 62ec024..389e4de 100644 --- a/libcfs/autoconf/lustre-libcfs.m4 +++ b/libcfs/autoconf/lustre-libcfs.m4 @@ -346,7 +346,24 @@ LB_LINUX_TRY_COMPILE([ ]) ]) -# 2.6.24 +# 2.6.24-rc1 sg_init_table +AC_DEFUN([LIBCFS_SCATTERLIST_INITTABLE], +[AC_MSG_CHECKING([for sg_init_table]) +LB_LINUX_TRY_COMPILE([ + #include + #include +],[ + sg_init_table(NULL,0); +],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SCATTERLIST_INITTABLE, 1, + [scatterlist has sg_init_table]) +],[ + AC_MSG_RESULT(NO) +]) +]) + +# 2.6.24 AC_DEFUN([LIBCFS_NETWORK_NAMESPACE], [AC_MSG_CHECKING([for network stack has namespaces]) LB_LINUX_TRY_COMPILE([ @@ -765,6 +782,7 @@ LC_REGISTER_SHRINKER # 2.6.24 LIBCFS_SYSCTL_UNNUMBERED LIBCFS_SCATTERLIST_SETPAGE +LIBCFS_SCATTERLIST_INITTABLE LIBCFS_NETWORK_NAMESPACE LIBCFS_FUNC_DUMP_TRACE # 2.6.26 diff --git a/libcfs/include/libcfs/linux/libcfs.h b/libcfs/include/libcfs/linux/libcfs.h index 3635a7f..f8453ce 100644 --- a/libcfs/include/libcfs/linux/libcfs.h +++ b/libcfs/include/libcfs/linux/libcfs.h @@ -164,4 +164,13 @@ typedef long long_ptr_t; #endif /* HAVE_STRUCT_CRED */ +#ifndef HAVE_SCATTERLIST_INITTABLE +#define sg_init_table(sg, nents) memset(sg, 0, sizeof(*(sg))*(nents)) +#endif + +#ifndef HAVE_SCATTERLIST_SETPAGE +#define sg_set_page(sg, p, len, off) \ + sg_set_buf(sg, page_address(p) + ((off) & ~CFS_PAGE_MASK), len) +#endif + #endif /* _LINUX_LIBCFS_H */ diff --git a/libcfs/libcfs/linux/linux-crypto.c b/libcfs/libcfs/linux/linux-crypto.c index 002b241..aaffa61 100644 --- a/libcfs/libcfs/linux/linux-crypto.c +++ b/libcfs/libcfs/linux/linux-crypto.c @@ -167,7 +167,7 @@ int cfs_crypto_hash_digest(unsigned char alg_id, unsigned char *key, unsigned int key_len, unsigned char *hash, unsigned int *hash_len) { - struct scatterlist sl = {0}; + struct scatterlist sl; struct hash_desc hdesc; int err; const struct cfs_crypto_hash_type *type; @@ -184,7 +184,7 @@ int cfs_crypto_hash_digest(unsigned char alg_id, crypto_free_hash(hdesc.tfm); return -ENOSPC; } - sg_set_buf(&sl, (void *)buf, buf_len); + sg_init_one(&sl, (void *)buf, buf_len); hdesc.flags = 0; err = crypto_hash_digest(&hdesc, &sl, sl.length, hash); @@ -221,8 +221,9 @@ int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *hdesc, cfs_page_t *page, unsigned int offset, unsigned int len) { - struct scatterlist sl = {0}; + struct scatterlist sl; + sg_init_table(&sl, 1); sg_set_page(&sl, page, len, offset & ~CFS_PAGE_MASK); return crypto_hash_update((struct hash_desc *)hdesc, &sl, sl.length); @@ -232,9 +233,9 @@ EXPORT_SYMBOL(cfs_crypto_hash_update_page); int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *hdesc, const void *buf, unsigned int buf_len) { - struct scatterlist sl = {0}; + struct scatterlist sl; - sg_set_buf(&sl, (void *)buf, buf_len); + sg_init_one(&sl, (void *)buf, buf_len); return crypto_hash_update((struct hash_desc *)hdesc, &sl, sl.length); } diff --git a/lnet/klnds/o2iblnd/o2iblnd.c b/lnet/klnds/o2iblnd/o2iblnd.c index 35a6132..46f7007 100644 --- a/lnet/klnds/o2iblnd/o2iblnd.c +++ b/lnet/klnds/o2iblnd/o2iblnd.c @@ -2147,6 +2147,8 @@ kiblnd_create_tx_pool(kib_poolset_t *ps, int size, kib_pool_t **pp_po) if (tx->tx_frags == NULL) break; + sg_init_table(tx->tx_frags, IBLND_MAX_RDMA_FRAGS); + LIBCFS_CPT_ALLOC(tx->tx_wrq, lnet_cpt_table(), ps->ps_cpt, (1 + IBLND_MAX_RDMA_FRAGS) * sizeof(*tx->tx_wrq)); diff --git a/lnet/klnds/o2iblnd/o2iblnd_cb.c b/lnet/klnds/o2iblnd/o2iblnd_cb.c index 90e35e6..2ebea68 100644 --- a/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -770,7 +770,6 @@ kiblnd_setup_rd_kiov (lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd, fragnob = min((int)(kiov->kiov_len - offset), nob); - memset(sg, 0, sizeof(*sg)); sg_set_page(sg, kiov->kiov_page, fragnob, kiov->kiov_offset + offset); sg++; -- 1.8.3.1