vm: object: add prefetch function to fetch missing pages
This commit is contained in:
+41
-9
@@ -58,20 +58,31 @@ kern_status_t sys_vm_object_read(
|
||||
|
||||
struct object *obj = NULL;
|
||||
handle_flags_t flags = 0;
|
||||
unsigned long irq_flags = 0;
|
||||
task_lock_irqsave(self, &irq_flags);
|
||||
kern_status_t status = task_resolve_handle(self, object, &obj, &flags);
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
put_current_task(self);
|
||||
|
||||
if (status != KERN_OK) {
|
||||
put_current_task(self);
|
||||
return status;
|
||||
}
|
||||
|
||||
struct vm_object *vmo = vm_object_cast(obj);
|
||||
if (!vmo) {
|
||||
put_current_task(self);
|
||||
object_unref(obj);
|
||||
return KERN_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = vm_object_read(vmo, dst, offset, count, nr_read);
|
||||
put_current_task(self);
|
||||
vm_object_lock_irqsave(vmo, &irq_flags);
|
||||
status = vm_object_prefetch(vmo, offset, count, &irq_flags);
|
||||
if (status == KERN_OK) {
|
||||
status = vm_object_read(vmo, dst, offset, count, nr_read);
|
||||
}
|
||||
|
||||
vm_object_unlock_irqrestore(vmo, irq_flags);
|
||||
object_unref(obj);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -97,20 +108,25 @@ kern_status_t sys_vm_object_write(
|
||||
|
||||
struct object *obj = NULL;
|
||||
handle_flags_t flags = 0;
|
||||
unsigned long irq_flags = 0;
|
||||
task_lock_irqsave(self, &irq_flags);
|
||||
kern_status_t status = task_resolve_handle(self, object, &obj, &flags);
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
put_current_task(self);
|
||||
|
||||
if (status != KERN_OK) {
|
||||
put_current_task(self);
|
||||
return status;
|
||||
}
|
||||
|
||||
struct vm_object *vmo = vm_object_cast(obj);
|
||||
if (!vmo) {
|
||||
put_current_task(self);
|
||||
return KERN_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
vm_object_lock_irqsave(vmo, &irq_flags);
|
||||
status = vm_object_write(vmo, src, offset, count, nr_written);
|
||||
put_current_task(self);
|
||||
vm_object_unlock_irqrestore(vmo, irq_flags);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -162,13 +178,28 @@ kern_status_t sys_vm_object_copy(
|
||||
put_current_task(self);
|
||||
|
||||
struct vm_object *dst_vmo = vm_object_cast(dst_obj);
|
||||
if (!dst_vmo) {
|
||||
return KERN_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
struct vm_object *src_vmo = vm_object_cast(src_obj);
|
||||
if (!dst_vmo || !src_vmo) {
|
||||
object_unref(src_obj);
|
||||
if (!src_vmo) {
|
||||
object_unref(dst_obj);
|
||||
return KERN_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
unsigned long irq_flags = 0;
|
||||
vm_object_lock_irqsave(src_vmo, &irq_flags);
|
||||
status = vm_object_prefetch(src_vmo, src_offset, count, &irq_flags);
|
||||
vm_object_unlock_irqrestore(src_vmo, irq_flags);
|
||||
|
||||
if (status != KERN_OK) {
|
||||
object_unref(src_obj);
|
||||
object_unref(dst_obj);
|
||||
return status;
|
||||
}
|
||||
|
||||
vm_object_lock_pair_irqsave(src_vmo, dst_vmo, &irq_flags);
|
||||
status = vm_object_copy(
|
||||
dst_vmo,
|
||||
dst_offset,
|
||||
@@ -176,6 +207,7 @@ kern_status_t sys_vm_object_copy(
|
||||
src_offset,
|
||||
count,
|
||||
nr_copied);
|
||||
vm_object_unlock_pair_irqrestore(src_vmo, dst_vmo, irq_flags);
|
||||
|
||||
object_unref(src_obj);
|
||||
object_unref(dst_obj);
|
||||
|
||||
Reference in New Issue
Block a user