diff --git a/zfs/lib/libzpool/arc.c b/zfs/lib/libzpool/arc.c index a92a7e9cd9..b190ab1342 100644 --- a/zfs/lib/libzpool/arc.c +++ b/zfs/lib/libzpool/arc.c @@ -733,8 +733,15 @@ buf_fini(void) { int i; +#if defined(_KERNEL) && defined(HAVE_SPL) + /* Large allocations which do not require contiguous pages + * should be using vmem_free() in the linux kernel */ + vmem_free(buf_hash_table.ht_table, + (buf_hash_table.ht_mask + 1) * sizeof (void *)); +#else kmem_free(buf_hash_table.ht_table, (buf_hash_table.ht_mask + 1) * sizeof (void *)); +#endif for (i = 0; i < BUF_LOCKS; i++) mutex_destroy(&buf_hash_table.ht_locks[i].ht_lock); kmem_cache_destroy(hdr_cache); @@ -829,8 +836,15 @@ buf_init(void) hsize <<= 1; retry: buf_hash_table.ht_mask = hsize - 1; +#if defined(_KERNEL) && defined(HAVE_SPL) + /* Large allocations which do not require contiguous pages + * should be using vmem_alloc() in the linux kernel */ + buf_hash_table.ht_table = + vmem_zalloc(hsize * sizeof (void*), KM_SLEEP); +#else buf_hash_table.ht_table = kmem_zalloc(hsize * sizeof (void*), KM_NOSLEEP); +#endif if (buf_hash_table.ht_table == NULL) { ASSERT(hsize > (1ULL << 8)); hsize >>= 1; diff --git a/zfs/lib/libzpool/dbuf.c b/zfs/lib/libzpool/dbuf.c index b8f4cc69f8..fe4c2eedcf 100644 --- a/zfs/lib/libzpool/dbuf.c +++ b/zfs/lib/libzpool/dbuf.c @@ -255,7 +255,13 @@ dbuf_init(void) retry: h->hash_table_mask = hsize - 1; +#if defined(_KERNEL) && defined(HAVE_SPL) + /* Large allocations which do not require contiguous pages + * should be using vmem_alloc() in the linux kernel */ + h->hash_table = vmem_zalloc(hsize * sizeof (void *), KM_SLEEP); +#else h->hash_table = kmem_zalloc(hsize * sizeof (void *), KM_NOSLEEP); +#endif if (h->hash_table == NULL) { /* XXX - we should really return an error instead of assert */ ASSERT(hsize > (1ULL << 10)); @@ -279,7 +285,13 @@ dbuf_fini(void) for (i = 0; i < DBUF_MUTEXES; i++) mutex_destroy(&h->hash_mutexes[i]); +#if defined(_KERNEL) && defined(HAVE_SPL) + /* Large allocations which do not require contiguous pages + * should be using vmem_free() in the linux kernel */ + vmem_free(h->hash_table, (h->hash_table_mask + 1) * sizeof (void *)); +#else kmem_free(h->hash_table, (h->hash_table_mask + 1) * sizeof (void *)); +#endif kmem_cache_destroy(dbuf_cache); } diff --git a/zfs/lib/libzpool/dmu_send.c b/zfs/lib/libzpool/dmu_send.c index 663a26ba22..a0804e9268 100644 --- a/zfs/lib/libzpool/dmu_send.c +++ b/zfs/lib/libzpool/dmu_send.c @@ -1043,7 +1043,7 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, int fd, offset_t *voffp) #endif ra.voff = *voffp; ra.bufsize = 1<<20; - ra.buf = kmem_alloc(ra.bufsize, KM_SLEEP); + ra.buf = vmem_alloc(ra.bufsize, KM_SLEEP); /* these were verified in dmu_recv_begin */ ASSERT(drc->drc_drrb->drr_version == DMU_BACKUP_STREAM_VERSION); @@ -1133,7 +1133,7 @@ out: dmu_recv_abort_cleanup(drc); } - kmem_free(ra.buf, ra.bufsize); + vmem_free(ra.buf, ra.bufsize); *voffp = ra.voff; return (ra.err); } diff --git a/zfs/lib/libzpool/spa_history.c b/zfs/lib/libzpool/spa_history.c index db1441cebf..95eca1c850 100644 --- a/zfs/lib/libzpool/spa_history.c +++ b/zfs/lib/libzpool/spa_history.c @@ -293,7 +293,7 @@ spa_history_log_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) dmu_buf_rele(dbp, FTAG); if (hap->ha_log_type == LOG_INTERNAL) { - kmem_free((void*)hap->ha_history_str, HIS_MAX_RECORD_LEN); + vmem_free((void*)hap->ha_history_str, HIS_MAX_RECORD_LEN); kmem_free(hap, sizeof (history_arg_t)); } } @@ -419,7 +419,7 @@ spa_history_internal_log(history_internal_events_t event, spa_t *spa, return; hap = kmem_alloc(sizeof (history_arg_t), KM_SLEEP); - str = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP); + str = vmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP); va_start(adx, fmt); (void) vsnprintf(str, HIS_MAX_RECORD_LEN, fmt, adx); diff --git a/zfs/lib/libzpool/txg.c b/zfs/lib/libzpool/txg.c index c796979255..a5741bbdb3 100644 --- a/zfs/lib/libzpool/txg.c +++ b/zfs/lib/libzpool/txg.c @@ -49,7 +49,7 @@ txg_init(dsl_pool_t *dp, uint64_t txg) int c; bzero(tx, sizeof (tx_state_t)); - tx->tx_cpu = kmem_zalloc(max_ncpus * sizeof (tx_cpu_t), KM_SLEEP); + tx->tx_cpu = vmem_zalloc(max_ncpus * sizeof (tx_cpu_t), KM_SLEEP); for (c = 0; c < max_ncpus; c++) { int i; @@ -109,7 +109,7 @@ txg_fini(dsl_pool_t *dp) } } - kmem_free(tx->tx_cpu, max_ncpus * sizeof (tx_cpu_t)); + vmem_free(tx->tx_cpu, max_ncpus * sizeof (tx_cpu_t)); bzero(tx, sizeof (tx_state_t)); } diff --git a/zfs/lib/libzpool/zfs_ioctl.c b/zfs/lib/libzpool/zfs_ioctl.c index 7cb1e2dfe1..3438f973ad 100644 --- a/zfs/lib/libzpool/zfs_ioctl.c +++ b/zfs/lib/libzpool/zfs_ioctl.c @@ -132,7 +132,7 @@ __dprintf(const char *file, const char *func, int line, const char *fmt, ...) static void history_str_free(char *buf) { - kmem_free(buf, HIS_MAX_RECORD_LEN); + vmem_free(buf, HIS_MAX_RECORD_LEN); } static char * @@ -143,7 +143,7 @@ history_str_get(zfs_cmd_t *zc) if (zc->zc_history == 0) return (NULL); - buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP); + buf = vmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP); if (copyinstr((void *)(uintptr_t)zc->zc_history, buf, HIS_MAX_RECORD_LEN, NULL) != 0) { history_str_free(buf); @@ -741,12 +741,12 @@ put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl) if (size > zc->zc_nvlist_dst_size) { error = ENOMEM; } else { - packed = kmem_alloc(size, KM_SLEEP); + packed = vmem_alloc(size, KM_SLEEP); VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE, KM_SLEEP) == 0); error = xcopyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst, size); - kmem_free(packed, size); + vmem_free(packed, size); } zc->zc_nvlist_dst_size = size; @@ -3022,7 +3022,7 @@ zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) if (vec >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0])) return (EINVAL); - zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); + zc = vmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); error = xcopyin((void *)arg, zc, sizeof (zfs_cmd_t)); @@ -3061,7 +3061,7 @@ zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) zfs_log_history(zc); } - kmem_free(zc, sizeof (zfs_cmd_t)); + vmem_free(zc, sizeof (zfs_cmd_t)); return (error); }