]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
Make the slabrefzone, the zone from which we allocated slabs with
authorbmilekic <bmilekic@FreeBSD.org>
Wed, 9 Jun 2004 19:18:50 +0000 (19:18 +0000)
committerbmilekic <bmilekic@FreeBSD.org>
Wed, 9 Jun 2004 19:18:50 +0000 (19:18 +0000)
commit1edc23feaad96fde62e176b34b55074f2c42f1c4
tree2642e88b94f9d20c2a13881194c2d583ae3106ea
parentc298d11504ba291b24d865b166403192861c70ba
Make the slabrefzone, the zone from which we allocated slabs with
internal reference counters, UMA_ZONE_NOFREE.  This way, those slabs
(with their ref counts) will be effectively type-stable, then using
a trick like this on the refcount is no longer dangerous:

        MEXT_REM_REF(m);
        if (atomic_cmpset_int(m->m_ext.ref_cnt, 0, 1)) {
                if (m->m_ext.ext_type == EXT_PACKET) {
                        uma_zfree(zone_pack, m);
                        return;
                } else if (m->m_ext.ext_type == EXT_CLUSTER) {
                        uma_zfree(zone_clust, m->m_ext.ext_buf);
                        m->m_ext.ext_buf = NULL;
                } else {
                        (*(m->m_ext.ext_free))(m->m_ext.ext_buf,
                            m->m_ext.ext_args);
                        if (m->m_ext.ext_type != EXT_EXTREF)
                                free(m->m_ext.ref_cnt, M_MBUF);
                }
        }
        uma_zfree(zone_mbuf, m);

Previously, a second thread hitting the above cmpset might
actually read the refcnt AFTER it has already been freed.  A very
rare occurance.  Now we'll know that it won't be freed, though.

Spotted by: julian, pjd
sys/vm/uma_core.c