]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Avoid 128K kmem allocations in mzap_upgrade()
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 5 Aug 2014 20:46:49 +0000 (13:46 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 11 Aug 2014 23:10:32 +0000 (16:10 -0700)
As originally implemented the mzap_upgrade() function will
perform up to SPA_MAXBLOCKSIZE allocations using kmem_alloc().
These large allocations can potentially block indefinitely
if contiguous memory is not available.  Since this allocation
is done under the zap->zap_rwlock it can appear as if there is
a deadlock in zap_lockdir().  This is shown below.

The optimal fix for this would be to rework mzap_upgrade()
such that no large allocations are required.  This could be
done but it would result in us diverging further from the other
implementations.  Therefore I've opted against doing this
unless it becomes absolutely necessary.

Instead mzap_upgrade() has been updated to use zio_buf_alloc()
which can reliably provide buffers of up to SPA_MAXBLOCKSIZE.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Richard Yao <ryao@gentoo.org>
Close #2580

module/zfs/zap_micro.c

index 68fb747697d203ab971cad24c5614b0704481667..2249b73380270160f9df14b5c2939bc29b33e354 100644 (file)
@@ -533,7 +533,7 @@ mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags)
        ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
 
        sz = zap->zap_dbuf->db_size;
-       mzp = kmem_alloc(sz, KM_PUSHPAGE | KM_NODEBUG);
+       mzp = zio_buf_alloc(sz);
        bcopy(zap->zap_dbuf->db_data, mzp, sz);
        nchunks = zap->zap_m.zap_num_chunks;
 
@@ -541,7 +541,7 @@ mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags)
                err = dmu_object_set_blocksize(zap->zap_objset, zap->zap_object,
                    1ULL << fzap_default_block_shift, 0, tx);
                if (err) {
-                       kmem_free(mzp, sz);
+                       zio_buf_free(mzp, sz);
                        return (err);
                }
        }
@@ -567,7 +567,7 @@ mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags)
                if (err)
                        break;
        }
-       kmem_free(mzp, sz);
+       zio_buf_free(mzp, sz);
        *zapp = zap;
        return (err);
 }