All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Fixes potential lockup while finding latency
@ 2010-09-21 16:45 Elvis Pfützenreuter
  2010-09-21 18:09 ` Johan Hedberg
  0 siblings, 1 reply; 2+ messages in thread
From: Elvis Pfützenreuter @ 2010-09-21 16:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: epx

(To be applied after Jose reorganization patch)

This patch fixes a potential infinite loop while finding the
BT/system clock read latency. If the adapter is removed exactly
at that moment, BT clock simply can't be read and it must quit.
This is handled as a temporary failure (if a new connection is
made, adapter is probably in place again).
---
 health/mcap_sync.c |   46 ++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/health/mcap_sync.c b/health/mcap_sync.c
index 0943e41..670260b 100644
--- a/health/mcap_sync.c
+++ b/health/mcap_sync.c
@@ -360,7 +360,7 @@ uint32_t mcap_get_btclock(struct mcap_mcl *mcl)
 	return btclock;
 }
 
-static void initialize_caps(struct mcap_mcl *mcl)
+static gboolean initialize_caps(struct mcap_mcl *mcl)
 {
 	struct timespec t1, t2;
 	int latencies[20];
@@ -368,6 +368,7 @@ static void initialize_caps(struct mcap_mcl *mcl)
 	uint32_t btclock;
 	uint16_t btaccuracy;
 	int i;
+	int retries;
 
 	clock_getres(CLK, &t1);
 
@@ -383,10 +384,12 @@ static void initialize_caps(struct mcap_mcl *mcl)
 
 	/* Do clock read a number of times and measure latency */
 	avg = 0;
-	for (i = 0; i < 20; ++i) {
+	retries = 10;
+	for (i = 0; i < 20 && retries > 0; ++i) {
 		clock_gettime(CLK, &t1);
 		if (!read_btclock(mcl, &btclock, &btaccuracy)) {
 			--i;
+			--retries;
 			continue;
 		}
 		clock_gettime(CLK, &t2);
@@ -395,9 +398,12 @@ static void initialize_caps(struct mcap_mcl *mcl)
 		latencies[i] = latency;
 		avg += latency;
 	}
-	avg /= 20;
 
-	/* Calculate deviation */
+	if (retries <= 0)
+		return FALSE;
+
+	/* Calculate average and deviation */
+	avg /= 20;
 	dev = 0;
 	for (i = 0; i < 20; ++i)
 		dev += abs(latencies[i] - avg);
@@ -418,12 +424,16 @@ static void initialize_caps(struct mcap_mcl *mcl)
 	_caps.syncleadtime_ms = latency * 50 / 1000;
 
 	csp_caps_initialized = TRUE;
+	return TRUE;
 }
 
 static struct csp_caps *caps(struct mcap_mcl *mcl)
 {
 	if (!csp_caps_initialized)
-		initialize_caps(mcl);
+		if (!initialize_caps(mcl)) {
+			/* Temporary failure in reading BT clock */
+			return NULL;
+		}
 
 	return &_caps;
 }
@@ -465,6 +475,12 @@ static void proc_sync_cap_req(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
 		return;
 	}
 
+	if (!caps(mcl)) {
+		send_sync_cap_rsp(mcl, MCAP_RESOURCE_UNAVAILABLE,
+					0, 0, 0, 0);
+		return;
+	}
+
 	req = (mcap_md_sync_cap_req *) cmd;
 	required_accuracy = ntohs(req->timest);
 	our_accuracy = caps(mcl)->ts_acc;
@@ -514,11 +530,16 @@ static gboolean get_all_clocks(struct mcap_mcl *mcl, uint32_t *btclock,
 				struct timespec *base_time,
 				uint64_t *timestamp)
 {
-	int latency = caps(mcl)->preempt_thresh + 1;
+	int latency;
 	int retry = 5;
 	uint16_t btres;
 	struct timespec t0;
 
+	if (!caps(mcl))
+		return FALSE;
+
+	latency = caps(mcl)->preempt_thresh + 1;
+
 	while (latency > caps(mcl)->preempt_thresh && --retry >= 0) {
 
 		clock_gettime(CLK, &t0);
@@ -553,6 +574,9 @@ static gboolean sync_send_indication(gpointer user_data)
 
 	mcl = user_data;
 
+	if (!caps(mcl))
+		return FALSE;
+
 	if (!get_all_clocks(mcl, &btclock, &base_time, &tmstamp))
 		return FALSE;
 
@@ -600,6 +624,11 @@ static gboolean proc_sync_set_req_phase2(gpointer user_data)
 	ind_freq = data->ind_freq;
 	role = data->role;
 
+	if (!caps(mcl)) {
+		send_sync_set_rsp(mcl, MCAP_UNSPECIFIED_ERROR, 0, 0, 0);
+		return FALSE;
+	}
+
 	if (!get_all_clocks(mcl, &btclock, &base_time, &tmstamp)) {
 		send_sync_set_rsp(mcl, MCAP_UNSPECIFIED_ERROR, 0, 0, 0);
 		return FALSE;
@@ -688,6 +717,11 @@ static void proc_sync_set_req(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
 		return;
 	}
 
+	if (!caps(mcl)) {
+		send_sync_set_rsp(mcl, MCAP_UNSPECIFIED_ERROR, 0, 0, 0);
+		return;
+	}
+
 	if (!read_btclock_retry(mcl, &cur_btclock, &btres)) {
 		send_sync_set_rsp(mcl, MCAP_UNSPECIFIED_ERROR, 0, 0, 0);
 		return;
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fixes potential lockup while finding latency
  2010-09-21 16:45 [PATCH] Fixes potential lockup while finding latency Elvis Pfützenreuter
@ 2010-09-21 18:09 ` Johan Hedberg
  0 siblings, 0 replies; 2+ messages in thread
From: Johan Hedberg @ 2010-09-21 18:09 UTC (permalink / raw)
  To: Elvis Pfützenreuter; +Cc: linux-bluetooth

Hi Elvis,

On Tue, Sep 21, 2010, Elvis Pfützenreuter wrote:
> (To be applied after Jose reorganization patch)
> 
> This patch fixes a potential infinite loop while finding the
> BT/system clock read latency. If the adapter is removed exactly
> at that moment, BT clock simply can't be read and it must quit.
> This is handled as a temporary failure (if a new connection is
> made, adapter is probably in place again).
> ---
>  health/mcap_sync.c |   46 ++++++++++++++++++++++++++++++++++++++++------
>  1 files changed, 40 insertions(+), 6 deletions(-)

Thanks. This patch has also been pushed upstream. In the future please
use the format "Fix ..." instead of "Fixes ..." in the summary message
to be consistent with the rest of the commit history. I changed it
manually this time before pushing upstream.

Johan

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-09-21 18:09 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-21 16:45 [PATCH] Fixes potential lockup while finding latency Elvis Pfützenreuter
2010-09-21 18:09 ` Johan Hedberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.