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;
|
||||
int rc, confirm_rx;
|
||||
|
||||
mutex_lock(&node->ep_lock);
|
||||
if (!atomic_read(&node->hello_sent) && type != QRTR_TYPE_HELLO) {
|
||||
kfree_skb(skb);
|
||||
mutex_unlock(&node->ep_lock);
|
||||
return 0;
|
||||
}
|
||||
if (atomic_read(&node->hello_sent) && type == QRTR_TYPE_HELLO) {
|
||||
kfree_skb(skb);
|
||||
mutex_unlock(&node->ep_lock);
|
||||
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 (!skb->sk) {
|
||||
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
|
||||
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__,
|
||||
skb->len, ALIGN(skb->len, 4), rc);
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
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 */
|
||||
if (rc && confirm_rx)
|
||||
qrtr_tx_flow_failed(node, to->sq_node, to->sq_port);
|
||||
if (type == QRTR_TYPE_HELLO) {
|
||||
if (!rc)
|
||||
atomic_inc(&node->hello_sent);
|
||||
else
|
||||
kthread_queue_work(&node->kworker, &node->say_hello);
|
||||
if (rc && type == QRTR_TYPE_HELLO) {
|
||||
atomic_dec(&node->hello_sent);
|
||||
kthread_queue_work(&node->kworker, &node->say_hello);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -1391,6 +1398,7 @@ static void qrtr_fwd_del_proc(struct qrtr_node *src, unsigned int nid)
|
||||
struct qrtr_node *dst;
|
||||
struct sk_buff *skb;
|
||||
|
||||
down_read(&qrtr_epts_lock);
|
||||
list_for_each_entry(dst, &qrtr_all_epts, item) {
|
||||
if (!qrtr_must_forward(src, dst, QRTR_TYPE_DEL_PROC))
|
||||
continue;
|
||||
@ -1408,6 +1416,7 @@ static void qrtr_fwd_del_proc(struct qrtr_node *src, unsigned int nid)
|
||||
to.sq_node = dst->nid;
|
||||
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();
|
||||
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 */
|
||||
if (!zapped)
|
||||
qrtr_port_remove(ipc);
|
||||
@ -2123,6 +2121,18 @@ static int qrtr_release(struct socket *sock)
|
||||
lock_sock(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;
|
||||
if (!sock_flag(sk, SOCK_DEAD))
|
||||
sk->sk_state_change(sk);
|
||||
|
@ -64,6 +64,7 @@ struct gunyah_pipe {
|
||||
* @label: label for gunyah resources
|
||||
* @tx_dbl: doorbell for tx notifications.
|
||||
* @rx_dbl: doorbell for rx notifications.
|
||||
* @dbl_lock: lock to prevent read races.
|
||||
* @tx_pipe: TX gunyah specific info.
|
||||
* @rx_pipe: RX gunyah specific info.
|
||||
*/
|
||||
@ -84,6 +85,8 @@ struct qrtr_gunyah_dev {
|
||||
void *tx_dbl;
|
||||
void *rx_dbl;
|
||||
struct work_struct work;
|
||||
/* lock to protect dbl_running */
|
||||
spinlock_t dbl_lock;
|
||||
|
||||
struct gunyah_pipe tx_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);
|
||||
pkt_len = qrtr_peek_pkt_size((void *)&hdr);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&qdev->dbl_lock, flags);
|
||||
wake_up_all(&qdev->tx_avail_notify);
|
||||
|
||||
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))
|
||||
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,
|
||||
@ -696,6 +707,8 @@ static int qrtr_gunyah_probe(struct platform_device *pdev)
|
||||
if (!qdev->ring.buf)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&qdev->dbl_lock);
|
||||
|
||||
ret = of_property_read_u32(node, "gunyah-label", &qdev->label);
|
||||
if (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 */
|
||||
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);
|
||||
int rc;
|
||||
@ -81,6 +81,18 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
|
||||
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,
|
||||
u32 *net_id, bool *rt)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user