Merge "net: qrtr: Fix duplicate server announcement in qrtr"
This commit is contained in:
commit
fa7e8805be
@ -743,15 +743,23 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
|
|||||||
size_t len = skb->len;
|
size_t len = skb->len;
|
||||||
int rc, confirm_rx;
|
int rc, confirm_rx;
|
||||||
|
|
||||||
|
mutex_lock(&node->ep_lock);
|
||||||
if (!atomic_read(&node->hello_sent) && type != QRTR_TYPE_HELLO) {
|
if (!atomic_read(&node->hello_sent) && type != QRTR_TYPE_HELLO) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
mutex_unlock(&node->ep_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (atomic_read(&node->hello_sent) && type == QRTR_TYPE_HELLO) {
|
if (atomic_read(&node->hello_sent) && type == QRTR_TYPE_HELLO) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
mutex_unlock(&node->ep_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!atomic_read(&node->hello_sent) && type == QRTR_TYPE_HELLO)
|
||||||
|
atomic_inc(&node->hello_sent);
|
||||||
|
|
||||||
|
mutex_unlock(&node->ep_lock);
|
||||||
|
|
||||||
/* If sk is null, this is a forwarded packet and should not wait */
|
/* If sk is null, this is a forwarded packet and should not wait */
|
||||||
if (!skb->sk) {
|
if (!skb->sk) {
|
||||||
struct qrtr_cb *cb = (struct qrtr_cb *)skb->cb;
|
struct qrtr_cb *cb = (struct qrtr_cb *)skb->cb;
|
||||||
@ -788,9 +796,10 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
|
|||||||
else
|
else
|
||||||
rc = skb_put_padto(skb, ALIGN(len, 4) + sizeof(*hdr));
|
rc = skb_put_padto(skb, ALIGN(len, 4) + sizeof(*hdr));
|
||||||
|
|
||||||
if (rc)
|
if (rc) {
|
||||||
pr_err("%s: failed to pad size %lu to %lu rc:%d\n", __func__,
|
pr_err("%s: failed to pad size %lu to %lu rc:%d\n", __func__,
|
||||||
skb->len, ALIGN(skb->len, 4), rc);
|
skb->len, ALIGN(skb->len, 4), rc);
|
||||||
|
}
|
||||||
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
mutex_lock(&node->ep_lock);
|
mutex_lock(&node->ep_lock);
|
||||||
@ -805,11 +814,9 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
|
|||||||
* confirm_rx flag if we dropped this one */
|
* confirm_rx flag if we dropped this one */
|
||||||
if (rc && confirm_rx)
|
if (rc && confirm_rx)
|
||||||
qrtr_tx_flow_failed(node, to->sq_node, to->sq_port);
|
qrtr_tx_flow_failed(node, to->sq_node, to->sq_port);
|
||||||
if (type == QRTR_TYPE_HELLO) {
|
if (rc && type == QRTR_TYPE_HELLO) {
|
||||||
if (!rc)
|
atomic_dec(&node->hello_sent);
|
||||||
atomic_inc(&node->hello_sent);
|
kthread_queue_work(&node->kworker, &node->say_hello);
|
||||||
else
|
|
||||||
kthread_queue_work(&node->kworker, &node->say_hello);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@ -1391,6 +1398,7 @@ static void qrtr_fwd_del_proc(struct qrtr_node *src, unsigned int nid)
|
|||||||
struct qrtr_node *dst;
|
struct qrtr_node *dst;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
|
down_read(&qrtr_epts_lock);
|
||||||
list_for_each_entry(dst, &qrtr_all_epts, item) {
|
list_for_each_entry(dst, &qrtr_all_epts, item) {
|
||||||
if (!qrtr_must_forward(src, dst, QRTR_TYPE_DEL_PROC))
|
if (!qrtr_must_forward(src, dst, QRTR_TYPE_DEL_PROC))
|
||||||
continue;
|
continue;
|
||||||
@ -1408,6 +1416,7 @@ static void qrtr_fwd_del_proc(struct qrtr_node *src, unsigned int nid)
|
|||||||
to.sq_node = dst->nid;
|
to.sq_node = dst->nid;
|
||||||
qrtr_node_enqueue(dst, skb, QRTR_TYPE_DEL_PROC, &from, &to, 0);
|
qrtr_node_enqueue(dst, skb, QRTR_TYPE_DEL_PROC, &from, &to, 0);
|
||||||
}
|
}
|
||||||
|
up_read(&qrtr_epts_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1637,17 +1646,6 @@ static int __qrtr_bind(struct socket *sock,
|
|||||||
qrtr_reset_ports();
|
qrtr_reset_ports();
|
||||||
spin_unlock_irqrestore(&qrtr_port_lock, flags);
|
spin_unlock_irqrestore(&qrtr_port_lock, flags);
|
||||||
|
|
||||||
if (port == QRTR_PORT_CTRL) {
|
|
||||||
struct qrtr_node *node;
|
|
||||||
|
|
||||||
down_write(&qrtr_epts_lock);
|
|
||||||
list_for_each_entry(node, &qrtr_all_epts, item) {
|
|
||||||
atomic_set(&node->hello_sent, 0);
|
|
||||||
atomic_set(&node->hello_rcvd, 0);
|
|
||||||
}
|
|
||||||
up_write(&qrtr_epts_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unbind previous, if any */
|
/* unbind previous, if any */
|
||||||
if (!zapped)
|
if (!zapped)
|
||||||
qrtr_port_remove(ipc);
|
qrtr_port_remove(ipc);
|
||||||
@ -2123,6 +2121,18 @@ static int qrtr_release(struct socket *sock)
|
|||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
|
||||||
ipc = qrtr_sk(sk);
|
ipc = qrtr_sk(sk);
|
||||||
|
|
||||||
|
if (ipc->us.sq_port == QRTR_PORT_CTRL) {
|
||||||
|
struct qrtr_node *node;
|
||||||
|
|
||||||
|
down_write(&qrtr_epts_lock);
|
||||||
|
list_for_each_entry(node, &qrtr_all_epts, item) {
|
||||||
|
atomic_set(&node->hello_sent, 0);
|
||||||
|
atomic_set(&node->hello_rcvd, 0);
|
||||||
|
}
|
||||||
|
up_write(&qrtr_epts_lock);
|
||||||
|
}
|
||||||
|
|
||||||
sk->sk_shutdown = SHUTDOWN_MASK;
|
sk->sk_shutdown = SHUTDOWN_MASK;
|
||||||
if (!sock_flag(sk, SOCK_DEAD))
|
if (!sock_flag(sk, SOCK_DEAD))
|
||||||
sk->sk_state_change(sk);
|
sk->sk_state_change(sk);
|
||||||
|
@ -64,6 +64,7 @@ struct gunyah_pipe {
|
|||||||
* @label: label for gunyah resources
|
* @label: label for gunyah resources
|
||||||
* @tx_dbl: doorbell for tx notifications.
|
* @tx_dbl: doorbell for tx notifications.
|
||||||
* @rx_dbl: doorbell for rx notifications.
|
* @rx_dbl: doorbell for rx notifications.
|
||||||
|
* @dbl_lock: lock to prevent read races.
|
||||||
* @tx_pipe: TX gunyah specific info.
|
* @tx_pipe: TX gunyah specific info.
|
||||||
* @rx_pipe: RX gunyah specific info.
|
* @rx_pipe: RX gunyah specific info.
|
||||||
*/
|
*/
|
||||||
@ -84,6 +85,8 @@ struct qrtr_gunyah_dev {
|
|||||||
void *tx_dbl;
|
void *tx_dbl;
|
||||||
void *rx_dbl;
|
void *rx_dbl;
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
|
/* lock to protect dbl_running */
|
||||||
|
spinlock_t dbl_lock;
|
||||||
|
|
||||||
struct gunyah_pipe tx_pipe;
|
struct gunyah_pipe tx_pipe;
|
||||||
struct gunyah_pipe rx_pipe;
|
struct gunyah_pipe rx_pipe;
|
||||||
@ -359,7 +362,11 @@ static void qrtr_gunyah_read_new(struct qrtr_gunyah_dev *qdev)
|
|||||||
gunyah_rx_peak(&qdev->rx_pipe, &hdr, 0, hdr_len);
|
gunyah_rx_peak(&qdev->rx_pipe, &hdr, 0, hdr_len);
|
||||||
pkt_len = qrtr_peek_pkt_size((void *)&hdr);
|
pkt_len = qrtr_peek_pkt_size((void *)&hdr);
|
||||||
if ((int)pkt_len < 0 || pkt_len > MAX_PKT_SZ) {
|
if ((int)pkt_len < 0 || pkt_len > MAX_PKT_SZ) {
|
||||||
dev_err(qdev->dev, "invalid pkt_len %zu\n", pkt_len);
|
/* Corrupted packet, reset the pipe and discard existing data */
|
||||||
|
rx_avail = gunyah_rx_avail(&qdev->rx_pipe);
|
||||||
|
dev_err(qdev->dev, "invalid pkt_len:%zu dropping:%zu bytes\n",
|
||||||
|
pkt_len, rx_avail);
|
||||||
|
gunyah_rx_advance(&qdev->rx_pipe, rx_avail);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,6 +413,9 @@ static void qrtr_gunyah_read_frag(struct qrtr_gunyah_dev *qdev)
|
|||||||
|
|
||||||
static void qrtr_gunyah_read(struct qrtr_gunyah_dev *qdev)
|
static void qrtr_gunyah_read(struct qrtr_gunyah_dev *qdev)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&qdev->dbl_lock, flags);
|
||||||
wake_up_all(&qdev->tx_avail_notify);
|
wake_up_all(&qdev->tx_avail_notify);
|
||||||
|
|
||||||
while (gunyah_rx_avail(&qdev->rx_pipe)) {
|
while (gunyah_rx_avail(&qdev->rx_pipe)) {
|
||||||
@ -417,6 +427,7 @@ static void qrtr_gunyah_read(struct qrtr_gunyah_dev *qdev)
|
|||||||
if (gunyah_get_read_notify(qdev))
|
if (gunyah_get_read_notify(qdev))
|
||||||
qrtr_gunyah_kick(qdev);
|
qrtr_gunyah_kick(qdev);
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&qdev->dbl_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qrtr_gunyah_share_mem(struct qrtr_gunyah_dev *qdev, gh_vmid_t self,
|
static int qrtr_gunyah_share_mem(struct qrtr_gunyah_dev *qdev, gh_vmid_t self,
|
||||||
@ -696,6 +707,8 @@ static int qrtr_gunyah_probe(struct platform_device *pdev)
|
|||||||
if (!qdev->ring.buf)
|
if (!qdev->ring.buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
spin_lock_init(&qdev->dbl_lock);
|
||||||
|
|
||||||
ret = of_property_read_u32(node, "gunyah-label", &qdev->label);
|
ret = of_property_read_u32(node, "gunyah-label", &qdev->label);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(qdev->dev, "failed to read label info %d\n", ret);
|
dev_err(qdev->dev, "failed to read label info %d\n", ret);
|
||||||
|
@ -50,7 +50,7 @@ static void qcom_mhi_qrtr_ul_callback(struct mhi_device *mhi_dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Send data over MHI */
|
/* Send data over MHI */
|
||||||
static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
|
static int __qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct qrtr_mhi_dev *qdev = container_of(ep, struct qrtr_mhi_dev, ep);
|
struct qrtr_mhi_dev *qdev = container_of(ep, struct qrtr_mhi_dev, ep);
|
||||||
int rc;
|
int rc;
|
||||||
@ -81,6 +81,18 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
do {
|
||||||
|
rc = __qcom_mhi_qrtr_send(ep, skb);
|
||||||
|
usleep_range(1000, 2000);
|
||||||
|
} while (rc == -EAGAIN);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static void qrtr_mhi_of_parse(struct mhi_device *mhi_dev,
|
static void qrtr_mhi_of_parse(struct mhi_device *mhi_dev,
|
||||||
u32 *net_id, bool *rt)
|
u32 *net_id, bool *rt)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user