xref: /dragonfly/sys/dev/drm/linux_shmem.c (revision a85cb24f)
11964046dSFrançois Tigeot /*-
21964046dSFrançois Tigeot  * Copyright (c) 2011 The FreeBSD Foundation
3*a85cb24fSFrançois Tigeot  * Copyright (c) 2014-2020 François Tigeot <ftigeot@wolfpond.org>
41964046dSFrançois Tigeot  * All rights reserved.
51964046dSFrançois Tigeot  *
61964046dSFrançois Tigeot  * Portions of this software were developed by Konstantin Belousov
71964046dSFrançois Tigeot  * under sponsorship from the FreeBSD Foundation.
81964046dSFrançois Tigeot  *
91964046dSFrançois Tigeot  * Redistribution and use in source and binary forms, with or without
101964046dSFrançois Tigeot  * modification, are permitted provided that the following conditions
111964046dSFrançois Tigeot  * are met:
121964046dSFrançois Tigeot  * 1. Redistributions of source code must retain the above copyright
131964046dSFrançois Tigeot  *    notice, this list of conditions and the following disclaimer.
141964046dSFrançois Tigeot  * 2. Redistributions in binary form must reproduce the above copyright
151964046dSFrançois Tigeot  *    notice, this list of conditions and the following disclaimer in the
161964046dSFrançois Tigeot  *    documentation and/or other materials provided with the distribution.
171964046dSFrançois Tigeot  *
181964046dSFrançois Tigeot  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
191964046dSFrançois Tigeot  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
201964046dSFrançois Tigeot  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
211964046dSFrançois Tigeot  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
221964046dSFrançois Tigeot  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
231964046dSFrançois Tigeot  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
241964046dSFrançois Tigeot  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
251964046dSFrançois Tigeot  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
261964046dSFrançois Tigeot  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
271964046dSFrançois Tigeot  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
281964046dSFrançois Tigeot  * SUCH DAMAGE.
291964046dSFrançois Tigeot  *
301964046dSFrançois Tigeot  */
311964046dSFrançois Tigeot 
321964046dSFrançois Tigeot #include <vm/vm.h>
331964046dSFrançois Tigeot #include <vm/vm_page.h>
341964046dSFrançois Tigeot #include <vm/vm_page2.h>
351964046dSFrançois Tigeot #include <vm/vm_pager.h>
361964046dSFrançois Tigeot 
371964046dSFrançois Tigeot #include <linux/err.h>
381964046dSFrançois Tigeot #include <linux/shmem_fs.h>
391964046dSFrançois Tigeot 
40f0bba3d1SFrançois Tigeot struct page *
411964046dSFrançois Tigeot shmem_read_mapping_page(vm_object_t object, vm_pindex_t pindex)
421964046dSFrançois Tigeot {
431964046dSFrançois Tigeot 	vm_page_t m;
441964046dSFrançois Tigeot 	int rv;
451964046dSFrançois Tigeot 
461964046dSFrançois Tigeot 	VM_OBJECT_LOCK_ASSERT_OWNED(object);
471964046dSFrançois Tigeot 	m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
481964046dSFrançois Tigeot 	if (m->valid != VM_PAGE_BITS_ALL) {
491964046dSFrançois Tigeot 		if (vm_pager_has_page(object, pindex)) {
501964046dSFrançois Tigeot 			rv = vm_pager_get_page(object, &m, 1);
511964046dSFrançois Tigeot 			m = vm_page_lookup(object, pindex);
521964046dSFrançois Tigeot 			if (m == NULL)
531964046dSFrançois Tigeot 				return ERR_PTR(-ENOMEM);
541964046dSFrançois Tigeot 			if (rv != VM_PAGER_OK) {
551964046dSFrançois Tigeot 				vm_page_free(m);
561964046dSFrançois Tigeot 				return ERR_PTR(-ENOMEM);
571964046dSFrançois Tigeot 			}
581964046dSFrançois Tigeot 		} else {
591964046dSFrançois Tigeot 			pmap_zero_page(VM_PAGE_TO_PHYS(m));
601964046dSFrançois Tigeot 			m->valid = VM_PAGE_BITS_ALL;
611964046dSFrançois Tigeot 			m->dirty = 0;
621964046dSFrançois Tigeot 		}
631964046dSFrançois Tigeot 	}
641964046dSFrançois Tigeot 	vm_page_wire(m);
651964046dSFrançois Tigeot 	vm_page_wakeup(m);
66f0bba3d1SFrançois Tigeot 	return (struct page *)m;
671964046dSFrançois Tigeot }
68*a85cb24fSFrançois Tigeot 
69*a85cb24fSFrançois Tigeot struct page *
70*a85cb24fSFrançois Tigeot shmem_read_mapping_page_gfp(struct vm_object *mapping,
71*a85cb24fSFrançois Tigeot     pgoff_t index, gfp_t gfp_mask)
72*a85cb24fSFrançois Tigeot {
73*a85cb24fSFrançois Tigeot 	return shmem_read_mapping_page(mapping, index);
74*a85cb24fSFrançois Tigeot }
75