Re: [PATCH] [RFC] Fix HDP-related segfault upon device recreation

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

 



Hi Elvis,

2010/11/10 Elvis Pfützenreuter <epx@xxxxxxxxxxx>:
> When device is removed and paired again, hdp_device is destroyed
> but a cached mcap_mcl may retain a pointer in mcl->cb->user_data.
> This patch ensures that such MCL is destroyed.
>
> There is probably a better solution to this e.g. changing cache
> strategy for accepted connections. A loop can be removed if 1:1
> relationship between hdp_device and MCL is guaranteed.
> ---
>  health/hdp.c      |    1 +
>  health/mcap.c     |   23 ++++++++++++++++++++++-
>  health/mcap_lib.h |    2 ++
>  3 files changed, 25 insertions(+), 1 deletions(-)
>
> diff --git a/health/hdp.c b/health/hdp.c
> index b141fe7..44ebe75 100644
> --- a/health/hdp.c
> +++ b/health/hdp.c
> @@ -277,6 +277,7 @@ static void free_health_device(struct hdp_device *device)
>        }
>
>        device_unref_mcl(device);
> +       mcap_invalidate_by_user_data(device->hdp_adapter->mi, device);
>
>        g_free(device);
>  }
> diff --git a/health/mcap.c b/health/mcap.c
> index cb7b74c..34ccdaa 100644
> --- a/health/mcap.c
> +++ b/health/mcap.c
> @@ -938,6 +938,27 @@ gboolean mcap_mcl_set_cb(struct mcap_mcl *mcl, gpointer user_data,
>        return TRUE;
>  }
>
> +static gint cmp_mcl_user_data(gconstpointer a, gconstpointer b)
> +{
> +       const struct mcap_mcl *mcl = a;
> +       gconstpointer user_data = b;
> +
> +       if (mcl->cb)
> +               if (mcl->cb->user_data == user_data)
> +                       return 0;
> +
> +       return 1;
> +}
> +
> +void mcap_invalidate_by_user_data(struct mcap_instance *mi, gpointer user_data)
> +{
> +       GSList *l;
> +
> +       while ((l = g_slist_find_custom(mi->cached, user_data,
> +                                               cmp_mcl_user_data)))
> +               mcap_close_mcl(l->data, FALSE);
> +}
> +
>  void mcap_mcl_get_addr(struct mcap_mcl *mcl, bdaddr_t *addr)
>  {
>        bacpy(addr, &mcl->addr);
> @@ -2143,4 +2164,4 @@ gboolean mcap_set_data_chan_mode(struct mcap_instance *mi, uint8_t mode,
>
>        return bt_io_set(mi->dcio, BT_IO_L2CAP, err, BT_IO_OPT_MODE, mode,
>                                                        BT_IO_OPT_INVALID);
> -}
> \ No newline at end of file
> +}
> diff --git a/health/mcap_lib.h b/health/mcap_lib.h
> index 7740623..cc10c17 100644
> --- a/health/mcap_lib.h
> +++ b/health/mcap_lib.h
> @@ -172,6 +172,8 @@ void mcap_mcl_get_addr(struct mcap_mcl *mcl, bdaddr_t *addr);
>  struct mcap_mcl *mcap_mcl_ref(struct mcap_mcl *mcl);
>  void mcap_mcl_unref(struct mcap_mcl *mcl);
>
> +void mcap_invalidate_by_user_data(struct mcap_instance *mi, gpointer user_data);
> +
>  /* CSP operations */
>
>  void mcap_enable_csp(struct mcap_instance *ms);

I'm not sure if this is the best way to face this issue. It seems that
this solution is a workaround to avoid the real problem. Let me have a
look and search for a better solution.

Regards.
--
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