示例#1
0
/*
 * MPSAFE
 */
static vm_object_t
phys_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
                 vm_ooffset_t foff, struct ucred *cred)
{
    vm_object_t object, object1;
    vm_pindex_t pindex;

    /*
     * Offset should be page aligned.
     */
    if (foff & PAGE_MASK)
        return (NULL);

    pindex = OFF_TO_IDX(foff + PAGE_MASK + size);

    if (handle != NULL) {
        mtx_lock(&phys_pager_mtx);
        /*
         * Look up pager, creating as necessary.
         */
        object1 = NULL;
        object = vm_pager_object_lookup(&phys_pager_object_list, handle);
        if (object == NULL) {
            /*
             * Allocate object and associate it with the pager.
             */
            mtx_unlock(&phys_pager_mtx);
            object1 = vm_object_allocate(OBJT_PHYS, pindex);
            mtx_lock(&phys_pager_mtx);
            object = vm_pager_object_lookup(&phys_pager_object_list,
                                            handle);
            if (object != NULL) {
                /*
                 * We raced with other thread while
                 * allocating object.
                 */
                if (pindex > object->size)
                    object->size = pindex;
            } else {
                object = object1;
                object1 = NULL;
                object->handle = handle;
                TAILQ_INSERT_TAIL(&phys_pager_object_list, object,
                                  pager_object_list);
            }
        } else {
            if (pindex > object->size)
                object->size = pindex;
        }
        mtx_unlock(&phys_pager_mtx);
        vm_object_deallocate(object1);
    } else {
        object = vm_object_allocate(OBJT_PHYS, pindex);
    }

    return (object);
}
示例#2
0
文件: phys_pager.c 项目: MarginC/kame
/*
 * MPSAFE
 */
