[PATCH][ATM] svc's possibly race with sigd

From: chas williams (chas@locutus.cmf.nrl.navy.mil)
Date: Mon May 05 2003 - 17:53:30 EST


pretty sure the author wanted the wait queues in place before
talking to sigd which might cause a wakeup on the vcc in question.
this race is VERY unlikely, since going down to user space and back
is quite slow.

--- linux-2.5.68/net/atm/svc.c.000 Mon May 5 18:31:34 2003
+++ linux-2.5.68/net/atm/svc.c Mon May 5 18:33:04 2003
@@ -64,8 +64,8 @@
 
         DPRINTK("svc_disconnect %p\n",vcc);
         if (test_bit(ATM_VF_REGIS,&vcc->flags)) {
- sigd_enq(vcc,as_close,NULL,NULL,NULL);
                 add_wait_queue(&vcc->sleep,&wait);
+ sigd_enq(vcc,as_close,NULL,NULL,NULL);
                 while (!test_bit(ATM_VF_RELEASED,&vcc->flags) && sigd) {
                         set_current_state(TASK_UNINTERRUPTIBLE);
                         schedule();
@@ -124,8 +124,8 @@
         if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
         vcc->local = *addr;
         vcc->reply = WAITING;
- sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local);
         add_wait_queue(&vcc->sleep,&wait);
+ sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local);
         while (vcc->reply == WAITING && sigd) {
                 set_current_state(TASK_UNINTERRUPTIBLE);
                 schedule();
@@ -169,12 +169,13 @@
                     !vcc->qos.rxtp.traffic_class) return -EINVAL;
                 vcc->remote = *addr;
                 vcc->reply = WAITING;
+ add_wait_queue(&vcc->sleep,&wait);
                 sigd_enq(vcc,as_connect,NULL,NULL,&vcc->remote);
                 if (flags & O_NONBLOCK) {
+ remove_wait_queue(&vcc->sleep,&wait);
                         sock->state = SS_CONNECTING;
                         return -EINPROGRESS;
                 }
- add_wait_queue(&vcc->sleep,&wait);
                 error = 0;
                 while (vcc->reply == WAITING && sigd) {
                         set_current_state(TASK_INTERRUPTIBLE);
@@ -243,8 +244,8 @@
         /* let server handle listen on unbound sockets */
         if (test_bit(ATM_VF_SESSION,&vcc->flags)) return -EINVAL;
         vcc->reply = WAITING;
- sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
         add_wait_queue(&vcc->sleep,&wait);
+ sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
         while (vcc->reply == WAITING && sigd) {
                 set_current_state(TASK_UNINTERRUPTIBLE);
                 schedule();
@@ -313,8 +314,8 @@
                 }
                 /* wait should be short, so we ignore the non-blocking flag */
                 new_vcc->reply = WAITING;
- sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL);
                 add_wait_queue(&new_vcc->sleep,&wait);
+ sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL);
                 while (new_vcc->reply == WAITING && sigd) {
                         set_current_state(TASK_UNINTERRUPTIBLE);
                         schedule();
@@ -347,8 +348,8 @@
         DECLARE_WAITQUEUE(wait,current);
 
         vcc->reply = WAITING;
- sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0);
         add_wait_queue(&vcc->sleep,&wait);
+ sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0);
         while (vcc->reply == WAITING && !test_bit(ATM_VF_RELEASED,&vcc->flags)
             && sigd) {
                 set_current_state(TASK_UNINTERRUPTIBLE);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed May 07 2003 - 22:00:23 EST