Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a64c4268 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: qrtr: Rearrange tx wait and protect critical section"

parents 7e0f425c c969cce7
Loading
Loading
Loading
Loading
+28 −26
Original line number Diff line number Diff line
@@ -390,10 +390,10 @@ static void qrtr_tx_resume(struct qrtr_node *node, struct sk_buff *skb)
	if (!flow)
		return;

	mutex_lock(&node->qrtr_tx_lock);
	atomic_set(&flow->pending, 0);
	wake_up_interruptible_all(&node->resume_tx);

	mutex_lock(&node->qrtr_tx_lock);
	list_for_each_entry_safe(waiter, temp, &flow->waiters, node) {
		list_del(&waiter->node);
		skbn = alloc_skb(0, GFP_KERNEL);
@@ -451,40 +451,39 @@ static int qrtr_tx_wait(struct qrtr_node *node, struct sockaddr_qrtr *to,
	}
	mutex_unlock(&node->qrtr_tx_lock);

	ret = timeo;
	for (;;) {
		ret = wait_event_interruptible_timeout(
				node->resume_tx,
				!node->ep ||
				atomic_read(&flow->pending) < QRTR_TX_FLOW_HIGH,
				timeo);
		if (ret < 0)
			return ret;
		if (!ret)
			return -EAGAIN;

		if (!node->ep)
			return -EPIPE;

		mutex_lock(&node->qrtr_tx_lock);
		if (atomic_read(&flow->pending) < QRTR_TX_FLOW_HIGH) {
			atomic_inc(&flow->pending);
			confirm_rx = atomic_read(&flow->pending) == QRTR_TX_FLOW_LOW;
			confirm_rx = atomic_read(&flow->pending) ==
				     QRTR_TX_FLOW_LOW;
			mutex_unlock(&node->qrtr_tx_lock);
			break;
		}
		mutex_unlock(&node->qrtr_tx_lock);
	}

	if (confirm_rx) {
		if (!ret) {
			waiter = kzalloc(sizeof(*waiter), GFP_KERNEL);
		if (!waiter)
			if (!waiter) {
				mutex_unlock(&node->qrtr_tx_lock);
				return -ENOMEM;
			}
			waiter->sk = sk;
			sock_hold(sk);

		mutex_lock(&node->qrtr_tx_lock);
			list_add_tail(&waiter->node, &flow->waiters);
			mutex_unlock(&node->qrtr_tx_lock);
			return -EAGAIN;
		}
		mutex_unlock(&node->qrtr_tx_lock);

		ret = wait_event_interruptible_timeout(
				node->resume_tx,
				!node->ep ||
				atomic_read(&flow->pending) < QRTR_TX_FLOW_HIGH,
				timeo);
		if (ret < 0)
			return ret;
		if (!node->ep)
			return -EPIPE;
	}
	return confirm_rx;
}
@@ -1221,7 +1220,8 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
		goto out_node;
	}

	if (ipc->us.sq_port == QRTR_PORT_CTRL) {
	if (ipc->us.sq_port == QRTR_PORT_CTRL ||
	    addr->sq_port == QRTR_PORT_CTRL) {
		if (len < 4) {
			rc = -EINVAL;
			kfree_skb(skb);
@@ -1232,6 +1232,8 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
		skb_copy_bits(skb, 0, &type, 4);
		type = le32_to_cpu(type);
	}
	if (addr->sq_port == QRTR_PORT_CTRL && type == QRTR_TYPE_NEW_SERVER)
		ipc->state = QRTR_STATE_MULTI;

	rc = enqueue_fn(node, skb, type, &ipc->us, addr, msg->msg_flags);
	if (rc >= 0)