static vm_object_t
phys_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
		 vm_ooffset_t foff)
{
	vm_object_t object;

	/*
	 * Offset should be page aligned.
	 */
	if (foff & PAGE_MASK)
		return (NULL);

	size = round_page(size);

	if (handle != NULL) {
		mtx_lock(&Giant);
		/*
		 * Lock to prevent object creation race condition.
		 */
		while (phys_pager_alloc_lock) {
			phys_pager_alloc_lock = -1;
			tsleep(&phys_pager_alloc_lock, PVM, "swpalc", 0);
		}
		phys_pager_alloc_lock = 1;

		/*
		 * Look up pager, creating as necessary.
		 */
		object = vm_pager_object_lookup(&phys_pager_object_list, handle);
		if (object == NULL) {
			/*
			 * Allocate object and associate it with the pager.
			 */
			object = vm_object_allocate(OBJT_PHYS,
				OFF_TO_IDX(foff + size));
			object->handle = handle;
			mtx_lock(&phys_pager_mtx);
			TAILQ_INSERT_TAIL(&phys_pager_object_list, object,
			    pager_object_list);
			mtx_unlock(&phys_pager_mtx);
		} else {
			/*
			 * Gain a reference to the object.
			 */
			vm_object_reference(object);
			if (OFF_TO_IDX(foff + size) > object->size)
				object->size = OFF_TO_IDX(foff + size);
		}
		if (phys_pager_alloc_lock == -1)
			wakeup(&phys_pager_alloc_lock);
		phys_pager_alloc_lock = 0;
		mtx_unlock(&Giant);
	} else {
		object = vm_object_allocate(OBJT_PHYS,
			OFF_TO_IDX(foff + size));
	}

	return (object);
}
vm_object_t
cdev_pager_lookup(void *handle)
{
	vm_object_t object;
	mtx_lock(&dev_pager_mtx);
	object = vm_pager_object_lookup(&dev_pager_object_list, handle);
	mtx_unlock(&dev_pager_mtx);
	return (object);
}
vm_object_t
cdev_pager_allocate(void *handle, enum obj_type tp, struct cdev_pager_ops *ops,
	vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t foff, struct ucred *cred)
{
	cdev_t dev;
	vm_object_t object;
	u_short color;

	/*
	 * Offset should be page aligned.
	 */
	if (foff & PAGE_MASK)
		return (NULL);

	size = round_page64(size);

	if (ops->cdev_pg_ctor(handle, size, prot, foff, cred, &color) != 0)
		return (NULL);

	/*
	 * Look up pager, creating as necessary.
	 */
	mtx_lock(&dev_pager_mtx);
	object = vm_pager_object_lookup(&dev_pager_object_list, handle);
	if (object == NULL) {
		/*
		 * Allocate object and associate it with the pager.
		 */
		object = vm_object_allocate_hold(tp,
						 OFF_TO_IDX(foff + size));
		object->handle = handle;
		object->un_pager.devp.ops = ops;
		object->un_pager.devp.dev = handle;
		TAILQ_INIT(&object->un_pager.devp.devp_pglist);

		/*
		 * handle is only a device for old_dev_pager_ctor.
		 */
		if (ops->cdev_pg_ctor == old_dev_pager_ctor) {
			dev = handle;
			dev->si_object = object;
		}

		TAILQ_INSERT_TAIL(&dev_pager_object_list, object,
		    pager_object_list);

		vm_object_drop(object);
	} else {
		/*
		 * Gain a reference to the object.
		 */
		vm_object_hold(object);
		vm_object_reference_locked(object);
		if (OFF_TO_IDX(foff + size) > object->size)
			object->size = OFF_TO_IDX(foff + size);
		vm_object_drop(object);
	}
	mtx_unlock(&dev_pager_mtx);

	return (object);
}
示例#5
0
vm_object_t
cdev_pager_allocate(void *handle, enum obj_type tp, struct cdev_pager_ops *ops,
    vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t foff, struct ucred *cred)
{
	vm_object_t object, object1;
	vm_pindex_t pindex;
	u_short color;

	if (tp != OBJT_DEVICE && tp != OBJT_MGTDEVICE)
		return (NULL);

	/*
	 * Offset should be page aligned.
	 */
	if (foff & PAGE_MASK)
		return (NULL);

	size = round_page(size);
	pindex = OFF_TO_IDX(foff + size);

	if (ops->cdev_pg_ctor(handle, size, prot, foff, cred, &color) != 0)
		return (NULL);
	mtx_lock(&dev_pager_mtx);

	/*
	 * Look up pager, creating as necessary.
	 */
	object1 = NULL;
	object = vm_pager_object_lookup(&dev_pager_object_list, handle);
	if (object == NULL) {
		/*
		 * Allocate object and associate it with the pager.  Initialize
		 * the object's pg_color based upon the physical address of the
		 * device's memory.
		 */
		mtx_unlock(&dev_pager_mtx);
		object1 = vm_object_allocate(tp, pindex);
		object1->flags |= OBJ_COLORED;
		object1->pg_color = color;
		object1->handle = handle;
		object1->un_pager.devp.ops = ops;
		object1->un_pager.devp.dev = handle;
		TAILQ_INIT(&object1->un_pager.devp.devp_pglist);
		mtx_lock(&dev_pager_mtx);
		object = vm_pager_object_lookup(&dev_pager_object_list, handle);
		if (object != NULL) {
			/*
			 * We raced with other thread while allocating object.
			 */
			if (pindex > object->size)
				object->size = pindex;
		} else {
			object = object1;
			object1 = NULL;
			object->handle = handle;
			TAILQ_INSERT_TAIL(&dev_pager_object_list, object,
			    pager_object_list);
			KASSERT(object->type == tp,
		("Inconsistent device pager type %p %d", object, tp));
		}
	} else {
		if (pindex > object->size)
			object->size = pindex;
	}
	mtx_unlock(&dev_pager_mtx);
	if (object1 != NULL) {
		object1->handle = object1;
		mtx_lock(&dev_pager_mtx);
		TAILQ_INSERT_TAIL(&dev_pager_object_list, object1,
		    pager_object_list);
		mtx_unlock(&dev_pager_mtx);
		vm_object_deallocate(object1);
	}
	return (object);
}