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

Commit 32826ac4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull networking fixes from David Miller:
 "I've been traveling so this accumulates more than week or so of bug
  fixing.  It perhaps looks a little worse than it really is.

   1) Fix deadlock in ath10k driver, from Ben Greear.

   2) Increase scan timeout in iwlwifi, from Luca Coelho.

   3) Unbreak STP by properly reinjecting STP packets back into the
      stack.  Regression fix from Ido Schimmel.

   4) Mediatek driver fixes (missing malloc failure checks, leaking of
      scratch memory, wrong indexing when mapping TX buffers, etc.) from
      John Crispin.

   5) Fix endianness bug in icmpv6_err() handler, from Hannes Frederic
      Sowa.

   6) Fix hashing of flows in UDP in the ruseport case, from Xuemin Su.

   7) Fix netlink notifications in ovs for tunnels, delete link messages
      are never emitted because of how the device registry state is
      handled.  From Nicolas Dichtel.

   8) Conntrack module leaks kmemcache on unload, from Florian Westphal.

   9) Prevent endless jump loops in nft rules, from Liping Zhang and
      Pablo Neira Ayuso.

  10) Not early enough spinlock initialization in mlx4, from Eric
      Dumazet.

  11) Bind refcount leak in act_ipt, from Cong WANG.

  12) Missing RCU locking in HTB scheduler, from Florian Westphal.

  13) Several small MACSEC bug fixes from Sabrina Dubroca (missing RCU
      barrier, using heap for SG and IV, and erroneous use of async flag
      when allocating AEAD conext.)

  14) RCU handling fix in TIPC, from Ying Xue.

  15) Pass correct protocol down into ipv4_{update_pmtu,redirect}() in
      SIT driver, from Simon Horman.

  16) Socket timer deadlock fix in TIPC from Jon Paul Maloy.

  17) Fix potential deadlock in team enslave, from Ido Schimmel.

  18) Memory leak in KCM procfs handling, from Jiri Slaby.

  19) ESN generation fix in ipv4 ESP, from Herbert Xu.

  20) Fix GFP_KERNEL allocations with locks held in act_ife, from Cong
      WANG.

  21) Use after free in netem, from Eric Dumazet.

  22) Uninitialized last assert time in multicast router code, from Tom
      Goff.

  23) Skip raw sockets in sock_diag destruction broadcast, from Willem
      de Bruijn.

  24) Fix link status reporting in thunderx, from Sunil Goutham.

  25) Limit resegmentation of retransmit queue so that we do not
      retransmit too large GSO frames.  From Eric Dumazet.

  26) Delay bpf program release after grace period, from Daniel
      Borkmann"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (141 commits)
  openvswitch: fix conntrack netlink event delivery
  qed: Protect the doorbell BAR with the write barriers.
  neigh: Explicitly declare RCU-bh read side critical section in neigh_xmit()
  e1000e: keep VLAN interfaces functional after rxvlan off
  cfg80211: fix proto in ieee80211_data_to_8023 for frames without LLC header
  qlcnic: use the correct ring in qlcnic_83xx_process_rcv_ring_diag()
  bpf, perf: delay release of BPF prog after grace period
  net: bridge: fix vlan stats continue counter
  tcp: do not send too big packets at retransmit time
  ibmvnic: fix to use list_for_each_safe() when delete items
  net: thunderx: Fix TL4 configuration for secondary Qsets
  net: thunderx: Fix link status reporting
  net/mlx5e: Reorganize ethtool statistics
  net/mlx5e: Fix number of PFC counters reported to ethtool
  net/mlx5e: Prevent adding the same vxlan port
  net/mlx5e: Check for BlueFlame capability before allocating SQ uar
  net/mlx5e: Change enum to better reflect usage
  net/mlx5: Add ConnectX-5 PCIe 4.0 to list of supported devices
  net/mlx5: Update command strings
  net: marvell: Add separate config ANEG function for Marvell 88E1111
  ...
parents 653c574a 751ad819
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -7424,7 +7424,7 @@ F: drivers/scsi/megaraid.*
F:	drivers/scsi/megaraid/

MELLANOX ETHERNET DRIVER (mlx4_en)
M: 	Eugenia Emantayev <eugenia@mellanox.com>
M:	Tariq Toukan <tariqt@mellanox.com>
L:	netdev@vger.kernel.org
S:	Supported
W:	http://www.mellanox.com
+22 −21
Original line number Diff line number Diff line
@@ -56,11 +56,21 @@ static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
/* proc_event_counts is used as the sequence number of the netlink message */
static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 };

static inline void get_seq(__u32 *ts, int *cpu)
static inline void send_msg(struct cn_msg *msg)
{
	preempt_disable();
	*ts = __this_cpu_inc_return(proc_event_counts) - 1;
	*cpu = smp_processor_id();

	msg->seq = __this_cpu_inc_return(proc_event_counts) - 1;
	((struct proc_event *)msg->data)->cpu = smp_processor_id();

	/*
	 * Preemption remains disabled during send to ensure the messages are
	 * ordered according to their sequence numbers.
	 *
	 * If cn_netlink_send() fails, the data is not sent.
	 */
	cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_NOWAIT);

	preempt_enable();
}

@@ -77,7 +87,6 @@ void proc_fork_connector(struct task_struct *task)
	msg = buffer_to_cn_msg(buffer);
	ev = (struct proc_event *)msg->data;
	memset(&ev->event_data, 0, sizeof(ev->event_data));
	get_seq(&msg->seq, &ev->cpu);
	ev->timestamp_ns = ktime_get_ns();
	ev->what = PROC_EVENT_FORK;
	rcu_read_lock();
@@ -92,8 +101,7 @@ void proc_fork_connector(struct task_struct *task)
	msg->ack = 0; /* not used */
	msg->len = sizeof(*ev);
	msg->flags = 0; /* not used */
	/*  If cn_netlink_send() failed, the data is not sent */
	cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
	send_msg(msg);
}

void proc_exec_connector(struct task_struct *task)
@@ -108,7 +116,6 @@ void proc_exec_connector(struct task_struct *task)
	msg = buffer_to_cn_msg(buffer);
	ev = (struct proc_event *)msg->data;
	memset(&ev->event_data, 0, sizeof(ev->event_data));
	get_seq(&msg->seq, &ev->cpu);
	ev->timestamp_ns = ktime_get_ns();
	ev->what = PROC_EVENT_EXEC;
	ev->event_data.exec.process_pid = task->pid;
@@ -118,7 +125,7 @@ void proc_exec_connector(struct task_struct *task)
	msg->ack = 0; /* not used */
	msg->len = sizeof(*ev);
	msg->flags = 0; /* not used */
	cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
	send_msg(msg);
}

void proc_id_connector(struct task_struct *task, int which_id)
@@ -150,14 +157,13 @@ void proc_id_connector(struct task_struct *task, int which_id)
		return;
	}
	rcu_read_unlock();
	get_seq(&msg->seq, &ev->cpu);
	ev->timestamp_ns = ktime_get_ns();

	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
	msg->ack = 0; /* not used */
	msg->len = sizeof(*ev);
	msg->flags = 0; /* not used */
	cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
	send_msg(msg);
}

void proc_sid_connector(struct task_struct *task)
@@ -172,7 +178,6 @@ void proc_sid_connector(struct task_struct *task)
	msg = buffer_to_cn_msg(buffer);
	ev = (struct proc_event *)msg->data;
	memset(&ev->event_data, 0, sizeof(ev->event_data));
	get_seq(&msg->seq, &ev->cpu);
	ev->timestamp_ns = ktime_get_ns();
	ev->what = PROC_EVENT_SID;
	ev->event_data.sid.process_pid = task->pid;
@@ -182,7 +187,7 @@ void proc_sid_connector(struct task_struct *task)
	msg->ack = 0; /* not used */
	msg->len = sizeof(*ev);
	msg->flags = 0; /* not used */
	cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
	send_msg(msg);
}

void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
@@ -197,7 +202,6 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
	msg = buffer_to_cn_msg(buffer);
	ev = (struct proc_event *)msg->data;
	memset(&ev->event_data, 0, sizeof(ev->event_data));
	get_seq(&msg->seq, &ev->cpu);
	ev->timestamp_ns = ktime_get_ns();
	ev->what = PROC_EVENT_PTRACE;
	ev->event_data.ptrace.process_pid  = task->pid;
@@ -215,7 +219,7 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
	msg->ack = 0; /* not used */
	msg->len = sizeof(*ev);
	msg->flags = 0; /* not used */
	cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
	send_msg(msg);
}

void proc_comm_connector(struct task_struct *task)
@@ -230,7 +234,6 @@ void proc_comm_connector(struct task_struct *task)
	msg = buffer_to_cn_msg(buffer);
	ev = (struct proc_event *)msg->data;
	memset(&ev->event_data, 0, sizeof(ev->event_data));
	get_seq(&msg->seq, &ev->cpu);
	ev->timestamp_ns = ktime_get_ns();
	ev->what = PROC_EVENT_COMM;
	ev->event_data.comm.process_pid  = task->pid;
@@ -241,7 +244,7 @@ void proc_comm_connector(struct task_struct *task)
	msg->ack = 0; /* not used */
	msg->len = sizeof(*ev);
	msg->flags = 0; /* not used */
	cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
	send_msg(msg);
}

void proc_coredump_connector(struct task_struct *task)
@@ -256,7 +259,6 @@ void proc_coredump_connector(struct task_struct *task)
	msg = buffer_to_cn_msg(buffer);
	ev = (struct proc_event *)msg->data;
	memset(&ev->event_data, 0, sizeof(ev->event_data));
	get_seq(&msg->seq, &ev->cpu);
	ev->timestamp_ns = ktime_get_ns();
	ev->what = PROC_EVENT_COREDUMP;
	ev->event_data.coredump.process_pid = task->pid;
@@ -266,7 +268,7 @@ void proc_coredump_connector(struct task_struct *task)
	msg->ack = 0; /* not used */
	msg->len = sizeof(*ev);
	msg->flags = 0; /* not used */
	cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
	send_msg(msg);
}

void proc_exit_connector(struct task_struct *task)
@@ -281,7 +283,6 @@ void proc_exit_connector(struct task_struct *task)
	msg = buffer_to_cn_msg(buffer);
	ev = (struct proc_event *)msg->data;
	memset(&ev->event_data, 0, sizeof(ev->event_data));
	get_seq(&msg->seq, &ev->cpu);
	ev->timestamp_ns = ktime_get_ns();
	ev->what = PROC_EVENT_EXIT;
	ev->event_data.exit.process_pid = task->pid;
@@ -293,7 +294,7 @@ void proc_exit_connector(struct task_struct *task)
	msg->ack = 0; /* not used */
	msg->len = sizeof(*ev);
	msg->flags = 0; /* not used */
	cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
	send_msg(msg);
}

/*
@@ -325,7 +326,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
	msg->ack = rcvd_ack + 1;
	msg->len = sizeof(*ev);
	msg->flags = 0; /* not used */
	cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
	send_msg(msg);
}

/**
+45 −19
Original line number Diff line number Diff line
@@ -657,6 +657,20 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val)
	}
}

static int __agg_active_ports(struct aggregator *agg)
{
	struct port *port;
	int active = 0;

	for (port = agg->lag_ports; port;
	     port = port->next_port_in_aggregator) {
		if (port->is_enabled)
			active++;
	}

	return active;
}

/**
 * __get_agg_bandwidth - get the total bandwidth of an aggregator
 * @aggregator: the aggregator we're looking at
@@ -664,39 +678,40 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val)
 */
static u32 __get_agg_bandwidth(struct aggregator *aggregator)
{
	int nports = __agg_active_ports(aggregator);
	u32 bandwidth = 0;

	if (aggregator->num_of_ports) {
	if (nports) {
		switch (__get_link_speed(aggregator->lag_ports)) {
		case AD_LINK_SPEED_1MBPS:
			bandwidth = aggregator->num_of_ports;
			bandwidth = nports;
			break;
		case AD_LINK_SPEED_10MBPS:
			bandwidth = aggregator->num_of_ports * 10;
			bandwidth = nports * 10;
			break;
		case AD_LINK_SPEED_100MBPS:
			bandwidth = aggregator->num_of_ports * 100;
			bandwidth = nports * 100;
			break;
		case AD_LINK_SPEED_1000MBPS:
			bandwidth = aggregator->num_of_ports * 1000;
			bandwidth = nports * 1000;
			break;
		case AD_LINK_SPEED_2500MBPS:
			bandwidth = aggregator->num_of_ports * 2500;
			bandwidth = nports * 2500;
			break;
		case AD_LINK_SPEED_10000MBPS:
			bandwidth = aggregator->num_of_ports * 10000;
			bandwidth = nports * 10000;
			break;
		case AD_LINK_SPEED_20000MBPS:
			bandwidth = aggregator->num_of_ports * 20000;
			bandwidth = nports * 20000;
			break;
		case AD_LINK_SPEED_40000MBPS:
			bandwidth = aggregator->num_of_ports * 40000;
			bandwidth = nports * 40000;
			break;
		case AD_LINK_SPEED_56000MBPS:
			bandwidth = aggregator->num_of_ports * 56000;
			bandwidth = nports * 56000;
			break;
		case AD_LINK_SPEED_100000MBPS:
			bandwidth = aggregator->num_of_ports * 100000;
			bandwidth = nports * 100000;
			break;
		default:
			bandwidth = 0; /* to silence the compiler */
@@ -1530,10 +1545,10 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best,

	switch (__get_agg_selection_mode(curr->lag_ports)) {
	case BOND_AD_COUNT:
		if (curr->num_of_ports > best->num_of_ports)
		if (__agg_active_ports(curr) > __agg_active_ports(best))
			return curr;

		if (curr->num_of_ports < best->num_of_ports)
		if (__agg_active_ports(curr) < __agg_active_ports(best))
			return best;

		/*FALLTHROUGH*/
@@ -1561,8 +1576,14 @@ static int agg_device_up(const struct aggregator *agg)
	if (!port)
		return 0;

	return netif_running(port->slave->dev) &&
	       netif_carrier_ok(port->slave->dev);
	for (port = agg->lag_ports; port;
	     port = port->next_port_in_aggregator) {
		if (netif_running(port->slave->dev) &&
		    netif_carrier_ok(port->slave->dev))
			return 1;
	}

	return 0;
}

/**
@@ -1610,7 +1631,7 @@ static void ad_agg_selection_logic(struct aggregator *agg,

		agg->is_active = 0;

		if (agg->num_of_ports && agg_device_up(agg))
		if (__agg_active_ports(agg) && agg_device_up(agg))
			best = ad_agg_selection_test(best, agg);
	}

@@ -1622,7 +1643,7 @@ static void ad_agg_selection_logic(struct aggregator *agg,
		 * answering partner.
		 */
		if (active && active->lag_ports &&
		    active->lag_ports->is_enabled &&
		    __agg_active_ports(active) &&
		    (__agg_has_partner(active) ||
		     (!__agg_has_partner(active) &&
		     !__agg_has_partner(best)))) {
@@ -2133,7 +2154,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
				else
					temp_aggregator->lag_ports = temp_port->next_port_in_aggregator;
				temp_aggregator->num_of_ports--;
				if (temp_aggregator->num_of_ports == 0) {
				if (__agg_active_ports(temp_aggregator) == 0) {
					select_new_active_agg = temp_aggregator->is_active;
					ad_clear_agg(temp_aggregator);
					if (select_new_active_agg) {
@@ -2432,7 +2453,9 @@ void bond_3ad_adapter_speed_duplex_changed(struct slave *slave)
 */
void bond_3ad_handle_link_change(struct slave *slave, char link)
{
	struct aggregator *agg;
	struct port *port;
	bool dummy;

	port = &(SLAVE_AD_INFO(slave)->port);

@@ -2459,6 +2482,9 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
		port->is_enabled = false;
		ad_update_actor_keys(port, true);
	}
	agg = __get_first_agg(port);
	ad_agg_selection_logic(agg, &dummy);

	netdev_dbg(slave->bond->dev, "Port %d changed link status to %s\n",
		   port->actor_port_number,
		   link == BOND_LINK_UP ? "UP" : "DOWN");
@@ -2499,7 +2525,7 @@ int bond_3ad_set_carrier(struct bonding *bond)
	active = __get_active_agg(&(SLAVE_AD_INFO(first_slave)->aggregator));
	if (active) {
		/* are enough slaves available to consider link up? */
		if (active->num_of_ports < bond->params.min_links) {
		if (__agg_active_ports(active) < bond->params.min_links) {
			if (netif_carrier_ok(bond->dev)) {
				netif_carrier_off(bond->dev);
				goto out;
+3 −2
Original line number Diff line number Diff line
@@ -712,8 +712,9 @@ static int at91_poll_rx(struct net_device *dev, int quota)

	/* upper group completed, look again in lower */
	if (priv->rx_next > get_mb_rx_low_last(priv) &&
	    quota > 0 && mb > get_mb_rx_last(priv)) {
	    mb > get_mb_rx_last(priv)) {
		priv->rx_next = get_mb_rx_first(priv);
		if (quota > 0)
			goto again;
	}

+31 −7
Original line number Diff line number Diff line
@@ -332,9 +332,23 @@ static void c_can_setup_tx_object(struct net_device *dev, int iface,

	priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);

	if (priv->type == BOSCH_D_CAN) {
		u32 data = 0, dreg = C_CAN_IFACE(DATA1_REG, iface);

		for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
			data = (u32)frame->data[i];
			data |= (u32)frame->data[i + 1] << 8;
			data |= (u32)frame->data[i + 2] << 16;
			data |= (u32)frame->data[i + 3] << 24;
			priv->write_reg32(priv, dreg, data);
		}
	} else {
		for (i = 0; i < frame->can_dlc; i += 2) {
		priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2,
				frame->data[i] | (frame->data[i + 1] << 8));
			priv->write_reg(priv,
					C_CAN_IFACE(DATA1_REG, iface) + i / 2,
					frame->data[i] |
					(frame->data[i + 1] << 8));
		}
	}
}

@@ -402,12 +416,22 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl)
	} else {
		int i, dreg = C_CAN_IFACE(DATA1_REG, iface);

		if (priv->type == BOSCH_D_CAN) {
			for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
				data = priv->read_reg32(priv, dreg);
				frame->data[i] = data;
				frame->data[i + 1] = data >> 8;
				frame->data[i + 2] = data >> 16;
				frame->data[i + 3] = data >> 24;
			}
		} else {
			for (i = 0; i < frame->can_dlc; i += 2, dreg++) {
				data = priv->read_reg(priv, dreg);
				frame->data[i] = data;
				frame->data[i + 1] = data >> 8;
			}
		}
	}

	stats->rx_packets++;
	stats->rx_bytes += frame->can_dlc;
Loading