aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/perf_counter.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 195e976eb07d..c841563de043 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -1461,13 +1461,14 @@ static void perf_mmap_close(struct vm_area_struct *vma)
1461 1461
1462 if (atomic_dec_and_mutex_lock(&counter->mmap_count, 1462 if (atomic_dec_and_mutex_lock(&counter->mmap_count,
1463 &counter->mmap_mutex)) { 1463 &counter->mmap_mutex)) {
1464 vma->vm_mm->locked_vm -= counter->data->nr_pages + 1;
1464 perf_mmap_data_free(counter); 1465 perf_mmap_data_free(counter);
1465 mutex_unlock(&counter->mmap_mutex); 1466 mutex_unlock(&counter->mmap_mutex);
1466 } 1467 }
1467} 1468}
1468 1469
1469static struct vm_operations_struct perf_mmap_vmops = { 1470static struct vm_operations_struct perf_mmap_vmops = {
1470 .open = perf_mmap_open, 1471 .open = perf_mmap_open,
1471 .close = perf_mmap_close, 1472 .close = perf_mmap_close,
1472 .fault = perf_mmap_fault, 1473 .fault = perf_mmap_fault,
1473}; 1474};
@@ -1499,24 +1500,32 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
1499 if (vma->vm_pgoff != 0) 1500 if (vma->vm_pgoff != 0)
1500 return -EINVAL; 1501 return -EINVAL;
1501 1502
1502 locked = vma_size >> PAGE_SHIFT; 1503 mutex_lock(&counter->mmap_mutex);
1503 locked += vma->vm_mm->locked_vm; 1504 if (atomic_inc_not_zero(&counter->mmap_count)) {
1505 if (nr_pages != counter->data->nr_pages)
1506 ret = -EINVAL;
1507 goto unlock;
1508 }
1509
1510 locked = vma->vm_mm->locked_vm;
1511 locked += nr_pages + 1;
1504 1512
1505 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; 1513 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
1506 lock_limit >>= PAGE_SHIFT; 1514 lock_limit >>= PAGE_SHIFT;
1507 1515
1508 if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) 1516 if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
1509 return -EPERM; 1517 ret = -EPERM;
1510 1518 goto unlock;
1511 mutex_lock(&counter->mmap_mutex); 1519 }
1512 if (atomic_inc_not_zero(&counter->mmap_count))
1513 goto out;
1514 1520
1515 WARN_ON(counter->data); 1521 WARN_ON(counter->data);
1516 ret = perf_mmap_data_alloc(counter, nr_pages); 1522 ret = perf_mmap_data_alloc(counter, nr_pages);
1517 if (!ret) 1523 if (ret)
1518 atomic_set(&counter->mmap_count, 1); 1524 goto unlock;
1519out: 1525
1526 atomic_set(&counter->mmap_count, 1);
1527 vma->vm_mm->locked_vm += nr_pages + 1;
1528unlock:
1520 mutex_unlock(&counter->mmap_mutex); 1529 mutex_unlock(&counter->mmap_mutex);
1521 1530
1522 vma->vm_flags &= ~VM_MAYWRITE; 1531 vma->vm_flags &= ~VM_MAYWRITE;