Re: regression introduced on v2.6.30-rc1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Marcel,

On Sun, Jun 21, 2009 at 4:04 PM, Marcel Holtmann<marcel@xxxxxxxxxxxx> wrote:
> stupid specification. It is just bloody stupid that we have to cleanup
> someone else's stuff that we haven't initiated in the first place :(
>
> diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
> index 374536e..864c3c4 100644
> --- a/net/bluetooth/rfcomm/core.c
> +++ b/net/bluetooth/rfcomm/core.c
> @@ -466,6 +466,11 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
>
>                skb_queue_purge(&d->tx_queue);
>                rfcomm_dlc_unlink(d);
> +
> +               /* Specification demands to cleanup after remote
> +                * initiated session when closing last DLC */
> +               if (list_empty(&s->dlcs))
> +                       rfcomm_session_put(s);
>        }


As your patch seems to trigger DISC 0 in both sides when the remote
stack cope with DM I would suggest introducing a timer_list to
rfcomm_session so we can give some time to remote stack to take down
dlci 0 clean it up otherwise.


@@ -244,6 +246,33 @@ static inline int rfcomm_check_security(struct
rfcomm_dlc *d)
 								auth_type);
 }

+static void rfcomm_session_timeout(unsigned long arg)
+{
+	struct rfcomm_session *s = (void *) arg;
+
+	BT_DBG("session %p state %ld", s, s->state);
+
+	set_bit(RFCOMM_TIMED_OUT, &s->flags);
+	rfcomm_session_put(s);
+	rfcomm_schedule(RFCOMM_SCHED_TIMEO);
+}
+
+static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout)
+{
+	BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout);
+
+	if (!mod_timer(&s->timer, jiffies + timeout))
+		rfcomm_session_hold(s);
+}
+
+static void rfcomm_session_clear_timer(struct rfcomm_session *s)
+{
+	BT_DBG("session %p state %ld", s, s->state);
+
+	if (timer_pending(&s->timer) && del_timer(&s->timer))
+		rfcomm_session_put(s);
+}
+
 /* ---- RFCOMM DLCs ---- */
 static void rfcomm_dlc_timeout(unsigned long arg)
 {
@@ -320,6 +349,7 @@ static void rfcomm_dlc_link(struct rfcomm_session
*s, struct rfcomm_dlc *d)

 	rfcomm_session_hold(s);

+	rfcomm_session_clear_timer(s);
 	rfcomm_dlc_hold(d);
 	list_add(&d->list, &s->dlcs);
 	d->session = s;
@@ -335,6 +365,9 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
 	d->session = NULL;
 	rfcomm_dlc_put(d);

+	if (list_empty(&s->dlcs))
+		rfcomm_session_set_timer(s, RFCOMM_DISC_TIMEOUT);
+
 	rfcomm_session_put(s);
 }

@@ -454,6 +487,7 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
 			rfcomm_schedule(RFCOMM_SCHED_AUTH);
 			break;
 		}
+
 		/* Fall through */

 	default:
@@ -567,6 +601,8 @@ static struct rfcomm_session
*rfcomm_session_add(struct socket *sock, int state)

 	BT_DBG("session %p sock %p", s, sock);

+	setup_timer(&s->timer, rfcomm_session_timeout, (unsigned long)s);
+
 	INIT_LIST_HEAD(&s->dlcs);
 	s->state = state;
 	s->sock  = sock;
@@ -639,6 +675,7 @@ static void rfcomm_session_close(struct
rfcomm_session *s, int err)
 		__rfcomm_dlc_close(d, err);
 	}

+	rfcomm_session_clear_timer(s);
 	rfcomm_session_put(s);
 }

@@ -1774,6 +1811,7 @@ static inline void rfcomm_process_dlcs(struct
rfcomm_session *s)
 				rfcomm_send_dm(s, d->dlci);
 			else
 				d->state = BT_CLOSED;
+
 			__rfcomm_dlc_close(d, ECONNREFUSED);
 			continue;
 		}
@@ -1879,6 +1917,11 @@ static inline void rfcomm_process_sessions(void)
 		struct rfcomm_session *s;
 		s = list_entry(p, struct rfcomm_session, list);

+		if (test_bit(RFCOMM_TIMED_OUT, &s->flags)) {
+			rfcomm_session_put(s);
+			continue;
+		}
+
 		if (s->state == BT_LISTEN) {
 			rfcomm_accept_connection(s);
 			continue;


-- 
Luiz Augusto von Dentz
Engenheiro de Computação
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux