diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-02 19:07:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-02 19:07:27 -0400 |
commit | 092f4c56c1927e4b61a41ee8055005f1cb437009 (patch) | |
tree | 616ceb54b7671ccc13922ae9e002b8b972f6e09e /ipc | |
parent | 80c2861672bbf000f6af838656959ee937e4ee4d (diff) | |
parent | c1e2ee2dc436574880758b3836fc96935b774c32 (diff) |
Merge branch 'akpm' (Andrew's incoming - part two)
Says Andrew:
"60 patches. That's good enough for -rc1 I guess. I have quite a lot
of detritus to be rechecked, work through maintainers, etc.
- most of the remains of MM
- rtc
- various misc
- cgroups
- memcg
- cpusets
- procfs
- ipc
- rapidio
- sysctl
- pps
- w1
- drivers/misc
- aio"
* akpm: (60 commits)
memcg: replace ss->id_lock with a rwlock
aio: allocate kiocbs in batches
drivers/misc/vmw_balloon.c: fix typo in code comment
drivers/misc/vmw_balloon.c: determine page allocation flag can_sleep outside loop
w1: disable irqs in critical section
drivers/w1/w1_int.c: multiple masters used same init_name
drivers/power/ds2780_battery.c: fix deadlock upon insertion and removal
drivers/power/ds2780_battery.c: add a nolock function to w1 interface
drivers/power/ds2780_battery.c: create central point for calling w1 interface
w1: ds2760 and ds2780, use ida for id and ida_simple_get() to get it
pps gpio client: add missing dependency
pps: new client driver using GPIO
pps: default echo function
include/linux/dma-mapping.h: add dma_zalloc_coherent()
sysctl: make CONFIG_SYSCTL_SYSCALL default to n
sysctl: add support for poll()
RapidIO: documentation update
drivers/net/rionet.c: fix ethernet address macros for LE platforms
RapidIO: fix potential null deref in rio_setup_device()
RapidIO: add mport driver for Tsi721 bridge
...
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/sem.c | 56 |
1 files changed, 55 insertions, 1 deletions
@@ -90,6 +90,52 @@ | |||
90 | #include <asm/uaccess.h> | 90 | #include <asm/uaccess.h> |
91 | #include "util.h" | 91 | #include "util.h" |
92 | 92 | ||
93 | /* One semaphore structure for each semaphore in the system. */ | ||
94 | struct sem { | ||
95 | int semval; /* current value */ | ||
96 | int sempid; /* pid of last operation */ | ||
97 | struct list_head sem_pending; /* pending single-sop operations */ | ||
98 | }; | ||
99 | |||
100 | /* One queue for each sleeping process in the system. */ | ||
101 | struct sem_queue { | ||
102 | struct list_head simple_list; /* queue of pending operations */ | ||
103 | struct list_head list; /* queue of pending operations */ | ||
104 | struct task_struct *sleeper; /* this process */ | ||
105 | struct sem_undo *undo; /* undo structure */ | ||
106 | int pid; /* process id of requesting process */ | ||
107 | int status; /* completion status of operation */ | ||
108 | struct sembuf *sops; /* array of pending operations */ | ||
109 | int nsops; /* number of operations */ | ||
110 | int alter; /* does *sops alter the array? */ | ||
111 | }; | ||
112 | |||
113 | /* Each task has a list of undo requests. They are executed automatically | ||
114 | * when the process exits. | ||
115 | */ | ||
116 | struct sem_undo { | ||
117 | struct list_head list_proc; /* per-process list: * | ||
118 | * all undos from one process | ||
119 | * rcu protected */ | ||
120 | struct rcu_head rcu; /* rcu struct for sem_undo */ | ||
121 | struct sem_undo_list *ulp; /* back ptr to sem_undo_list */ | ||
122 | struct list_head list_id; /* per semaphore array list: | ||
123 | * all undos for one array */ | ||
124 | int semid; /* semaphore set identifier */ | ||
125 | short *semadj; /* array of adjustments */ | ||
126 | /* one per semaphore */ | ||
127 | }; | ||
128 | |||
129 | /* sem_undo_list controls shared access to the list of sem_undo structures | ||
130 | * that may be shared among all a CLONE_SYSVSEM task group. | ||
131 | */ | ||
132 | struct sem_undo_list { | ||
133 | atomic_t refcnt; | ||
134 | spinlock_t lock; | ||
135 | struct list_head list_proc; | ||
136 | }; | ||
137 | |||
138 | |||
93 | #define sem_ids(ns) ((ns)->ids[IPC_SEM_IDS]) | 139 | #define sem_ids(ns) ((ns)->ids[IPC_SEM_IDS]) |
94 | 140 | ||
95 | #define sem_unlock(sma) ipc_unlock(&(sma)->sem_perm) | 141 | #define sem_unlock(sma) ipc_unlock(&(sma)->sem_perm) |
@@ -1426,6 +1472,8 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, | |||
1426 | 1472 | ||
1427 | queue.status = -EINTR; | 1473 | queue.status = -EINTR; |
1428 | queue.sleeper = current; | 1474 | queue.sleeper = current; |
1475 | |||
1476 | sleep_again: | ||
1429 | current->state = TASK_INTERRUPTIBLE; | 1477 | current->state = TASK_INTERRUPTIBLE; |
1430 | sem_unlock(sma); | 1478 | sem_unlock(sma); |
1431 | 1479 | ||
@@ -1460,7 +1508,6 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, | |||
1460 | * Array removed? If yes, leave without sem_unlock(). | 1508 | * Array removed? If yes, leave without sem_unlock(). |
1461 | */ | 1509 | */ |
1462 | if (IS_ERR(sma)) { | 1510 | if (IS_ERR(sma)) { |
1463 | error = -EIDRM; | ||
1464 | goto out_free; | 1511 | goto out_free; |
1465 | } | 1512 | } |
1466 | 1513 | ||
@@ -1479,6 +1526,13 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, | |||
1479 | */ | 1526 | */ |
1480 | if (timeout && jiffies_left == 0) | 1527 | if (timeout && jiffies_left == 0) |
1481 | error = -EAGAIN; | 1528 | error = -EAGAIN; |
1529 | |||
1530 | /* | ||
1531 | * If the wakeup was spurious, just retry | ||
1532 | */ | ||
1533 | if (error == -EINTR && !signal_pending(current)) | ||
1534 | goto sleep_again; | ||
1535 | |||
1482 | unlink_queue(sma, &queue); | 1536 | unlink_queue(sma, &queue); |
1483 | 1537 | ||
1484 | out_unlock_free: | 1538 | out_unlock_free: |