Re: [PATCH 1/2] net: adding memory barrier to the poll and receive callbacks
From: Davide Libenzi <hidden>
Date: 2009-06-29 15:37:10
Also in:
lkml
On Mon, 29 Jun 2009, Jiri Olsa wrote:
-static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
+static inline void __poll_wait(struct file *filp,
+ wait_queue_head_t *wait_address, poll_table *p)
+{
+ p->qproc(filp, wait_address, p);
+}
+
+static inline void poll_wait(struct file *filp,
+ wait_queue_head_t *wait_address, poll_table *p)
{
if (p && wait_address)
- p->qproc(filp, wait_address, p);
+ __poll_wait(filp, wait_address, p);
}+static inline void sock_poll_wait(struct file *filp, struct sock *sk,
+ poll_table *p)
+{
+ if (p && sk->sk_sleep) {
+ __poll_wait(filp, sk->sk_sleep, p);
+ /*
+ * We need to be sure we are in sync with the
+ * socket flags modification.
+ *
+ * This memory barrier is paired in the sk_has_sleeper.
+ */
+ smp_mb();
+ }
+}
I think Oleg already said this, but you can use directly poll_wait()
without adding another abstraction, and the compiler will drop the double
check for you:
extern void foo(int, int, int);
extern void mb(void);
static inline void cfoo(int a, int b, int c) {
if (b && c)
foo(a, b, c);
}
void xxx(int a, int b, int c) {
if (b && c) {
cfoo(a, b, c);
mb();
}
}
-----
xxx:
subq $8, %rsp
testl %esi, %esi
je .L3
testl %edx, %edx
je .L3
call foo
addq $8, %rsp
jmp mb
.L3:
addq $8, %rsp
ret
- Davide