예제 #1
0
/*
 * Get an sf_buf from the freelist.  May block if none are available.
 */
struct sf_buf *
sf_buf_alloc(struct vm_page *m, int flags)
{
    struct sf_head *hash_list;
    struct sf_buf *sf;
    int error;

#ifdef SFBUF_OPTIONAL_DIRECT_MAP
    if (SFBUF_OPTIONAL_DIRECT_MAP)
        return ((struct sf_buf *)m);
#endif

    KASSERT(curthread->td_pinned > 0 || (flags & SFB_CPUPRIVATE) == 0,
            ("sf_buf_alloc(SFB_CPUPRIVATE): curthread not pinned"));
    hash_list = &sf_buf_active[SF_BUF_HASH(m)];
    mtx_lock(&sf_buf_lock);
    LIST_FOREACH(sf, hash_list, list_entry) {
        if (sf->m == m) {
            sf->ref_count++;
            if (sf->ref_count == 1) {
                TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
                nsfbufsused++;
                nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
            }
#if defined(SMP) && defined(SFBUF_CPUSET)
            sf_buf_shootdown(sf, flags);
#endif
            goto done;
        }
    }
    while ((sf = TAILQ_FIRST(&sf_buf_freelist)) == NULL) {
        if (flags & SFB_NOWAIT)
            goto done;
        sf_buf_alloc_want++;
        SFSTAT_INC(sf_allocwait);
        error = msleep(&sf_buf_freelist, &sf_buf_lock,
                       (flags & SFB_CATCH) ? PCATCH | PVM : PVM, "sfbufa", 0);
        sf_buf_alloc_want--;

        /*
         * If we got a signal, don't risk going back to sleep.
         */
        if (error)
            goto done;
    }
    TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
    if (sf->m != NULL)
        LIST_REMOVE(sf, list_entry);
    LIST_INSERT_HEAD(hash_list, sf, list_entry);
    sf->ref_count = 1;
    sf->m = m;
    nsfbufsused++;
    nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
    sf_buf_map(sf, flags);
done:
    mtx_unlock(&sf_buf_lock);
    return (sf);
}
예제 #2
0
파일: vm_machdep.c 프로젝트: hlcherub/src
/*
 * Get an sf_buf from the freelist. Will block if none are available.
 */
struct sf_buf *
sf_buf_alloc(struct vm_page *m, int flags)
{
    struct sf_head *hash_list;
    struct sf_buf *sf;
    int error;

    if (hw_direct_map) {
        /* Shortcut the direct mapped case */
        return ((struct sf_buf *)m);
    }

    hash_list = &sf_buf_active[SF_BUF_HASH(m)];
    mtx_lock(&sf_buf_lock);
    LIST_FOREACH(sf, hash_list, list_entry) {
        if (sf->m == m) {
            sf->ref_count++;
            if (sf->ref_count == 1) {
                TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
                nsfbufsused++;
                nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
            }
            goto done;
        }
    }

    while ((sf = TAILQ_FIRST(&sf_buf_freelist)) == NULL) {
        if (flags & SFB_NOWAIT)
            goto done;

        sf_buf_alloc_want++;
        SFSTAT_INC(sf_allocwait);
        error = msleep(&sf_buf_freelist, &sf_buf_lock,
                       (flags & SFB_CATCH) ? PCATCH | PVM : PVM, "sfbufa", 0);
        sf_buf_alloc_want--;

        /*
         * If we got a signal, don't risk going back to sleep.
         */
        if (error)
            goto done;
    }

    TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
    if (sf->m != NULL)
        LIST_REMOVE(sf, list_entry);

    LIST_INSERT_HEAD(hash_list, sf, list_entry);
    sf->ref_count = 1;
    sf->m = m;
    nsfbufsused++;
    nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
    pmap_qenter(sf->kva, &sf->m, 1);
done:
    mtx_unlock(&sf_buf_lock);
    return (sf);
}
예제 #3
0
/*
 * Get an sf_buf from the freelist. Will block if none are available.
 */
struct sf_buf *
sf_buf_alloc(struct vm_page *m, int flags)
{
#ifdef ARM_USE_SMALL_ALLOC
	return ((struct sf_buf *)m);
#else
	struct sf_head *hash_list;
	struct sf_buf *sf;
	int error;

	hash_list = &sf_buf_active[SF_BUF_HASH(m)];
	mtx_lock(&sf_buf_lock);
	LIST_FOREACH(sf, hash_list, list_entry) {
		if (sf->m == m) {
			sf->ref_count++;
			if (sf->ref_count == 1) {
				TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
				nsfbufsused++;
				nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
			}
			goto done;
		}
	}
	while ((sf = TAILQ_FIRST(&sf_buf_freelist)) == NULL) {
		if (flags & SFB_NOWAIT)
			goto done;
		sf_buf_alloc_want++;
		SFSTAT_INC(sf_allocwait);
		error = msleep(&sf_buf_freelist, &sf_buf_lock,
		    (flags & SFB_CATCH) ? PCATCH | PVM : PVM, "sfbufa", 0);
		sf_buf_alloc_want--;
	

		/*
		 * If we got a signal, don't risk going back to sleep.
		 */
		if (error)
			goto done;
	}
	TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
	if (sf->m != NULL)
		LIST_REMOVE(sf, list_entry);
	LIST_INSERT_HEAD(hash_list, sf, list_entry);
	sf->ref_count = 1;
	sf->m = m;
	nsfbufsused++;
	nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
	pmap_kenter(sf->kva, VM_PAGE_TO_PHYS(sf->m));
done:
	mtx_unlock(&sf_buf_lock);
	return (sf);
#endif
}