From 2d2dac3ae77a3cbdc505328b6cbf648323a0795c Mon Sep 17 00:00:00 2001 From: James Simmons Date: Fri, 19 Jun 2020 09:39:34 -0400 Subject: [PATCH] LU-9859 libcfs: move tgt_descs to standard Linux bitmaps. Originally the Linux kernel was lacking a uniform bitmap API so Lustre created its own. Todays modern kernels support a standard bitmap API so migrate tgt_descs to the standard API. Change-Id: If43b520c29d16355189b1eb7f9fdab7309446545 Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/38981 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Shaun Tancheff Reviewed-by: Lai Siyao Reviewed-by: Neil Brown Reviewed-by: Oleg Drokin --- libcfs/autoconf/lustre-libcfs.m4 | 19 +++++++++++++++++++ libcfs/include/libcfs/linux/linux-mem.h | 18 ++++++++++++++++++ lnet/klnds/o2iblnd/o2iblnd.h | 3 +++ lustre/include/lu_object.h | 16 ++++++++-------- lustre/lmv/lmv_internal.h | 6 +++--- lustre/lod/lod_lov.c | 6 +++--- lustre/lod/lod_object.c | 6 +++--- lustre/lod/lod_qos.c | 20 ++++++++++---------- lustre/lod/lproc_lod.c | 16 ++++++++-------- lustre/obdclass/lu_tgt_descs.c | 20 ++++++++++---------- 10 files changed, 85 insertions(+), 45 deletions(-) diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4 index c3efe06..b42c9a7 100644 --- a/libcfs/autoconf/lustre-libcfs.m4 +++ b/libcfs/autoconf/lustre-libcfs.m4 @@ -1085,6 +1085,24 @@ wait_var_event, [ ]) # LIBCFS_WAIT_VAR_EVENT # +# LIBCFS_BITMAP_ALLOC +# +# Kernel version 4.17 commit c42b65e363ce97a828f81b59033c3558f8fa7f70 +# added bitmap memory allocation handling. +# +AC_DEFUN([LIBCFS_BITMAP_ALLOC], [ +LB_CHECK_COMPILE([if Linux bitmap memory management exist], +bitmap_alloc, [ + #include +],[ + unsigned long *map = bitmap_alloc(1, GFP_KERNEL); +],[ + AC_DEFINE(HAVE_BITMAP_ALLOC, 1, + [Linux bitmap can be allocated]) +]) +]) # LIBCFS_BITMAP_ALLOC + +# # LIBCFS_CLEAR_AND_WAKE_UP_BIT # # Kernel version 4.17-rc2 commit 8236b0ae31c837d2b3a2565c5f8d77f637e824cc @@ -1353,6 +1371,7 @@ LIBCFS_TIMER_SETUP # 4.16 LIBCFS_WAIT_VAR_EVENT # 4.17 +LIBCFS_BITMAP_ALLOC LIBCFS_CLEAR_AND_WAKE_UP_BIT # 4.19 LIBCFS_XARRAY_SUPPORT diff --git a/libcfs/include/libcfs/linux/linux-mem.h b/libcfs/include/libcfs/linux/linux-mem.h index 1694b80..80668b1 100644 --- a/libcfs/include/libcfs/linux/linux-mem.h +++ b/libcfs/include/libcfs/linux/linux-mem.h @@ -74,6 +74,24 @@ static inline void memalloc_noreclaim_restore(unsigned int flags) } #endif /* !HAVE_MEMALLOC_RECLAIM */ +#ifndef HAVE_BITMAP_ALLOC +static inline unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags) +{ + return kmalloc_array(BITS_TO_LONGS(nbits), sizeof(unsigned long), + flags); +} + +static inline unsigned long *bitmap_zalloc(unsigned int nbits, gfp_t flags) +{ + return bitmap_alloc(nbits, flags | __GFP_ZERO); +} + +static inline void bitmap_free(const unsigned long *bitmap) +{ + kfree(bitmap); +} +#endif /* !HAVE_BITMAP_ALLOC */ + /* * Shrinker */ diff --git a/lnet/klnds/o2iblnd/o2iblnd.h b/lnet/klnds/o2iblnd/o2iblnd.h index 3793817..ad09426 100644 --- a/lnet/klnds/o2iblnd/o2iblnd.h +++ b/lnet/klnds/o2iblnd/o2iblnd.h @@ -41,6 +41,9 @@ #undef NEED_KTIME_GET_REAL_NS #endif +/* MOFED has its own bitmap_alloc backport */ +#define HAVE_BITMAP_ALLOC 1 + #endif #include diff --git a/lustre/include/lu_object.h b/lustre/include/lu_object.h index 187ecdd..4afaa18 100644 --- a/lustre/include/lu_object.h +++ b/lustre/include/lu_object.h @@ -1607,7 +1607,7 @@ struct lu_tgt_descs { /* Size of the lu_tgts array, granted to be a power of 2 */ __u32 ltd_tgts_size; /* bitmap of TGTs available */ - struct cfs_bitmap *ltd_tgt_bitmap; + unsigned long *ltd_tgt_bitmap; /* TGTs scheduled to be deleted */ __u32 ltd_death_row; /* Table refcount used for delayed deletion */ @@ -1646,9 +1646,9 @@ static inline struct lu_tgt_desc *ltd_first_tgt(struct lu_tgt_descs *ltd) { int index; - index = find_first_bit(ltd->ltd_tgt_bitmap->data, - ltd->ltd_tgt_bitmap->size); - return (index < ltd->ltd_tgt_bitmap->size) ? LTD_TGT(ltd, index) : NULL; + index = find_first_bit(ltd->ltd_tgt_bitmap, + ltd->ltd_tgts_size); + return (index < ltd->ltd_tgts_size) ? LTD_TGT(ltd, index) : NULL; } static inline struct lu_tgt_desc *ltd_next_tgt(struct lu_tgt_descs *ltd, @@ -1660,10 +1660,10 @@ static inline struct lu_tgt_desc *ltd_next_tgt(struct lu_tgt_descs *ltd, return NULL; index = tgt->ltd_index; - LASSERT(index < ltd->ltd_tgt_bitmap->size); - index = find_next_bit(ltd->ltd_tgt_bitmap->data, - ltd->ltd_tgt_bitmap->size, index + 1); - return (index < ltd->ltd_tgt_bitmap->size) ? LTD_TGT(ltd, index) : NULL; + LASSERT(index < ltd->ltd_tgts_size); + index = find_next_bit(ltd->ltd_tgt_bitmap, + ltd->ltd_tgts_size, index + 1); + return (index < ltd->ltd_tgts_size) ? LTD_TGT(ltd, index) : NULL; } #define ltd_foreach_tgt(ltd, tgt) \ diff --git a/lustre/lmv/lmv_internal.h b/lustre/lmv/lmv_internal.h index 7b9aeff..d0527ba 100644 --- a/lustre/lmv/lmv_internal.h +++ b/lustre/lmv/lmv_internal.h @@ -73,15 +73,15 @@ static inline struct obd_device *lmv2obd_dev(struct lmv_obd *lmv) static inline struct lu_tgt_desc * lmv_tgt(struct lmv_obd *lmv, __u32 index) { - return index < lmv->lmv_mdt_descs.ltd_tgt_bitmap->size ? + return index < lmv->lmv_mdt_descs.ltd_tgts_size ? LTD_TGT(&lmv->lmv_mdt_descs, index) : NULL; } static inline bool lmv_mdt0_inited(struct lmv_obd *lmv) { - return lmv->lmv_mdt_descs.ltd_tgt_bitmap->size > 0 && - cfs_bitmap_check(lmv->lmv_mdt_descs.ltd_tgt_bitmap, 0); + return lmv->lmv_mdt_descs.ltd_tgts_size > 0 && + test_bit(0, lmv->lmv_mdt_descs.ltd_tgt_bitmap); } #define lmv_foreach_tgt(lmv, tgt) ltd_foreach_tgt(&(lmv)->lmv_mdt_descs, tgt) diff --git a/lustre/lod/lod_lov.c b/lustre/lod/lod_lov.c index 9861040..d3f6390 100644 --- a/lustre/lod/lod_lov.c +++ b/lustre/lod/lod_lov.c @@ -415,7 +415,7 @@ int lod_del_device(const struct lu_env *env, struct lod_device *lod, mutex_lock(<d->ltd_mutex); tgt = LTD_TGT(ltd, idx); /* check that the index is allocated in the bitmap */ - if (!cfs_bitmap_check(ltd->ltd_tgt_bitmap, idx) || !tgt) { + if (!test_bit(idx, ltd->ltd_tgt_bitmap) || !tgt) { CERROR("%s: device %d is not set up\n", obd->obd_name, idx); GOTO(out, rc = -EINVAL); } @@ -961,7 +961,7 @@ repeat: static int validate_lod_and_idx(struct lod_device *md, __u32 idx) { if (unlikely(idx >= md->lod_ost_descs.ltd_tgts_size || - !cfs_bitmap_check(md->lod_ost_bitmap, idx))) { + !test_bit(idx, md->lod_ost_bitmap))) { CERROR("%s: bad idx: %d of %d\n", lod2obd(md)->obd_name, idx, md->lod_ost_descs.ltd_tgts_size); return -EINVAL; @@ -1530,7 +1530,7 @@ static int lod_verify_v1v3(struct lod_device *d, const struct lu_buf *buf, } /* if lmm_stripe_offset is *not* in bitmap */ - if (!cfs_bitmap_check(d->lod_ost_bitmap, stripe_offset)) { + if (!test_bit(stripe_offset, d->lod_ost_bitmap)) { CDEBUG(D_LAYOUT, "stripe offset %u not in bitmap\n", stripe_offset); GOTO(out, rc = -EINVAL); diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index 867fb36..0381a6e 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -2108,7 +2108,7 @@ static int lod_mdt_alloc_specific(const struct lu_env *env, /* Sigh, this index is not in the bitmap, let's check * next available target */ - if (!cfs_bitmap_check(ltd->ltd_tgt_bitmap, idx) && + if (!test_bit(idx, ltd->ltd_tgt_bitmap) && idx != master_index) continue; @@ -6394,7 +6394,7 @@ static bool lod_sel_osts_allowed(const struct lu_env *env, if (j < lod_comp->llc_stripe_count) continue; - if (!cfs_bitmap_check(lod->lod_ost_bitmap, index)) { + if (!test_bit(index, lod->lod_ost_bitmap)) { CDEBUG(D_LAYOUT, "ost %d no longer present\n", index); ret = false; break; @@ -8502,7 +8502,7 @@ static int lod_object_init(const struct lu_env *env, struct lu_object *lo, if (ltd != NULL) { if (ltd->ltd_tgts_size > idx && - cfs_bitmap_check(ltd->ltd_tgt_bitmap, idx)) { + test_bit(idx, ltd->ltd_tgt_bitmap)) { tgt = LTD_TGT(ltd, idx); LASSERT(tgt != NULL); diff --git a/lustre/lod/lod_qos.c b/lustre/lod/lod_qos.c index 509b0df..7fe0826 100644 --- a/lustre/lod/lod_qos.c +++ b/lustre/lod/lod_qos.c @@ -296,8 +296,8 @@ static int lod_qos_calc_rr(struct lod_device *lod, struct lu_tgt_descs *ltd, for (i = 0; i < lqr->lqr_pool.op_count; i++) { int next; - if (!cfs_bitmap_check(ltd->ltd_tgt_bitmap, - src_pool->op_array[i])) + if (!test_bit(src_pool->op_array[i], + ltd->ltd_tgt_bitmap)) continue; tgt = LTD_TGT(ltd, src_pool->op_array[i]); @@ -572,7 +572,7 @@ static inline bool lod_should_avoid_ost(struct lod_object *lo, bool used = false; int i; - if (!cfs_bitmap_check(lod->lod_ost_bitmap, index)) { + if (!test_bit(index, lod->lod_ost_bitmap)) { QOS_DEBUG("OST%d: been used in conflicting mirror component\n", index); return true; @@ -808,7 +808,7 @@ repeat_find: stripe_idx, array_idx, ost_idx); if ((ost_idx == LOV_QOS_EMPTY) || - !cfs_bitmap_check(m->lod_ost_bitmap, ost_idx)) + !test_bit(ost_idx, m->lod_ost_bitmap)) continue; /* Fail Check before osc_precreate() is called @@ -890,7 +890,7 @@ lod_qos_mdt_in_use_init(const struct lu_env *env, for (j = 0; j < pool->op_count; j++) { mdt_idx = pool->op_array[j]; - if (!cfs_bitmap_check(ltd->ltd_tgt_bitmap, mdt_idx)) + if (!test_bit(mdt_idx, ltd->ltd_tgt_bitmap)) continue; mdt = LTD_TGT(ltd, mdt_idx); @@ -993,7 +993,7 @@ repeat_find: stripe_idx, pool_idx, mdt_idx); if (mdt_idx == LOV_QOS_EMPTY || - !cfs_bitmap_check(ltd->ltd_tgt_bitmap, mdt_idx)) + !test_bit(mdt_idx, ltd->ltd_tgt_bitmap)) continue; /* do not put >1 objects on one MDT */ @@ -1132,7 +1132,7 @@ static int lod_alloc_ost_list(const struct lu_env *env, struct lod_object *lo, i++, array_idx = (array_idx + 1) % lod_comp->llc_stripe_count) { __u32 ost_idx = lod_comp->llc_ostlist.op_array[array_idx]; - if (!cfs_bitmap_check(m->lod_ost_bitmap, ost_idx)) { + if (!test_bit(ost_idx, m->lod_ost_bitmap)) { rc = -ENODEV; break; } @@ -1260,7 +1260,7 @@ repeat_find: i++, array_idx = (array_idx + 1) % ost_count) { ost_idx = osts->op_array[array_idx]; - if (!cfs_bitmap_check(m->lod_ost_bitmap, ost_idx)) + if (!test_bit(ost_idx, m->lod_ost_bitmap)) continue; /* Fail Check before osc_precreate() is called @@ -1458,7 +1458,7 @@ static int lod_ost_alloc_qos(const struct lu_env *env, struct lod_object *lo, good_osts = 0; /* Find all the OSTs that are valid stripe candidates */ for (i = 0; i < osts->op_count; i++) { - if (!cfs_bitmap_check(lod->lod_ost_bitmap, osts->op_array[i])) + if (!test_bit(osts->op_array[i], lod->lod_ost_bitmap)) continue; ost = OST_TGT(lod, osts->op_array[i]); @@ -1702,7 +1702,7 @@ int lod_mdt_alloc_qos(const struct lu_env *env, struct lod_object *lo, good_mdts = 0; /* Find all the MDTs that are valid stripe candidates */ for (i = 0; i < pool->op_count; i++) { - if (!cfs_bitmap_check(ltd->ltd_tgt_bitmap, pool->op_array[i])) + if (!test_bit(pool->op_array[i], ltd->ltd_tgt_bitmap)) continue; mdt = LTD_TGT(ltd, pool->op_array[i]); diff --git a/lustre/lod/lproc_lod.c b/lustre/lod/lproc_lod.c index 0b275cf..c4a4572 100644 --- a/lustre/lod/lproc_lod.c +++ b/lustre/lod/lproc_lod.c @@ -785,12 +785,12 @@ static void *lod_tgts_seq_start(struct seq_file *p, loff_t *pos, bool is_mdt) LASSERT(obd != NULL); lod_getref(ltd); /* released in lod_tgts_seq_stop */ - if (*pos >= ltd->ltd_tgt_bitmap->size) + if (*pos >= ltd->ltd_tgts_size) return NULL; - *pos = find_next_bit(ltd->ltd_tgt_bitmap->data, - ltd->ltd_tgt_bitmap->size, *pos); - if (*pos < ltd->ltd_tgt_bitmap->size) + *pos = find_next_bit(ltd->ltd_tgt_bitmap, + ltd->ltd_tgts_size, *pos); + if (*pos < ltd->ltd_tgts_size) return LTD_TGT(ltd, *pos); else return NULL; @@ -835,12 +835,12 @@ static void *lod_tgts_seq_next(struct seq_file *p, void *v, loff_t *pos, struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs : &lod->lod_ost_descs; - if (*pos >= ltd->ltd_tgt_bitmap->size - 1) + if (*pos >= ltd->ltd_tgts_size - 1) return NULL; - *pos = find_next_bit(ltd->ltd_tgt_bitmap->data, - ltd->ltd_tgt_bitmap->size, *pos + 1); - if (*pos < ltd->ltd_tgt_bitmap->size) + *pos = find_next_bit(ltd->ltd_tgt_bitmap, + ltd->ltd_tgts_size, *pos + 1); + if (*pos < ltd->ltd_tgts_size) return LTD_TGT(ltd, *pos); else return NULL; diff --git a/lustre/obdclass/lu_tgt_descs.c b/lustre/obdclass/lu_tgt_descs.c index 2be22102..22d79a1 100644 --- a/lustre/obdclass/lu_tgt_descs.c +++ b/lustre/obdclass/lu_tgt_descs.c @@ -264,7 +264,7 @@ int lu_tgt_descs_init(struct lu_tgt_descs *ltd, bool is_mdt) * the tgt array and bitmap are allocated/grown dynamically as tgts are * added to the LOD/LMV, see lu_tgt_descs_add() */ - ltd->ltd_tgt_bitmap = CFS_ALLOCATE_BITMAP(BITS_PER_LONG); + ltd->ltd_tgt_bitmap = bitmap_zalloc(BITS_PER_LONG, GFP_NOFS); if (!ltd->ltd_tgt_bitmap) return -ENOMEM; @@ -300,7 +300,7 @@ void lu_tgt_descs_fini(struct lu_tgt_descs *ltd) { int i; - CFS_FREE_BITMAP(ltd->ltd_tgt_bitmap); + bitmap_free(ltd->ltd_tgt_bitmap); for (i = 0; i < TGT_PTRS; i++) { if (ltd->ltd_tgt_idx[i]) OBD_FREE_PTR(ltd->ltd_tgt_idx[i]); @@ -324,27 +324,27 @@ EXPORT_SYMBOL(lu_tgt_descs_fini); */ static int lu_tgt_descs_resize(struct lu_tgt_descs *ltd, __u32 newsize) { - struct cfs_bitmap *new_bitmap, *old_bitmap = NULL; + unsigned long *new_bitmap, *old_bitmap = NULL; /* someone else has already resize the array */ if (newsize <= ltd->ltd_tgts_size) return 0; - new_bitmap = CFS_ALLOCATE_BITMAP(newsize); + new_bitmap = bitmap_zalloc(newsize, GFP_NOFS); if (!new_bitmap) return -ENOMEM; if (ltd->ltd_tgts_size > 0) { /* the bitmap already exists, copy data from old one */ - cfs_bitmap_copy(new_bitmap, ltd->ltd_tgt_bitmap); + bitmap_copy(new_bitmap, ltd->ltd_tgt_bitmap, + ltd->ltd_tgts_size); old_bitmap = ltd->ltd_tgt_bitmap; } ltd->ltd_tgts_size = newsize; ltd->ltd_tgt_bitmap = new_bitmap; - if (old_bitmap) - CFS_FREE_BITMAP(old_bitmap); + bitmap_free(old_bitmap); CDEBUG(D_CONFIG, "tgt size: %d\n", ltd->ltd_tgts_size); @@ -381,7 +381,7 @@ int ltd_add_tgt(struct lu_tgt_descs *ltd, struct lu_tgt_desc *tgt) rc = lu_tgt_descs_resize(ltd, newsize); if (rc) RETURN(rc); - } else if (cfs_bitmap_check(ltd->ltd_tgt_bitmap, index)) { + } else if (test_bit(index, ltd->ltd_tgt_bitmap)) { RETURN(-EEXIST); } @@ -392,7 +392,7 @@ int ltd_add_tgt(struct lu_tgt_descs *ltd, struct lu_tgt_desc *tgt) } LTD_TGT(ltd, tgt->ltd_index) = tgt; - cfs_bitmap_set(ltd->ltd_tgt_bitmap, tgt->ltd_index); + set_bit(tgt->ltd_index, ltd->ltd_tgt_bitmap); ltd->ltd_lov_desc.ld_tgt_count++; if (tgt->ltd_active) @@ -409,7 +409,7 @@ void ltd_del_tgt(struct lu_tgt_descs *ltd, struct lu_tgt_desc *tgt) { lu_qos_del_tgt(<d->ltd_qos, tgt); LTD_TGT(ltd, tgt->ltd_index) = NULL; - cfs_bitmap_clear(ltd->ltd_tgt_bitmap, tgt->ltd_index); + clear_bit(tgt->ltd_index, ltd->ltd_tgt_bitmap); ltd->ltd_lov_desc.ld_tgt_count--; if (tgt->ltd_active) ltd->ltd_lov_desc.ld_active_tgt_count--; -- 1.8.3.1