ring-buffer: Do not poll non allocated cpu buffers
[platform/adaptation/renesas_rcar/renesas_kernel.git] / ipc / sem.c
index 8486a5b..a7e40ed 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -796,6 +796,13 @@ static int count_semncnt (struct sem_array * sma, ushort semnum)
        struct sem_queue * q;
 
        semncnt = 0;
+       list_for_each_entry(q, &sma->sem_base[semnum].sem_pending, list) {
+               struct sembuf * sops = q->sops;
+               BUG_ON(sops->sem_num != semnum);
+               if ((sops->sem_op < 0) && !(sops->sem_flg & IPC_NOWAIT))
+                       semncnt++;
+       }
+
        list_for_each_entry(q, &sma->sem_pending, list) {
                struct sembuf * sops = q->sops;
                int nsops = q->nsops;
@@ -815,6 +822,13 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
        struct sem_queue * q;
 
        semzcnt = 0;
+       list_for_each_entry(q, &sma->sem_base[semnum].sem_pending, list) {
+               struct sembuf * sops = q->sops;
+               BUG_ON(sops->sem_num != semnum);
+               if ((sops->sem_op == 0) && !(sops->sem_flg & IPC_NOWAIT))
+                       semzcnt++;
+       }
+
        list_for_each_entry(q, &sma->sem_pending, list) {
                struct sembuf * sops = q->sops;
                int nsops = q->nsops;
@@ -948,8 +962,8 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
 
                memset(&tbuf, 0, sizeof(tbuf));
 
+               rcu_read_lock();
                if (cmd == SEM_STAT) {
-                       rcu_read_lock();
                        sma = sem_obtain_object(ns, semid);
                        if (IS_ERR(sma)) {
                                err = PTR_ERR(sma);
@@ -957,7 +971,6 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
                        }
                        id = sma->sem_perm.id;
                } else {
-                       rcu_read_lock();
                        sma = sem_obtain_object_check(ns, semid);
                        if (IS_ERR(sma)) {
                                err = PTR_ERR(sma);
@@ -1077,17 +1090,12 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
        nsems = sma->sem_nsems;
 
        err = -EACCES;
-       if (ipcperms(ns, &sma->sem_perm,
-                       cmd == SETALL ? S_IWUGO : S_IRUGO)) {
-               rcu_read_unlock();
-               goto out_wakeup;
-       }
+       if (ipcperms(ns, &sma->sem_perm, cmd == SETALL ? S_IWUGO : S_IRUGO))
+               goto out_rcu_wakeup;
 
        err = security_sem_semctl(sma, cmd);
-       if (err) {
-               rcu_read_unlock();
-               goto out_wakeup;
-       }
+       if (err)
+               goto out_rcu_wakeup;
 
        err = -EACCES;
        switch (cmd) {
@@ -1188,10 +1196,8 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
        /* GETVAL, GETPID, GETNCTN, GETZCNT: fall-through */
        }
        err = -EINVAL;
-       if (semnum < 0 || semnum >= nsems) {
-               rcu_read_unlock();
-               goto out_wakeup;
-       }
+       if (semnum < 0 || semnum >= nsems)
+               goto out_rcu_wakeup;
 
        sem_lock(sma, NULL, -1);
        curr = &sma->sem_base[semnum];
@@ -1213,8 +1219,8 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
 
 out_unlock:
        sem_unlock(sma, -1);
+out_rcu_wakeup:
        rcu_read_unlock();
-out_wakeup:
        wake_up_sem_queue_do(&tasks);
 out_free:
        if(sem_io != fast_sem_io)
@@ -1585,22 +1591,16 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
        }
 
        error = -EFBIG;
-       if (max >= sma->sem_nsems) {
-               rcu_read_unlock();
-               goto out_wakeup;
-       }
+       if (max >= sma->sem_nsems)
+               goto out_rcu_wakeup;
 
        error = -EACCES;
-       if (ipcperms(ns, &sma->sem_perm, alter ? S_IWUGO : S_IRUGO)) {
-               rcu_read_unlock();
-               goto out_wakeup;
-       }
+       if (ipcperms(ns, &sma->sem_perm, alter ? S_IWUGO : S_IRUGO))
+               goto out_rcu_wakeup;
 
        error = security_sem_semop(sma, sops, nsops, alter);
-       if (error) {
-               rcu_read_unlock();
-               goto out_wakeup;
-       }
+       if (error)
+               goto out_rcu_wakeup;
 
        /*
         * semid identifiers are not unique - find_alloc_undo may have
@@ -1718,8 +1718,8 @@ sleep_again:
 
 out_unlock_free:
        sem_unlock(sma, locknum);
+out_rcu_wakeup:
        rcu_read_unlock();
-out_wakeup:
        wake_up_sem_queue_do(&tasks);
 out_free:
        if(sops != fast_sops)