Merge 4.14.174 into android-4.14

Changes in 4.14.174
	phy: Revert toggling reset changes.
	net: phy: Avoid multiple suspends
	cgroup, netclassid: periodically release file_lock on classid updating
	gre: fix uninit-value in __iptunnel_pull_header
	ipv6/addrconf: call ipv6_mc_up() for non-Ethernet interface
	ipvlan: add cond_resched_rcu() while processing muticast backlog
	ipvlan: do not use cond_resched_rcu() in ipvlan_process_multicast()
	netlink: Use netlink header as base to calculate bad attribute offset
	net: macsec: update SCI upon MAC address change.
	net: nfc: fix bounds checking bugs on "pipe"
	net/packet: tpacket_rcv: do not increment ring index on drop
	r8152: check disconnect status after long sleep
	sfc: detach from cb_page in efx_copy_channel()
	bnxt_en: reinitialize IRQs when MTU is modified
	cgroup: memcg: net: do not associate sock with unrelated cgroup
	net: memcg: late association of sock to memcg
	net: memcg: fix lockdep splat in inet_csk_accept()
	fib: add missing attribute validation for tun_id
	nl802154: add missing attribute validation
	nl802154: add missing attribute validation for dev_type
	can: add missing attribute validation for termination
	macsec: add missing attribute validation for port
	net: fq: add missing attribute validation for orphan mask
	team: add missing attribute validation for port ifindex
	team: add missing attribute validation for array index
	nfc: add missing attribute validation for SE API
	nfc: add missing attribute validation for vendor subcommand
	net: phy: fix MDIO bus PM PHY resuming
	bonding/alb: make sure arp header is pulled before accessing it
	slip: make slhc_compress() more robust against malicious packets
	net: fec: validate the new settings in fec_enet_set_coalesce()
	macvlan: add cond_resched() during multicast processing
	inet_diag: return classid for all socket types
	ipvlan: do not add hardware address of master to its unicast filter list
	ipvlan: egress mcast packets are not exceptional
	ipvlan: don't deref eth hdr before checking it's set
	cgroup: cgroup_procs_next should increase position index
	cgroup: Iterate tasks that did not finish do_exit()
	iwlwifi: mvm: Do not require PHY_SKU NVM section for 3168 devices
	virtio-blk: fix hw_queue stopped on arbitrary error
	iommu/vt-d: quirk_ioat_snb_local_iommu: replace WARN_TAINT with pr_warn + add_taint
	workqueue: don't use wq_select_unbound_cpu() for bound works
	drm/amd/display: remove duplicated assignment to grph_obj_type
	ktest: Add timeout for ssh sync testing
	cifs_atomic_open(): fix double-put on late allocation failure
	gfs2_atomic_open(): fix O_EXCL|O_CREAT handling on cold dcache
	KVM: x86: clear stale x86_emulate_ctxt->intercept value
	ARC: define __ALIGN_STR and __ALIGN symbols for ARC
	efi: Fix a race and a buffer overflow while reading efivars via sysfs
	x86/mce: Fix logic and comments around MSR_PPIN_CTL
	iommu/dma: Fix MSI reservation allocation
	iommu/vt-d: dmar: replace WARN_TAINT with pr_warn + add_taint
	iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page
	pinctrl: meson-gxl: fix GPIOX sdio pins
	pinctrl: core: Remove extra kref_get which blocks hogs being freed
	nl80211: add missing attribute validation for critical protocol indication
	nl80211: add missing attribute validation for beacon report scanning
	nl80211: add missing attribute validation for channel switch
	netfilter: cthelper: add missing attribute validation for cthelper
	netfilter: nft_payload: add missing attribute validation for payload csum flags
	iommu/vt-d: Fix the wrong printing in RHSA parsing
	iommu/vt-d: Ignore devices with out-of-spec domain number
	i2c: acpi: put device when verifying client fails
	ipv6: restrict IPV6_ADDRFORM operation
	net/smc: check for valid ib_client_data
	efi: Add a sanity check to efivar_store_raw()
	batman-adv: Avoid spurious warnings from bat_v neigh_cmp implementation
	batman-adv: Always initialize fragment header priority
	batman-adv: Fix check of retrieved orig_gw in batadv_v_gw_is_eligible
	batman-adv: Fix lock for ogm cnt access in batadv_iv_ogm_calc_tq
	batman-adv: Fix internal interface indices types
	batman-adv: update data pointers after skb_cow()
	batman-adv: Avoid race in TT TVLV allocator helper
	batman-adv: Fix TT sync flags for intermediate TT responses
	batman-adv: prevent TT request storms by not sending inconsistent TT TLVLs
	batman-adv: Fix debugfs path for renamed hardif
	batman-adv: Fix debugfs path for renamed softif
	batman-adv: Fix duplicated OGMs on NETDEV_UP
	batman-adv: Avoid free/alloc race when handling OGM2 buffer
	batman-adv: Avoid free/alloc race when handling OGM buffer
	batman-adv: Don't schedule OGM for disabled interface
	perf/amd/uncore: Replace manual sampling check with CAP_NO_INTERRUPT flag
	ACPI: watchdog: Allow disabling WDAT at boot
	HID: apple: Add support for recent firmware on Magic Keyboards
	HID: i2c-hid: add Trekstor Surfbook E11B to descriptor override
	cfg80211: check reg_rule for NULL in handle_channel_custom()
	scsi: libfc: free response frame from GPN_ID
	net: usb: qmi_wwan: restore mtu min/max values after raw_ip switch
	net: ks8851-ml: Fix IRQ handling and locking
	mac80211: rx: avoid RCU list traversal under mutex
	signal: avoid double atomic counter increments for user accounting
	slip: not call free_netdev before rtnl_unlock in slip_open
	hinic: fix a bug of setting hw_ioctxt
	net: rmnet: fix NULL pointer dereference in rmnet_newlink()
	jbd2: fix data races at struct journal_head
	ARM: 8957/1: VDSO: Match ARMv8 timer in cntvct_functional()
	ARM: 8958/1: rename missed uaccess .fixup section
	mm: slub: add missing TID bump in kmem_cache_alloc_bulk()
	ipv4: ensure rcu_read_lock() in cipso_v4_error()
	Linux 4.14.174

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I8594f155b5b3df71510fdb5dc034c80fb2332c91
This commit is contained in:
Greg Kroah-Hartman
2020-03-20 12:19:46 +01:00
90 changed files with 745 additions and 286 deletions

View File

@@ -137,6 +137,10 @@
dynamic table installation which will install SSDT
tables to /sys/firmware/acpi/tables/dynamic.
acpi_no_watchdog [HW,ACPI,WDT]
Ignore the ACPI-based watchdog interface (WDAT) and let
a native driver control the watchdog device instead.
acpi_rsdp= [ACPI,EFI,KEXEC]
Pass the RSDP address to the kernel, mostly used
on machines running EFI runtime service to boot the

View File

@@ -606,3 +606,10 @@ in your dentry operations instead.
dentry separately, and it now has request_mask and query_flags arguments
to specify the fields and sync type requested by statx. Filesystems not
supporting any statx-specific features may ignore the new arguments.
--
[mandatory]
[should've been added in 2016] stale comment in finish_open()
nonwithstanding, failure exits in ->atomic_open() instances should
*NOT* fput() the file, no matter what. Everything is handled by the
caller.

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 4
PATCHLEVEL = 14
SUBLEVEL = 173
SUBLEVEL = 174
EXTRAVERSION =
NAME = Petit Gorille

View File

@@ -14,6 +14,8 @@
#ifdef __ASSEMBLY__
#define ASM_NL ` /* use '`' to mark new line in macro */
#define __ALIGN .align 4
#define __ALIGN_STR __stringify(__ALIGN)
/* annotation for data we want in DCCM - if enabled in .config */
.macro ARCFP_DATA nm

View File

@@ -103,6 +103,8 @@ static bool __init cntvct_functional(void)
* this.
*/
np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
if (!np)
np = of_find_compatible_node(NULL, NULL, "arm,armv8-timer");
if (!np)
goto out_put;

View File

@@ -193,20 +193,18 @@ static int amd_uncore_event_init(struct perf_event *event)
/*
* NB and Last level cache counters (MSRs) are shared across all cores
* that share the same NB / Last level cache. Interrupts can be directed
* to a single target core, however, event counts generated by processes
* running on other cores cannot be masked out. So we do not support
* sampling and per-thread events.
* that share the same NB / Last level cache. On family 16h and below,
* Interrupts can be directed to a single target core, however, event
* counts generated by processes running on other cores cannot be masked
* out. So we do not support sampling and per-thread events via
* CAP_NO_INTERRUPT, and we do not enable counter overflow interrupts:
*/
if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
return -EINVAL;
/* NB and Last level cache counters do not have usr/os/guest/host bits */
if (event->attr.exclude_user || event->attr.exclude_kernel ||
event->attr.exclude_host || event->attr.exclude_guest)
return -EINVAL;
/* and we do not enable counter overflow interrupts */
hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB;
hwc->idx = -1;
@@ -314,6 +312,7 @@ static struct pmu amd_nb_pmu = {
.start = amd_uncore_start,
.stop = amd_uncore_stop,
.read = amd_uncore_read,
.capabilities = PERF_PMU_CAP_NO_INTERRUPT,
};
static struct pmu amd_llc_pmu = {
@@ -324,6 +323,7 @@ static struct pmu amd_llc_pmu = {
.start = amd_uncore_start,
.stop = amd_uncore_stop,
.read = amd_uncore_read,
.capabilities = PERF_PMU_CAP_NO_INTERRUPT,
};
static struct amd_uncore *amd_uncore_alloc(unsigned int cpu)

View File

@@ -489,17 +489,18 @@ static void intel_ppin_init(struct cpuinfo_x86 *c)
return;
if ((val & 3UL) == 1UL) {
/* PPIN available but disabled: */
/* PPIN locked in disabled mode */
return;
}
/* If PPIN is disabled, but not locked, try to enable: */
if (!(val & 3UL)) {
/* If PPIN is disabled, try to enable */
if (!(val & 2UL)) {
wrmsrl_safe(MSR_PPIN_CTL, val | 2UL);
rdmsrl_safe(MSR_PPIN_CTL, &val);
}
if ((val & 3UL) == 2UL)
/* Is the enable bit set? */
if (val & 2UL)
set_cpu_cap(c, X86_FEATURE_INTEL_PPIN);
}
}

View File

@@ -5062,6 +5062,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
ctxt->fetch.ptr = ctxt->fetch.data;
ctxt->fetch.end = ctxt->fetch.data + insn_len;
ctxt->opcode_len = 1;
ctxt->intercept = x86_intercept_none;
if (insn_len > 0)
memcpy(ctxt->fetch.data, insn, insn_len);
else {

View File

@@ -58,12 +58,14 @@ static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat)
}
#endif
static bool acpi_no_watchdog;
static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
{
const struct acpi_table_wdat *wdat = NULL;
acpi_status status;
if (acpi_disabled)
if (acpi_disabled || acpi_no_watchdog)
return NULL;
status = acpi_get_table(ACPI_SIG_WDAT, 0,
@@ -91,6 +93,14 @@ bool acpi_has_watchdog(void)
}
EXPORT_SYMBOL_GPL(acpi_has_watchdog);
/* ACPI watchdog can be disabled on boot command line */
static int __init disable_acpi_watchdog(char *str)
{
acpi_no_watchdog = true;
return 1;
}
__setup("acpi_no_watchdog", disable_acpi_watchdog);
void __init acpi_watchdog_init(void)
{
const struct acpi_wdat_entry *entries;

View File

@@ -271,10 +271,12 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num);
if (err) {
virtqueue_kick(vblk->vqs[qid].vq);
blk_mq_stop_hw_queue(hctx);
/* Don't stop the queue if -ENOMEM: we may have failed to
* bounce the buffer due to global resource outage.
*/
if (err == -ENOSPC)
blk_mq_stop_hw_queue(hctx);
spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
/* Out of mem doesn't actually happen, since we fall back
* to direct descriptors */
if (err == -ENOMEM || err == -ENOSPC)
return BLK_STS_RESOURCE;
return BLK_STS_IOERR;

View File

@@ -139,13 +139,16 @@ static ssize_t
efivar_attr_read(struct efivar_entry *entry, char *buf)
{
struct efi_variable *var = &entry->var;
unsigned long size = sizeof(var->Data);
char *str = buf;
int ret;
if (!entry || !buf)
return -EINVAL;
var->DataSize = 1024;
if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
var->DataSize = size;
if (ret)
return -EIO;
if (var->Attributes & EFI_VARIABLE_NON_VOLATILE)
@@ -172,13 +175,16 @@ static ssize_t
efivar_size_read(struct efivar_entry *entry, char *buf)
{
struct efi_variable *var = &entry->var;
unsigned long size = sizeof(var->Data);
char *str = buf;
int ret;
if (!entry || !buf)
return -EINVAL;
var->DataSize = 1024;
if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
var->DataSize = size;
if (ret)
return -EIO;
str += sprintf(str, "0x%lx\n", var->DataSize);
@@ -189,12 +195,15 @@ static ssize_t
efivar_data_read(struct efivar_entry *entry, char *buf)
{
struct efi_variable *var = &entry->var;
unsigned long size = sizeof(var->Data);
int ret;
if (!entry || !buf)
return -EINVAL;
var->DataSize = 1024;
if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
var->DataSize = size;
if (ret)
return -EIO;
memcpy(buf, var->Data, var->DataSize);
@@ -263,6 +272,9 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
u8 *data;
int err;
if (!entry || !buf)
return -EINVAL;
if (is_compat()) {
struct compat_efi_variable *compat;
@@ -314,14 +326,16 @@ efivar_show_raw(struct efivar_entry *entry, char *buf)
{
struct efi_variable *var = &entry->var;
struct compat_efi_variable *compat;
unsigned long datasize = sizeof(var->Data);
size_t size;
int ret;
if (!entry || !buf)
return 0;
var->DataSize = 1024;
if (efivar_entry_get(entry, &entry->var.Attributes,
&entry->var.DataSize, entry->var.Data))
ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data);
var->DataSize = datasize;
if (ret)
return -EIO;
if (is_compat()) {

View File

@@ -363,8 +363,7 @@ bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device *
router.ddc_valid = false;
router.cd_valid = false;
for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) {
uint8_t grph_obj_type=
grph_obj_type =
uint8_t grph_obj_type =
(le16_to_cpu(path->usGraphicObjIds[j]) &
OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;

View File

@@ -343,7 +343,8 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
unsigned long **bit, int *max)
{
if (usage->hid == (HID_UP_CUSTOM | 0x0003) ||
usage->hid == (HID_UP_MSVENDOR | 0x0003)) {
usage->hid == (HID_UP_MSVENDOR | 0x0003) ||
usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) {
/* The fn key on Apple USB keyboards */
set_bit(EV_REP, hi->input->evbit);
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);

View File

@@ -341,6 +341,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
},
.driver_data = (void *)&sipodev_desc
},
{
.ident = "Trekstor SURFBOOK E11B",
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"),
},
.driver_data = (void *)&sipodev_desc
},
{
.ident = "Direkt-Tek DTLAPY116-2",
.matches = {

View File

@@ -352,10 +352,18 @@ static struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
{
struct device *dev;
struct i2c_client *client;
dev = bus_find_device(&i2c_bus_type, NULL, adev,
i2c_acpi_find_match_device);
return dev ? i2c_verify_client(dev) : NULL;
if (!dev)
return NULL;
client = i2c_verify_client(dev);
if (!client)
put_device(dev);
return client;
}
static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,

View File

@@ -208,15 +208,15 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie,
start -= iova_offset(iovad, start);
num_pages = iova_align(iovad, end - start) >> iova_shift(iovad);
msi_page = kcalloc(num_pages, sizeof(*msi_page), GFP_KERNEL);
if (!msi_page)
return -ENOMEM;
for (i = 0; i < num_pages; i++) {
msi_page[i].phys = start;
msi_page[i].iova = start;
INIT_LIST_HEAD(&msi_page[i].list);
list_add(&msi_page[i].list, &cookie->msi_page_list);
msi_page = kmalloc(sizeof(*msi_page), GFP_KERNEL);
if (!msi_page)
return -ENOMEM;
msi_page->phys = start;
msi_page->iova = start;
INIT_LIST_HEAD(&msi_page->list);
list_add(&msi_page->list, &cookie->msi_page_list);
start += iovad->granule;
}

View File

@@ -39,6 +39,7 @@
#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/iommu.h>
#include <linux/limits.h>
#include <asm/irq_remapping.h>
#include <asm/iommu_table.h>
@@ -139,6 +140,13 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event)
BUG_ON(dev->is_virtfn);
/*
* Ignore devices that have a domain number higher than what can
* be looked up in DMAR, e.g. VMD subdevices with domain 0x10000
*/
if (pci_domain_nr(dev->bus) > U16_MAX)
return NULL;
/* Only generate path[] for device addition event */
if (event == BUS_NOTIFY_ADD_DEVICE)
for (tmp = dev; tmp; tmp = tmp->bus->self)
@@ -451,12 +459,13 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header,
/* Check for NUL termination within the designated length */
if (strnlen(andd->device_name, header->length - 8) == header->length - 8) {
WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
pr_warn(FW_BUG
"Your BIOS is broken; ANDD object name is not NUL-terminated\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
return -EINVAL;
}
pr_info("ANDD device: %x name: %s\n", andd->device_number,
@@ -482,14 +491,14 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg)
return 0;
}
}
WARN_TAINT(
1, TAINT_FIRMWARE_WORKAROUND,
pr_warn(FW_BUG
"Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
drhd->reg_base_addr,
rhsa->base_address,
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
return 0;
}
@@ -835,14 +844,14 @@ int __init dmar_table_init(void)
static void warn_invalid_dmar(u64 addr, const char *message)
{
WARN_TAINT_ONCE(
1, TAINT_FIRMWARE_WORKAROUND,
pr_warn_once(FW_BUG
"Your BIOS is broken; DMAR reported at address %llx%s!\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
addr, message,
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
}
static int __ref

View File

@@ -3984,10 +3984,11 @@ static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
/* we know that the this iommu should be at offset 0xa000 from vtbar */
drhd = dmar_find_matched_drhd_unit(pdev);
if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
TAINT_FIRMWARE_WORKAROUND,
"BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) {
pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n");
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
}
}
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
@@ -5123,8 +5124,10 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
u64 phys = 0;
pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
if (pte)
phys = dma_pte_addr(pte);
if (pte && dma_pte_present(pte))
phys = dma_pte_addr(pte) +
(iova & (BIT_MASK(level_to_offset_bits(level) +
VTD_PAGE_SHIFT) - 1));
return phys;
}

View File

@@ -71,11 +71,6 @@ struct arp_pkt {
};
#pragma pack()
static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb)
{
return (struct arp_pkt *)skb_network_header(skb);
}
/* Forward declaration */
static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[],
bool strict_match);
@@ -574,10 +569,11 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip)
spin_unlock(&bond->mode_lock);
}
static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond)
static struct slave *rlb_choose_channel(struct sk_buff *skb,
struct bonding *bond,
const struct arp_pkt *arp)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct arp_pkt *arp = arp_pkt(skb);
struct slave *assigned_slave, *curr_active_slave;
struct rlb_client_info *client_info;
u32 hash_index = 0;
@@ -674,8 +670,12 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
*/
static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
{
struct arp_pkt *arp = arp_pkt(skb);
struct slave *tx_slave = NULL;
struct arp_pkt *arp;
if (!pskb_network_may_pull(skb, sizeof(*arp)))
return NULL;
arp = (struct arp_pkt *)skb_network_header(skb);
/* Don't modify or load balance ARPs that do not originate locally
* (e.g.,arrive via a bridge).
@@ -685,7 +685,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
if (arp->op_code == htons(ARPOP_REPLY)) {
/* the arp must be sent on the selected rx channel */
tx_slave = rlb_choose_channel(skb, bond);
tx_slave = rlb_choose_channel(skb, bond, arp);
if (tx_slave)
bond_hw_addr_copy(arp->mac_src, tx_slave->dev->dev_addr,
tx_slave->dev->addr_len);
@@ -696,7 +696,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
* When the arp reply is received the entry will be updated
* with the correct unicast address of the client.
*/
rlb_choose_channel(skb, bond);
rlb_choose_channel(skb, bond, arp);
/* The ARP reply packets must be delayed so that
* they can cancel out the influence of the ARP request.

View File

@@ -867,6 +867,7 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
= { .len = sizeof(struct can_bittiming) },
[IFLA_CAN_DATA_BITTIMING_CONST]
= { .len = sizeof(struct can_bittiming_const) },
[IFLA_CAN_TERMINATION] = { .type = NLA_U16 },
};
static int can_validate(struct nlattr *tb[], struct nlattr *data[],

View File

@@ -7310,13 +7310,13 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu)
struct bnxt *bp = netdev_priv(dev);
if (netif_running(dev))
bnxt_close_nic(bp, false, false);
bnxt_close_nic(bp, true, false);
dev->mtu = new_mtu;
bnxt_set_ring_params(bp);
if (netif_running(dev))
return bnxt_open_nic(bp, false, false);
return bnxt_open_nic(bp, true, false);
return 0;
}

View File

@@ -2478,15 +2478,15 @@ fec_enet_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *ec)
return -EINVAL;
}
cycle = fec_enet_us_to_itr_clock(ndev, fep->rx_time_itr);
cycle = fec_enet_us_to_itr_clock(ndev, ec->rx_coalesce_usecs);
if (cycle > 0xFFFF) {
pr_err("Rx coalesced usec exceed hardware limitation\n");
return -EINVAL;
}
cycle = fec_enet_us_to_itr_clock(ndev, fep->tx_time_itr);
cycle = fec_enet_us_to_itr_clock(ndev, ec->tx_coalesce_usecs);
if (cycle > 0xFFFF) {
pr_err("Rx coalesced usec exceed hardware limitation\n");
pr_err("Tx coalesced usec exceed hardware limitation\n");
return -EINVAL;
}

View File

@@ -312,6 +312,7 @@ static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth,
}
hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif);
hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT;
hw_ioctxt.cmdq_depth = 0;

View File

@@ -104,8 +104,8 @@ struct hinic_cmd_hw_ioctxt {
u8 rsvd2;
u8 rsvd3;
u8 ppf_idx;
u8 rsvd4;
u8 rsvd5;
u16 rq_depth;
u16 rx_buf_sz_idx;

View File

@@ -146,6 +146,7 @@
#define HINIC_HWIF_FUNC_IDX(hwif) ((hwif)->attr.func_idx)
#define HINIC_HWIF_PCI_INTF(hwif) ((hwif)->attr.pci_intf_idx)
#define HINIC_HWIF_PF_IDX(hwif) ((hwif)->attr.pf_idx)
#define HINIC_HWIF_PPF_IDX(hwif) ((hwif)->attr.ppf_idx)
#define HINIC_FUNC_TYPE(hwif) ((hwif)->attr.func_type)
#define HINIC_IS_PF(hwif) (HINIC_FUNC_TYPE(hwif) == HINIC_PF)

View File

@@ -831,14 +831,17 @@ static irqreturn_t ks_irq(int irq, void *pw)
{
struct net_device *netdev = pw;
struct ks_net *ks = netdev_priv(netdev);
unsigned long flags;
u16 status;
spin_lock_irqsave(&ks->statelock, flags);
/*this should be the first in IRQ handler */
ks_save_cmd_reg(ks);
status = ks_rdreg16(ks, KS_ISR);
if (unlikely(!status)) {
ks_restore_cmd_reg(ks);
spin_unlock_irqrestore(&ks->statelock, flags);
return IRQ_NONE;
}
@@ -864,6 +867,7 @@ static irqreturn_t ks_irq(int irq, void *pw)
ks->netdev->stats.rx_over_errors++;
/* this should be the last in IRQ handler*/
ks_restore_cmd_reg(ks);
spin_unlock_irqrestore(&ks->statelock, flags);
return IRQ_HANDLED;
}
@@ -933,6 +937,7 @@ static int ks_net_stop(struct net_device *netdev)
/* shutdown RX/TX QMU */
ks_disable_qmu(ks);
ks_disable_int(ks);
/* set powermode to soft power down to save power */
ks_set_powermode(ks, PMECR_PM_SOFTDOWN);
@@ -989,10 +994,9 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
netdev_tx_t retv = NETDEV_TX_OK;
struct ks_net *ks = netdev_priv(netdev);
unsigned long flags;
disable_irq(netdev->irq);
ks_disable_int(ks);
spin_lock(&ks->statelock);
spin_lock_irqsave(&ks->statelock, flags);
/* Extra space are required:
* 4 byte for alignment, 4 for status/length, 4 for CRC
@@ -1006,9 +1010,7 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev)
dev_kfree_skb(skb);
} else
retv = NETDEV_TX_BUSY;
spin_unlock(&ks->statelock);
ks_enable_int(ks);
enable_irq(netdev->irq);
spin_unlock_irqrestore(&ks->statelock, flags);
return retv;
}

View File

@@ -157,6 +157,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
int err = 0;
u16 mux_id;
if (!tb[IFLA_LINK]) {
NL_SET_ERR_MSG_MOD(extack, "link not specified");
return -EINVAL;
}
real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
if (!real_dev || !dev)
return -ENODEV;

View File

@@ -505,6 +505,7 @@ efx_copy_channel(const struct efx_channel *old_channel)
if (tx_queue->channel)
tx_queue->channel = channel;
tx_queue->buffer = NULL;
tx_queue->cb_page = NULL;
memset(&tx_queue->txd, 0, sizeof(tx_queue->txd));
}

View File

@@ -256,6 +256,7 @@ void ipvlan_process_multicast(struct work_struct *work)
}
if (dev)
dev_put(dev);
cond_resched();
}
}
@@ -448,19 +449,21 @@ static int ipvlan_process_outbound(struct sk_buff *skb)
struct ethhdr *ethh = eth_hdr(skb);
int ret = NET_XMIT_DROP;
/* In this mode we dont care about multicast and broadcast traffic */
if (is_multicast_ether_addr(ethh->h_dest)) {
pr_warn_ratelimited("Dropped {multi|broad}cast of type= [%x]\n",
ntohs(skb->protocol));
kfree_skb(skb);
goto out;
}
/* The ipvlan is a pseudo-L2 device, so the packets that we receive
* will have L2; which need to discarded and processed further
* in the net-ns of the main-device.
*/
if (skb_mac_header_was_set(skb)) {
/* In this mode we dont care about
* multicast and broadcast traffic */
if (is_multicast_ether_addr(ethh->h_dest)) {
pr_debug_ratelimited(
"Dropped {multi|broad}cast of type=[%x]\n",
ntohs(skb->protocol));
kfree_skb(skb);
goto out;
}
skb_pull(skb, sizeof(*ethh));
skb->mac_header = (typeof(skb->mac_header))~0U;
skb_reset_network_header(skb);

View File

@@ -236,7 +236,6 @@ static void ipvlan_uninit(struct net_device *dev)
static int ipvlan_open(struct net_device *dev)
{
struct ipvl_dev *ipvlan = netdev_priv(dev);
struct net_device *phy_dev = ipvlan->phy_dev;
struct ipvl_addr *addr;
if (ipvlan->port->mode == IPVLAN_MODE_L3 ||
@@ -248,7 +247,7 @@ static int ipvlan_open(struct net_device *dev)
list_for_each_entry(addr, &ipvlan->addrs, anode)
ipvlan_ht_addr_add(ipvlan, addr);
return dev_uc_add(phy_dev, phy_dev->dev_addr);
return 0;
}
static int ipvlan_stop(struct net_device *dev)
@@ -260,8 +259,6 @@ static int ipvlan_stop(struct net_device *dev)
dev_uc_unsync(phy_dev, dev);
dev_mc_unsync(phy_dev, dev);
dev_uc_del(phy_dev, phy_dev->dev_addr);
list_for_each_entry(addr, &ipvlan->addrs, anode)
ipvlan_ht_addr_del(addr);

View File

@@ -2871,6 +2871,11 @@ static void macsec_dev_set_rx_mode(struct net_device *dev)
dev_uc_sync(real_dev, dev);
}
static sci_t dev_to_sci(struct net_device *dev, __be16 port)
{
return make_sci(dev->dev_addr, port);
}
static int macsec_set_mac_address(struct net_device *dev, void *p)
{
struct macsec_dev *macsec = macsec_priv(dev);
@@ -2892,6 +2897,7 @@ static int macsec_set_mac_address(struct net_device *dev, void *p)
out:
ether_addr_copy(dev->dev_addr, addr->sa_data);
macsec->secy.sci = dev_to_sci(dev, MACSEC_PORT_ES);
return 0;
}
@@ -2974,6 +2980,7 @@ static const struct device_type macsec_type = {
static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = {
[IFLA_MACSEC_SCI] = { .type = NLA_U64 },
[IFLA_MACSEC_PORT] = { .type = NLA_U16 },
[IFLA_MACSEC_ICV_LEN] = { .type = NLA_U8 },
[IFLA_MACSEC_CIPHER_SUITE] = { .type = NLA_U64 },
[IFLA_MACSEC_WINDOW] = { .type = NLA_U32 },
@@ -3159,11 +3166,6 @@ static bool sci_exists(struct net_device *dev, sci_t sci)
return false;
}
static sci_t dev_to_sci(struct net_device *dev, __be16 port)
{
return make_sci(dev->dev_addr, port);
}
static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len)
{
struct macsec_dev *macsec = macsec_priv(dev);

View File

@@ -338,6 +338,8 @@ static void macvlan_process_broadcast(struct work_struct *w)
if (src)
dev_put(src->dev);
kfree_skb(skb);
cond_resched();
}
}

View File

@@ -76,7 +76,7 @@ static LIST_HEAD(phy_fixup_list);
static DEFINE_MUTEX(phy_fixup_lock);
#ifdef CONFIG_PM
static bool mdio_bus_phy_may_suspend(struct phy_device *phydev, bool suspend)
static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
{
struct device_driver *drv = phydev->mdio.dev.driver;
struct phy_driver *phydrv = to_phy_driver(drv);
@@ -88,11 +88,10 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev, bool suspend)
/* PHY not attached? May suspend if the PHY has not already been
* suspended as part of a prior call to phy_disconnect() ->
* phy_detach() -> phy_suspend() because the parent netdev might be the
* MDIO bus driver and clock gated at this point. Also may resume if
* PHY is not attached.
* MDIO bus driver and clock gated at this point.
*/
if (!netdev)
return suspend ? !phydev->suspended : phydev->suspended;
goto out;
/* Don't suspend PHY if the attached netdev parent may wakeup.
* The parent may point to a PCI device, as in tg3 driver.
@@ -107,7 +106,8 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev, bool suspend)
if (device_may_wakeup(&netdev->dev))
return false;
return true;
out:
return !phydev->suspended;
}
static int mdio_bus_phy_suspend(struct device *dev)
@@ -122,9 +122,11 @@ static int mdio_bus_phy_suspend(struct device *dev)
if (phydev->attached_dev && phydev->adjust_link)
phy_stop_machine(phydev);
if (!mdio_bus_phy_may_suspend(phydev, true))
if (!mdio_bus_phy_may_suspend(phydev))
return 0;
phydev->suspended_by_mdio_bus = true;
return phy_suspend(phydev);
}
@@ -133,9 +135,11 @@ static int mdio_bus_phy_resume(struct device *dev)
struct phy_device *phydev = to_phy_device(dev);
int ret;
if (!mdio_bus_phy_may_suspend(phydev, false))
if (!phydev->suspended_by_mdio_bus)
goto no_resume;
phydev->suspended_by_mdio_bus = false;
ret = phy_resume(phydev);
if (ret < 0)
return ret;

View File

@@ -232,7 +232,7 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize,
register struct cstate *cs = lcs->next;
register unsigned long deltaS, deltaA;
register short changes = 0;
int hlen;
int nlen, hlen;
unsigned char new_seq[16];
register unsigned char *cp = new_seq;
struct iphdr *ip;
@@ -248,6 +248,8 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize,
return isize;
ip = (struct iphdr *) icp;
if (ip->version != 4 || ip->ihl < 5)
return isize;
/* Bail if this packet isn't TCP, or is an IP fragment */
if (ip->protocol != IPPROTO_TCP || (ntohs(ip->frag_off) & 0x3fff)) {
@@ -258,10 +260,14 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize,
comp->sls_o_tcp++;
return isize;
}
/* Extract TCP header */
nlen = ip->ihl * 4;
if (isize < nlen + sizeof(*th))
return isize;
th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4);
hlen = ip->ihl*4 + th->doff*4;
th = (struct tcphdr *)(icp + nlen);
if (th->doff < sizeof(struct tcphdr) / 4)
return isize;
hlen = nlen + th->doff * 4;
/* Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or
* some other control bit is set). Also uncompressible if

View File

@@ -867,7 +867,10 @@ err_free_chan:
tty->disc_data = NULL;
clear_bit(SLF_INUSE, &sl->flags);
sl_free_netdev(sl->dev);
/* do not call free_netdev before rtnl_unlock */
rtnl_unlock();
free_netdev(sl->dev);
return err;
err_exit:
rtnl_unlock();

View File

@@ -2207,6 +2207,8 @@ team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = {
[TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG },
[TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 },
[TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY },
[TEAM_ATTR_OPTION_PORT_IFINDEX] = { .type = NLA_U32 },
[TEAM_ATTR_OPTION_ARRAY_INDEX] = { .type = NLA_U32 },
};
static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)

View File

@@ -274,6 +274,9 @@ static void qmi_wwan_netdev_setup(struct net_device *net)
netdev_dbg(net, "mode: raw IP\n");
} else if (!net->header_ops) { /* don't bother if already set */
ether_setup(net);
/* Restoring min/max mtu values set originally by usbnet */
net->min_mtu = 0;
net->max_mtu = ETH_MAX_MTU;
clear_bit(EVENT_NO_IP_ALIGN, &dev->flags);
netdev_dbg(net, "mode: Ethernet\n");
}

View File

@@ -2696,6 +2696,8 @@ static u16 r8153_phy_status(struct r8152 *tp, u16 desired)
}
msleep(20);
if (test_bit(RTL8152_UNPLUG, &tp->flags))
break;
}
return data;
@@ -4055,7 +4057,10 @@ static void r8153_init(struct r8152 *tp)
if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) &
AUTOLOAD_DONE)
break;
msleep(20);
if (test_bit(RTL8152_UNPLUG, &tp->flags))
break;
}
data = r8153_phy_status(tp, 0);
@@ -4170,7 +4175,10 @@ static void r8153b_init(struct r8152 *tp)
if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) &
AUTOLOAD_DONE)
break;
msleep(20);
if (test_bit(RTL8152_UNPLUG, &tp->flags))
break;
}
data = r8153_phy_status(tp, 0);

View File

@@ -326,7 +326,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
}
/* PHY_SKU section is mandatory in B0 */
if (!mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) {
if (mvm->trans->cfg->nvm_type == IWL_NVM_EXT &&
!mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) {
IWL_ERR(mvm,
"Can't parse phy_sku in B0, empty sections\n");
return NULL;

View File

@@ -2031,7 +2031,6 @@ static int pinctrl_claim_hogs(struct pinctrl_dev *pctldev)
return PTR_ERR(pctldev->p);
}
kref_get(&pctldev->p->users);
pctldev->hog_default =
pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT);
if (IS_ERR(pctldev->hog_default)) {

View File

@@ -158,8 +158,8 @@ static const unsigned int sdio_d0_pins[] = { PIN(GPIOX_0, EE_OFF) };
static const unsigned int sdio_d1_pins[] = { PIN(GPIOX_1, EE_OFF) };
static const unsigned int sdio_d2_pins[] = { PIN(GPIOX_2, EE_OFF) };
static const unsigned int sdio_d3_pins[] = { PIN(GPIOX_3, EE_OFF) };
static const unsigned int sdio_cmd_pins[] = { PIN(GPIOX_4, EE_OFF) };
static const unsigned int sdio_clk_pins[] = { PIN(GPIOX_5, EE_OFF) };
static const unsigned int sdio_clk_pins[] = { PIN(GPIOX_4, EE_OFF) };
static const unsigned int sdio_cmd_pins[] = { PIN(GPIOX_5, EE_OFF) };
static const unsigned int sdio_irq_pins[] = { PIN(GPIOX_7, EE_OFF) };
static const unsigned int nand_ce0_pins[] = { PIN(BOOT_8, EE_OFF) };

View File

@@ -652,6 +652,8 @@ redisc:
}
out:
kref_put(&rdata->kref, fc_rport_destroy);
if (!IS_ERR(fp))
fc_frame_free(fp);
}
/**

View File

@@ -562,7 +562,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
if (server->ops->close)
server->ops->close(xid, tcon, &fid);
cifs_del_pending_open(&open);
fput(file);
rc = -ENOMEM;
}

View File

@@ -1255,7 +1255,7 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry,
if (!(*opened & FILE_OPENED))
return finish_no_open(file, d);
dput(d);
return 0;
return excl && (flags & O_CREAT) ? -EEXIST : 0;
}
BUG_ON(d != NULL);

View File

@@ -1050,8 +1050,8 @@ static bool jbd2_write_access_granted(handle_t *handle, struct buffer_head *bh,
/* For undo access buffer must have data copied */
if (undo && !jh->b_committed_data)
goto out;
if (jh->b_transaction != handle->h_transaction &&
jh->b_next_transaction != handle->h_transaction)
if (READ_ONCE(jh->b_transaction) != handle->h_transaction &&
READ_ONCE(jh->b_next_transaction) != handle->h_transaction)
goto out;
/*
* There are two reasons for the barrier here:
@@ -2466,8 +2466,8 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh)
* our jh reference and thus __jbd2_journal_file_buffer() must not
* take a new one.
*/
jh->b_transaction = jh->b_next_transaction;
jh->b_next_transaction = NULL;
WRITE_ONCE(jh->b_transaction, jh->b_next_transaction);
WRITE_ONCE(jh->b_next_transaction, NULL);
if (buffer_freed(bh))
jlist = BJ_Forget;
else if (jh->b_modified)

View File

@@ -836,9 +836,6 @@ cleanup_file:
* the return value of d_splice_alias(), then the caller needs to perform dput()
* on it after finish_open().
*
* On successful return @file is a fully instantiated open file. After this, if
* an error occurs in ->atomic_open(), it needs to clean up with fput().
*
* Returns zero on success or -errno if the open failed.
*/
int finish_open(struct file *file, struct dentry *dentry,

View File

@@ -2,15 +2,10 @@
#ifndef _INET_DIAG_H_
#define _INET_DIAG_H_ 1
#include <net/netlink.h>
#include <uapi/linux/inet_diag.h>
struct net;
struct sock;
struct inet_hashinfo;
struct nlattr;
struct nlmsghdr;
struct sk_buff;
struct netlink_callback;
struct inet_diag_handler {
void (*dump)(struct sk_buff *skb,
@@ -62,6 +57,17 @@ int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk);
void inet_diag_msg_common_fill(struct inet_diag_msg *r, struct sock *sk);
static inline size_t inet_diag_msg_attrs_size(void)
{
return nla_total_size(1) /* INET_DIAG_SHUTDOWN */
+ nla_total_size(1) /* INET_DIAG_TOS */
#if IS_ENABLED(CONFIG_IPV6)
+ nla_total_size(1) /* INET_DIAG_TCLASS */
+ nla_total_size(1) /* INET_DIAG_SKV6ONLY */
#endif
+ nla_total_size(4) /* INET_DIAG_MARK */
+ nla_total_size(4); /* INET_DIAG_CLASS_ID */
}
int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
struct inet_diag_msg *r, int ext,
struct user_namespace *user_ns, bool net_admin);

View File

@@ -372,6 +372,7 @@ struct phy_c45_device_ids {
* is_pseudo_fixed_link: Set to true if this phy is an Ethernet switch, etc.
* has_fixups: Set to true if this phy has fixups/quirks.
* suspended: Set to true if this phy has been suspended successfully.
* suspended_by_mdio_bus: Set to true if this phy was suspended by MDIO bus.
* sysfs_links: Internal boolean tracking sysfs symbolic links setup/removal.
* loopback_enabled: Set true if this phy has been loopbacked successfully.
* state: state of the PHY for management purposes
@@ -410,6 +411,7 @@ struct phy_device {
bool is_pseudo_fixed_link;
bool has_fixups;
bool suspended;
bool suspended_by_mdio_bus;
bool sysfs_links;
bool loopback_enabled;

View File

@@ -102,6 +102,7 @@ struct fib_rule_notifier_info {
[FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
[FRA_PRIORITY] = { .type = NLA_U32 }, \
[FRA_FWMARK] = { .type = NLA_U32 }, \
[FRA_TUN_ID] = { .type = NLA_U64 }, \
[FRA_FWMASK] = { .type = NLA_U32 }, \
[FRA_TABLE] = { .type = NLA_U32 }, \
[FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \

View File

@@ -4348,6 +4348,9 @@ static void *cgroup_procs_next(struct seq_file *s, void *v, loff_t *pos)
struct kernfs_open_file *of = s->private;
struct css_task_iter *it = of->priv;
if (pos)
(*pos)++;
return css_task_iter_next(it);
}
@@ -4363,7 +4366,7 @@ static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos,
* from position 0, so we can simply keep iterating on !0 *pos.
*/
if (!it) {
if (WARN_ON_ONCE((*pos)++))
if (WARN_ON_ONCE((*pos)))
return ERR_PTR(-EINVAL);
it = kzalloc(sizeof(*it), GFP_KERNEL);
@@ -4371,10 +4374,11 @@ static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos,
return ERR_PTR(-ENOMEM);
of->priv = it;
css_task_iter_start(&cgrp->self, iter_flags, it);
} else if (!(*pos)++) {
} else if (!(*pos)) {
css_task_iter_end(it);
css_task_iter_start(&cgrp->self, iter_flags, it);
}
} else
return it->cur_task;
return cgroup_procs_next(s, NULL, NULL);
}
@@ -5934,6 +5938,10 @@ void cgroup_sk_alloc(struct sock_cgroup_data *skcd)
return;
}
/* Don't associate the sock with unrelated interrupted task's cgroup. */
if (in_interrupt())
return;
rcu_read_lock();
while (true) {

View File

@@ -381,27 +381,32 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
{
struct sigqueue *q = NULL;
struct user_struct *user;
int sigpending;
/*
* Protect access to @t credentials. This can go away when all
* callers hold rcu read lock.
*
* NOTE! A pending signal will hold on to the user refcount,
* and we get/put the refcount only when the sigpending count
* changes from/to zero.
*/
rcu_read_lock();
user = get_uid(__task_cred(t)->user);
atomic_inc(&user->sigpending);
user = __task_cred(t)->user;
sigpending = atomic_inc_return(&user->sigpending);
if (sigpending == 1)
get_uid(user);
rcu_read_unlock();
if (override_rlimit ||
atomic_read(&user->sigpending) <=
task_rlimit(t, RLIMIT_SIGPENDING)) {
if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
q = kmem_cache_alloc(sigqueue_cachep, flags);
} else {
print_dropped_signal(sig);
}
if (unlikely(q == NULL)) {
atomic_dec(&user->sigpending);
free_uid(user);
if (atomic_dec_and_test(&user->sigpending))
free_uid(user);
} else {
INIT_LIST_HEAD(&q->list);
q->flags = 0;
@@ -415,8 +420,8 @@ static void __sigqueue_free(struct sigqueue *q)
{
if (q->flags & SIGQUEUE_PREALLOC)
return;
atomic_dec(&q->user->sigpending);
free_uid(q->user);
if (atomic_dec_and_test(&q->user->sigpending))
free_uid(q->user);
kmem_cache_free(sigqueue_cachep, q);
}

View File

@@ -1406,14 +1406,16 @@ static void __queue_work(int cpu, struct workqueue_struct *wq,
WARN_ON_ONCE(!is_chained_work(wq)))
return;
retry:
if (req_cpu == WORK_CPU_UNBOUND)
cpu = wq_select_unbound_cpu(raw_smp_processor_id());
/* pwq which will be used unless @work is executing elsewhere */
if (!(wq->flags & WQ_UNBOUND))
pwq = per_cpu_ptr(wq->cpu_pwqs, cpu);
else
if (wq->flags & WQ_UNBOUND) {
if (req_cpu == WORK_CPU_UNBOUND)
cpu = wq_select_unbound_cpu(raw_smp_processor_id());
pwq = unbound_pwq_by_node(wq, cpu_to_node(cpu));
} else {
if (req_cpu == WORK_CPU_UNBOUND)
cpu = raw_smp_processor_id();
pwq = per_cpu_ptr(wq->cpu_pwqs, cpu);
}
/*
* If @work was previously on a different pool, it might still be

View File

@@ -5867,19 +5867,9 @@ void mem_cgroup_sk_alloc(struct sock *sk)
if (!mem_cgroup_sockets_enabled)
return;
/*
* Socket cloning can throw us here with sk_memcg already
* filled. It won't however, necessarily happen from
* process context. So the test for root memcg given
* the current task's memcg won't help us in this case.
*
* Respecting the original socket's memcg is a better
* decision in this case.
*/
if (sk->sk_memcg) {
css_get(&sk->sk_memcg->css);
/* Do not associate the sock with unrelated interrupted task's memcg. */
if (in_interrupt())
return;
}
rcu_read_lock();
memcg = mem_cgroup_from_task(current);

View File

@@ -3175,6 +3175,15 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
void *object = c->freelist;
if (unlikely(!object)) {
/*
* We may have removed an object from c->freelist using
* the fastpath in the previous iteration; in that case,
* c->tid has not been bumped yet.
* Since ___slab_alloc() may reenable interrupts while
* allocating memory, we should bump c->tid now.
*/
c->tid = next_tid(c->tid);
/*
* Invoking slow path likely have side-effect
* of re-populating per CPU c->freelist

View File

@@ -34,6 +34,7 @@
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/pkt_sched.h>
@@ -149,7 +150,7 @@ static void batadv_iv_ogm_orig_free(struct batadv_orig_node *orig_node)
* Return: 0 on success, a negative error code otherwise.
*/
static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node,
int max_if_num)
unsigned int max_if_num)
{
void *data_ptr;
size_t old_size;
@@ -193,7 +194,8 @@ unlock:
*/
static void
batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node,
int max_if_num, int del_if_num)
unsigned int max_if_num,
unsigned int del_if_num)
{
size_t chunk_size;
size_t if_offset;
@@ -231,7 +233,8 @@ batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node,
*/
static void
batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node,
int max_if_num, int del_if_num)
unsigned int max_if_num,
unsigned int del_if_num)
{
size_t if_offset;
void *data_ptr;
@@ -268,7 +271,8 @@ batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node,
* Return: 0 on success, a negative error code otherwise.
*/
static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node,
int max_if_num, int del_if_num)
unsigned int max_if_num,
unsigned int del_if_num)
{
spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
@@ -302,7 +306,8 @@ static struct batadv_orig_node *
batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
{
struct batadv_orig_node *orig_node;
int size, hash_added;
int hash_added;
size_t size;
orig_node = batadv_orig_hash_find(bat_priv, addr);
if (orig_node)
@@ -366,14 +371,18 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
unsigned char *ogm_buff;
u32 random_seqno;
mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
/* randomize initial seqno to avoid collision */
get_random_bytes(&random_seqno, sizeof(random_seqno));
atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
if (!ogm_buff)
if (!ogm_buff) {
mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
return -ENOMEM;
}
hard_iface->bat_iv.ogm_buff = ogm_buff;
@@ -385,35 +394,59 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
batadv_ogm_packet->reserved = 0;
batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
return 0;
}
static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
{
mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
kfree(hard_iface->bat_iv.ogm_buff);
hard_iface->bat_iv.ogm_buff = NULL;
mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
}
static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
{
struct batadv_ogm_packet *batadv_ogm_packet;
unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
void *ogm_buff;
batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
ogm_buff = hard_iface->bat_iv.ogm_buff;
if (!ogm_buff)
goto unlock;
batadv_ogm_packet = ogm_buff;
ether_addr_copy(batadv_ogm_packet->orig,
hard_iface->net_dev->dev_addr);
ether_addr_copy(batadv_ogm_packet->prev_sender,
hard_iface->net_dev->dev_addr);
unlock:
mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
}
static void
batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
{
struct batadv_ogm_packet *batadv_ogm_packet;
unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
void *ogm_buff;
batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
ogm_buff = hard_iface->bat_iv.ogm_buff;
if (!ogm_buff)
goto unlock;
batadv_ogm_packet = ogm_buff;
batadv_ogm_packet->ttl = BATADV_TTL;
unlock:
mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
}
/* when do we schedule our own ogm to be sent */
@@ -890,7 +923,7 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
u32 i;
size_t word_index;
u8 *w;
int if_num;
unsigned int if_num;
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -911,7 +944,11 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
}
}
static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
/**
* batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer
* @hard_iface: interface whose ogm buffer should be transmitted
*/
static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
@@ -922,8 +959,10 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
u16 tvlv_len = 0;
unsigned long send_time;
if ((hard_iface->if_status == BATADV_IF_NOT_IN_USE) ||
(hard_iface->if_status == BATADV_IF_TO_BE_REMOVED))
lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
/* interface already disabled by batadv_iv_ogm_iface_disable */
if (!*ogm_buff)
return;
/* the interface gets activated here to avoid race conditions between
@@ -992,6 +1031,17 @@ out:
batadv_hardif_put(primary_if);
}
static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
{
if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
return;
mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
batadv_iv_ogm_schedule_buff(hard_iface);
mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
}
/**
* batadv_iv_ogm_orig_update - use OGM to update corresponding data in an
* originator
@@ -1020,7 +1070,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
struct batadv_neigh_node *tmp_neigh_node = NULL;
struct batadv_neigh_node *router = NULL;
struct batadv_orig_node *orig_node_tmp;
int if_num;
unsigned int if_num;
u8 sum_orig, sum_neigh;
u8 *neigh_addr;
u8 tq_avg;
@@ -1179,7 +1229,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
u8 total_count;
u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
int if_num;
unsigned int if_num;
unsigned int tq_asym_penalty, inv_asym_penalty;
unsigned int combined_tq;
unsigned int tq_iface_penalty;
@@ -1220,7 +1270,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
orig_node->last_seen = jiffies;
/* find packet count of corresponding one hop neighbor */
spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
if_num = if_incoming->if_num;
orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num];
neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
@@ -1230,7 +1280,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
} else {
neigh_rq_count = 0;
}
spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
/* pay attention to not get a value bigger than 100 % */
if (orig_eq_count > neigh_rq_count)
@@ -1698,9 +1748,9 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
if (is_my_orig) {
unsigned long *word;
int offset;
size_t offset;
s32 bit_pos;
s16 if_num;
unsigned int if_num;
u8 *weight;
orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
@@ -2477,7 +2527,7 @@ batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1,
return ret;
}
static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface)
static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
{
/* begin scheduling originator messages on that interface */
batadv_iv_ogm_schedule(hard_iface);
@@ -2817,8 +2867,8 @@ unlock:
static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
.name = "BATMAN_IV",
.iface = {
.activate = batadv_iv_iface_activate,
.enable = batadv_iv_ogm_iface_enable,
.enabled = batadv_iv_iface_enabled,
.disable = batadv_iv_ogm_iface_disable,
.update_mac = batadv_iv_ogm_iface_update_mac,
.primary_set = batadv_iv_ogm_primary_iface_set,

View File

@@ -19,7 +19,6 @@
#include "main.h"
#include <linux/atomic.h>
#include <linux/bug.h>
#include <linux/cache.h>
#include <linux/errno.h>
#include <linux/if_ether.h>
@@ -623,11 +622,11 @@ static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1,
int ret = 0;
ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
if (WARN_ON(!ifinfo1))
if (!ifinfo1)
goto err_ifinfo1;
ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
if (WARN_ON(!ifinfo2))
if (!ifinfo2)
goto err_ifinfo2;
ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput;
@@ -649,11 +648,11 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
bool ret = false;
ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
if (WARN_ON(!ifinfo1))
if (!ifinfo1)
goto err_ifinfo1;
ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
if (WARN_ON(!ifinfo2))
if (!ifinfo2)
goto err_ifinfo2;
threshold = ifinfo1->bat_v.throughput / 4;
@@ -815,7 +814,7 @@ static bool batadv_v_gw_is_eligible(struct batadv_priv *bat_priv,
}
orig_gw = batadv_gw_node_get(bat_priv, orig_node);
if (!orig_node)
if (!orig_gw)
goto out;
if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0)

View File

@@ -28,6 +28,8 @@
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/random.h>
#include <linux/rculist.h>
@@ -127,14 +129,12 @@ static void batadv_v_ogm_send_to_if(struct sk_buff *skb,
}
/**
* batadv_v_ogm_send - periodic worker broadcasting the own OGM
* @work: work queue item
* batadv_v_ogm_send_softif() - periodic worker broadcasting the own OGM
* @bat_priv: the bat priv with all the soft interface information
*/
static void batadv_v_ogm_send(struct work_struct *work)
static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv)
{
struct batadv_hard_iface *hard_iface;
struct batadv_priv_bat_v *bat_v;
struct batadv_priv *bat_priv;
struct batadv_ogm2_packet *ogm_packet;
struct sk_buff *skb, *skb_tmp;
unsigned char *ogm_buff;
@@ -142,8 +142,7 @@ static void batadv_v_ogm_send(struct work_struct *work)
u16 tvlv_len = 0;
int ret;
bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex);
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
goto out;
@@ -234,6 +233,23 @@ out:
return;
}
/**
* batadv_v_ogm_send() - periodic worker broadcasting the own OGM
* @work: work queue item
*/
static void batadv_v_ogm_send(struct work_struct *work)
{
struct batadv_priv_bat_v *bat_v;
struct batadv_priv *bat_priv;
bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
batadv_v_ogm_send_softif(bat_priv);
mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
}
/**
* batadv_v_ogm_iface_enable - prepare an interface for B.A.T.M.A.N. V
* @hard_iface: the interface to prepare
@@ -260,11 +276,15 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface)
struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
struct batadv_ogm2_packet *ogm_packet;
mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
if (!bat_priv->bat_v.ogm_buff)
return;
goto unlock;
ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff;
ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr);
unlock:
mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
}
/**
@@ -886,6 +906,8 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv)
atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno);
INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send);
mutex_init(&bat_priv->bat_v.ogm_buff_mutex);
return 0;
}
@@ -897,7 +919,11 @@ void batadv_v_ogm_free(struct batadv_priv *bat_priv)
{
cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq);
mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
kfree(bat_priv->bat_v.ogm_buff);
bat_priv->bat_v.ogm_buff = NULL;
bat_priv->bat_v.ogm_buff_len = 0;
mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
}

View File

@@ -18,6 +18,7 @@
#include "debugfs.h"
#include "main.h"
#include <linux/dcache.h>
#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/errno.h>
@@ -338,7 +339,26 @@ out:
}
/**
* batadv_debugfs_del_hardif - delete the base directory for a hard interface
* batadv_debugfs_rename_hardif() - Fix debugfs path for renamed hardif
* @hard_iface: hard interface which was renamed
*/
void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface)
{
const char *name = hard_iface->net_dev->name;
struct dentry *dir;
struct dentry *d;
dir = hard_iface->debug_dir;
if (!dir)
return;
d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name);
if (!d)
pr_err("Can't rename debugfs dir to %s\n", name);
}
/**
* batadv_debugfs_del_hardif() - delete the base directory for a hard interface
* in debugfs.
* @hard_iface: hard interface which is deleted.
*/
@@ -401,6 +421,30 @@ out:
return -ENOMEM;
}
/**
* batadv_debugfs_rename_meshif() - Fix debugfs path for renamed softif
* @dev: net_device which was renamed
*/
void batadv_debugfs_rename_meshif(struct net_device *dev)
{
struct batadv_priv *bat_priv = netdev_priv(dev);
const char *name = dev->name;
struct dentry *dir;
struct dentry *d;
dir = bat_priv->debug_dir;
if (!dir)
return;
d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name);
if (!d)
pr_err("Can't rename debugfs dir to %s\n", name);
}
/**
* batadv_debugfs_del_meshif() - Remove interface dependent debugfs entries
* @dev: netdev struct of the soft interface
*/
void batadv_debugfs_del_meshif(struct net_device *dev)
{
struct batadv_priv *bat_priv = netdev_priv(dev);

View File

@@ -29,8 +29,10 @@ struct net_device;
void batadv_debugfs_init(void);
void batadv_debugfs_destroy(void);
int batadv_debugfs_add_meshif(struct net_device *dev);
void batadv_debugfs_rename_meshif(struct net_device *dev);
void batadv_debugfs_del_meshif(struct net_device *dev);
int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface);
void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface);
void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface);
#else
@@ -48,6 +50,10 @@ static inline int batadv_debugfs_add_meshif(struct net_device *dev)
return 0;
}
static inline void batadv_debugfs_rename_meshif(struct net_device *dev)
{
}
static inline void batadv_debugfs_del_meshif(struct net_device *dev)
{
}
@@ -58,6 +64,11 @@ int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface)
return 0;
}
static inline
void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface)
{
}
static inline
void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface)
{

View File

@@ -500,6 +500,8 @@ int batadv_frag_send_packet(struct sk_buff *skb,
*/
if (skb->priority >= 256 && skb->priority <= 263)
frag_header.priority = skb->priority - 256;
else
frag_header.priority = 0;
ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr);
ether_addr_copy(frag_header.dest, orig_node->orig);

View File

@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/printk.h>
#include <linux/rculist.h>
@@ -738,6 +739,11 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
hard_iface->soft_iface = soft_iface;
bat_priv = netdev_priv(hard_iface->soft_iface);
if (bat_priv->num_ifaces >= UINT_MAX) {
ret = -ENOSPC;
goto err_dev;
}
ret = netdev_master_upper_dev_link(hard_iface->net_dev,
soft_iface, NULL, NULL);
if (ret)
@@ -790,6 +796,9 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
batadv_hardif_recalc_extra_skbroom(soft_iface);
if (bat_priv->algo_ops->iface.enabled)
bat_priv->algo_ops->iface.enabled(hard_iface);
out:
return 0;
@@ -845,7 +854,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
/* nobody uses this interface anymore */
if (!bat_priv->num_ifaces) {
if (bat_priv->num_ifaces == 0) {
batadv_gw_check_client_stop(bat_priv);
if (autodel == BATADV_IF_CLEANUP_AUTO)
@@ -881,7 +890,7 @@ batadv_hardif_add_interface(struct net_device *net_dev)
if (ret)
goto free_if;
hard_iface->if_num = -1;
hard_iface->if_num = 0;
hard_iface->net_dev = net_dev;
hard_iface->soft_iface = NULL;
hard_iface->if_status = BATADV_IF_NOT_IN_USE;
@@ -893,6 +902,7 @@ batadv_hardif_add_interface(struct net_device *net_dev)
INIT_LIST_HEAD(&hard_iface->list);
INIT_HLIST_HEAD(&hard_iface->neigh_list);
mutex_init(&hard_iface->bat_iv.ogm_buff_mutex);
spin_lock_init(&hard_iface->neigh_list_lock);
kref_init(&hard_iface->refcount);
@@ -950,6 +960,32 @@ void batadv_hardif_remove_interfaces(void)
rtnl_unlock();
}
/**
* batadv_hard_if_event_softif() - Handle events for soft interfaces
* @event: NETDEV_* event to handle
* @net_dev: net_device which generated an event
*
* Return: NOTIFY_* result
*/
static int batadv_hard_if_event_softif(unsigned long event,
struct net_device *net_dev)
{
struct batadv_priv *bat_priv;
switch (event) {
case NETDEV_REGISTER:
batadv_sysfs_add_meshif(net_dev);
bat_priv = netdev_priv(net_dev);
batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
break;
case NETDEV_CHANGENAME:
batadv_debugfs_rename_meshif(net_dev);
break;
}
return NOTIFY_DONE;
}
static int batadv_hard_if_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
@@ -958,12 +994,8 @@ static int batadv_hard_if_event(struct notifier_block *this,
struct batadv_hard_iface *primary_if = NULL;
struct batadv_priv *bat_priv;
if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) {
batadv_sysfs_add_meshif(net_dev);
bat_priv = netdev_priv(net_dev);
batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
return NOTIFY_DONE;
}
if (batadv_softif_is_valid(net_dev))
return batadv_hard_if_event_softif(event, net_dev);
hard_iface = batadv_hardif_get_by_netdev(net_dev);
if (!hard_iface && (event == NETDEV_REGISTER ||
@@ -1012,6 +1044,9 @@ static int batadv_hard_if_event(struct notifier_block *this,
if (batadv_is_wifi_hardif(hard_iface))
hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
break;
case NETDEV_CHANGENAME:
batadv_debugfs_rename_hardif(hard_iface);
break;
default:
break;
}

View File

@@ -1500,7 +1500,7 @@ int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb)
}
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
int max_if_num)
unsigned int max_if_num)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batadv_algo_ops *bao = bat_priv->algo_ops;
@@ -1535,7 +1535,7 @@ err:
}
int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
int max_if_num)
unsigned int max_if_num)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batadv_hashtable *hash = bat_priv->orig_hash;

View File

@@ -78,9 +78,9 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset);
int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb);
int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset);
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
int max_if_num);
unsigned int max_if_num);
int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
int max_if_num);
unsigned int max_if_num);
struct batadv_orig_node_vlan *
batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
unsigned short vid);

View File

@@ -950,14 +950,10 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
struct batadv_orig_node *orig_node = NULL, *orig_node_gw = NULL;
int check, hdr_size = sizeof(*unicast_packet);
enum batadv_subtype subtype;
struct ethhdr *ethhdr;
int ret = NET_RX_DROP;
bool is4addr, is_gw;
unicast_packet = (struct batadv_unicast_packet *)skb->data;
unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
ethhdr = eth_hdr(skb);
is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR;
/* the caller function should have already pulled 2 bytes */
if (is4addr)
@@ -977,12 +973,14 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size))
goto free_skb;
unicast_packet = (struct batadv_unicast_packet *)skb->data;
/* packet for me */
if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
/* If this is a unicast packet from another backgone gw,
* drop it.
*/
orig_addr_gw = ethhdr->h_source;
orig_addr_gw = eth_hdr(skb)->h_source;
orig_node_gw = batadv_orig_hash_find(bat_priv, orig_addr_gw);
if (orig_node_gw) {
is_gw = batadv_bla_is_backbone_gw(skb, orig_node_gw,
@@ -997,6 +995,8 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
}
if (is4addr) {
unicast_4addr_packet =
(struct batadv_unicast_4addr_packet *)skb->data;
subtype = unicast_4addr_packet->subtype;
batadv_dat_inc_counter(bat_priv, subtype);

View File

@@ -872,7 +872,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
struct batadv_orig_node_vlan *vlan;
u8 *tt_change_ptr;
rcu_read_lock();
spin_lock_bh(&orig_node->vlan_list_lock);
hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
num_vlan++;
num_entries += atomic_read(&vlan->tt.num_entries);
@@ -910,7 +910,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
out:
rcu_read_unlock();
spin_unlock_bh(&orig_node->vlan_list_lock);
return tvlv_len;
}
@@ -941,15 +941,20 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
struct batadv_tvlv_tt_vlan_data *tt_vlan;
struct batadv_softif_vlan *vlan;
u16 num_vlan = 0;
u16 num_entries = 0;
u16 vlan_entries = 0;
u16 total_entries = 0;
u16 tvlv_len;
u8 *tt_change_ptr;
int change_offset;
rcu_read_lock();
spin_lock_bh(&bat_priv->softif_vlan_list_lock);
hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
vlan_entries = atomic_read(&vlan->tt.num_entries);
if (vlan_entries < 1)
continue;
num_vlan++;
num_entries += atomic_read(&vlan->tt.num_entries);
total_entries += vlan_entries;
}
change_offset = sizeof(**tt_data);
@@ -957,7 +962,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
/* if tt_len is negative, allocate the space needed by the full table */
if (*tt_len < 0)
*tt_len = batadv_tt_len(num_entries);
*tt_len = batadv_tt_len(total_entries);
tvlv_len = *tt_len;
tvlv_len += change_offset;
@@ -974,6 +979,10 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
vlan_entries = atomic_read(&vlan->tt.num_entries);
if (vlan_entries < 1)
continue;
tt_vlan->vid = htons(vlan->vid);
tt_vlan->crc = htonl(vlan->tt.crc);
@@ -984,7 +993,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
out:
rcu_read_unlock();
spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
return tvlv_len;
}
@@ -1544,6 +1553,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
* by a given originator
* @entry: the TT global entry to check
* @orig_node: the originator to search in the list
* @flags: a pointer to store TT flags for the given @entry received
* from @orig_node
*
* find out if an orig_node is already in the list of a tt_global_entry.
*
@@ -1551,7 +1562,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
*/
static bool
batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
const struct batadv_orig_node *orig_node)
const struct batadv_orig_node *orig_node,
u8 *flags)
{
struct batadv_tt_orig_list_entry *orig_entry;
bool found = false;
@@ -1559,6 +1571,10 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
if (orig_entry) {
found = true;
if (flags)
*flags = orig_entry->flags;
batadv_tt_orig_list_entry_put(orig_entry);
}
@@ -1741,7 +1757,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
if (!(common->flags & BATADV_TT_CLIENT_TEMP))
goto out;
if (batadv_tt_global_entry_has_orig(tt_global_entry,
orig_node))
orig_node, NULL))
goto out_remove;
batadv_tt_global_del_orig_list(tt_global_entry);
goto add_orig_entry;
@@ -2884,23 +2900,46 @@ unlock:
}
/**
* batadv_tt_local_valid - verify that given tt entry is a valid one
* batadv_tt_local_valid() - verify local tt entry and get flags
* @entry_ptr: to be checked local tt entry
* @data_ptr: not used but definition required to satisfy the callback prototype
* @flags: a pointer to store TT flags for this client to
*
* Checks the validity of the given local TT entry. If it is, then the provided
* flags pointer is updated.
*
* Return: true if the entry is a valid, false otherwise.
*/
static bool batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr)
static bool batadv_tt_local_valid(const void *entry_ptr,
const void *data_ptr,
u8 *flags)
{
const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
return false;
if (flags)
*flags = tt_common_entry->flags;
return true;
}
/**
* batadv_tt_global_valid() - verify global tt entry and get flags
* @entry_ptr: to be checked global tt entry
* @data_ptr: an orig_node object (may be NULL)
* @flags: a pointer to store TT flags for this client to
*
* Checks the validity of the given global TT entry. If it is, then the provided
* flags pointer is updated either with the common (summed) TT flags if data_ptr
* is NULL or the specific, per originator TT flags otherwise.
*
* Return: true if the entry is a valid, false otherwise.
*/
static bool batadv_tt_global_valid(const void *entry_ptr,
const void *data_ptr)
const void *data_ptr,
u8 *flags)
{
const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
const struct batadv_tt_global_entry *tt_global_entry;
@@ -2914,7 +2953,8 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
struct batadv_tt_global_entry,
common);
return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node,
flags);
}
/**
@@ -2924,25 +2964,34 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
* @hash: hash table containing the tt entries
* @tt_len: expected tvlv tt data buffer length in number of bytes
* @tvlv_buff: pointer to the buffer to fill with the TT data
* @valid_cb: function to filter tt change entries
* @valid_cb: function to filter tt change entries and to return TT flags
* @cb_data: data passed to the filter function as argument
*
* Fills the tvlv buff with the tt entries from the specified hash. If valid_cb
* is not provided then this becomes a no-op.
*/
static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
struct batadv_hashtable *hash,
void *tvlv_buff, u16 tt_len,
bool (*valid_cb)(const void *,
const void *),
const void *,
u8 *flags),
void *cb_data)
{
struct batadv_tt_common_entry *tt_common_entry;
struct batadv_tvlv_tt_change *tt_change;
struct hlist_head *head;
u16 tt_tot, tt_num_entries = 0;
u8 flags;
bool ret;
u32 i;
tt_tot = batadv_tt_entries(tt_len);
tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
if (!valid_cb)
return;
rcu_read_lock();
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -2952,11 +3001,12 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
if (tt_tot == tt_num_entries)
break;
if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
ret = valid_cb(tt_common_entry, cb_data, &flags);
if (!ret)
continue;
ether_addr_copy(tt_change->addr, tt_common_entry->addr);
tt_change->flags = tt_common_entry->flags;
tt_change->flags = flags;
tt_change->vid = htons(tt_common_entry->vid);
memset(tt_change->reserved, 0,
sizeof(tt_change->reserved));

View File

@@ -27,6 +27,7 @@
#include <linux/compiler.h>
#include <linux/if_ether.h>
#include <linux/kref.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/sched.h> /* for linux/wait.h */
@@ -81,11 +82,13 @@ enum batadv_dhcp_recipient {
* @ogm_buff: buffer holding the OGM packet
* @ogm_buff_len: length of the OGM packet buffer
* @ogm_seqno: OGM sequence number - used to identify each OGM
* @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len
*/
struct batadv_hard_iface_bat_iv {
unsigned char *ogm_buff;
int ogm_buff_len;
atomic_t ogm_seqno;
struct mutex ogm_buff_mutex;
};
/**
@@ -155,7 +158,7 @@ enum batadv_hard_iface_wifi_flags {
*/
struct batadv_hard_iface {
struct list_head list;
s16 if_num;
unsigned int if_num;
char if_status;
u8 num_bcasts;
u32 wifi_flags;
@@ -989,12 +992,14 @@ struct batadv_softif_vlan {
* @ogm_buff: buffer holding the OGM packet
* @ogm_buff_len: length of the OGM packet buffer
* @ogm_seqno: OGM sequence number - used to identify each OGM
* @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len
* @ogm_wq: workqueue used to schedule OGM transmissions
*/
struct batadv_priv_bat_v {
unsigned char *ogm_buff;
int ogm_buff_len;
atomic_t ogm_seqno;
struct mutex ogm_buff_mutex;
struct delayed_work ogm_wq;
};
@@ -1081,7 +1086,7 @@ struct batadv_priv {
atomic_t bcast_seqno;
atomic_t bcast_queue_left;
atomic_t batman_queue_left;
char num_ifaces;
unsigned int num_ifaces;
struct kobject *mesh_obj;
struct dentry *debug_dir;
struct hlist_head forw_bat_list;
@@ -1424,6 +1429,7 @@ struct batadv_forw_packet {
* @activate: start routing mechanisms when hard-interface is brought up
* (optional)
* @enable: init routing info when hard-interface is enabled
* @enabled: notification when hard-interface was enabled (optional)
* @disable: de-init routing info when hard-interface is disabled
* @update_mac: (re-)init mac addresses of the protocol information
* belonging to this hard-interface
@@ -1432,6 +1438,7 @@ struct batadv_forw_packet {
struct batadv_algo_iface_ops {
void (*activate)(struct batadv_hard_iface *hard_iface);
int (*enable)(struct batadv_hard_iface *hard_iface);
void (*enabled)(struct batadv_hard_iface *hard_iface);
void (*disable)(struct batadv_hard_iface *hard_iface);
void (*update_mac)(struct batadv_hard_iface *hard_iface);
void (*primary_set)(struct batadv_hard_iface *hard_iface);
@@ -1479,9 +1486,10 @@ struct batadv_algo_neigh_ops {
*/
struct batadv_algo_orig_ops {
void (*free)(struct batadv_orig_node *orig_node);
int (*add_if)(struct batadv_orig_node *orig_node, int max_if_num);
int (*del_if)(struct batadv_orig_node *orig_node, int max_if_num,
int del_if_num);
int (*add_if)(struct batadv_orig_node *orig_node,
unsigned int max_if_num);
int (*del_if)(struct batadv_orig_node *orig_node,
unsigned int max_if_num, unsigned int del_if_num);
#ifdef CONFIG_BATMAN_ADV_DEBUGFS
void (*print)(struct batadv_priv *priv, struct seq_file *seq,
struct batadv_hard_iface *hard_iface);

View File

@@ -57,30 +57,60 @@ static void cgrp_css_free(struct cgroup_subsys_state *css)
kfree(css_cls_state(css));
}
/*
* To avoid freezing of sockets creation for tasks with big number of threads
* and opened sockets lets release file_lock every 1000 iterated descriptors.
* New sockets will already have been created with new classid.
*/
struct update_classid_context {
u32 classid;
unsigned int batch;
};
#define UPDATE_CLASSID_BATCH 1000
static int update_classid_sock(const void *v, struct file *file, unsigned n)
{
int err;
struct update_classid_context *ctx = (void *)v;
struct socket *sock = sock_from_file(file, &err);
if (sock) {
spin_lock(&cgroup_sk_update_lock);
sock_cgroup_set_classid(&sock->sk->sk_cgrp_data,
(unsigned long)v);
sock_cgroup_set_classid(&sock->sk->sk_cgrp_data, ctx->classid);
spin_unlock(&cgroup_sk_update_lock);
}
if (--ctx->batch == 0) {
ctx->batch = UPDATE_CLASSID_BATCH;
return n + 1;
}
return 0;
}
static void update_classid_task(struct task_struct *p, u32 classid)
{
struct update_classid_context ctx = {
.classid = classid,
.batch = UPDATE_CLASSID_BATCH
};
unsigned int fd = 0;
do {
task_lock(p);
fd = iterate_fd(p->files, fd, update_classid_sock, &ctx);
task_unlock(p);
cond_resched();
} while (fd);
}
static void cgrp_attach(struct cgroup_taskset *tset)
{
struct cgroup_subsys_state *css;
struct task_struct *p;
cgroup_taskset_for_each(p, css, tset) {
task_lock(p);
iterate_fd(p->files, 0, update_classid_sock,
(void *)(unsigned long)css_cls_state(css)->classid);
task_unlock(p);
update_classid_task(p, css_cls_state(css)->classid);
}
}
@@ -102,10 +132,7 @@ static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
css_task_iter_start(css, 0, &it);
while ((p = css_task_iter_next(&it))) {
task_lock(p);
iterate_fd(p->files, 0, update_classid_sock,
(void *)(unsigned long)cs->classid);
task_unlock(p);
update_classid_task(p, cs->classid);
cond_resched();
}
css_task_iter_end(&it);

View File

@@ -1684,7 +1684,10 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
atomic_set(&newsk->sk_zckey, 0);
sock_reset_flag(newsk, SOCK_DONE);
mem_cgroup_sk_alloc(newsk);
/* sk->sk_memcg will be populated at accept() time */
newsk->sk_memcg = NULL;
cgroup_sk_alloc(&newsk->sk_cgrp_data);
rcu_read_lock();

View File

@@ -30,7 +30,13 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
[IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, },
[IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, },
[IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, },
[IEEE802154_ATTR_BCN_ORD] = { .type = NLA_U8, },
[IEEE802154_ATTR_SF_ORD] = { .type = NLA_U8, },
[IEEE802154_ATTR_PAN_COORD] = { .type = NLA_U8, },
[IEEE802154_ATTR_BAT_EXT] = { .type = NLA_U8, },
[IEEE802154_ATTR_COORD_REALIGN] = { .type = NLA_U8, },
[IEEE802154_ATTR_PAGE] = { .type = NLA_U8, },
[IEEE802154_ATTR_DEV_TYPE] = { .type = NLA_U8, },
[IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, },
[IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, },
[IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, },

View File

@@ -1738,6 +1738,7 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway)
{
unsigned char optbuf[sizeof(struct ip_options) + 40];
struct ip_options *opt = (struct ip_options *)optbuf;
int res;
if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES)
return;
@@ -1749,7 +1750,11 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway)
memset(opt, 0, sizeof(struct ip_options));
opt->optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr);
if (__ip_options_compile(dev_net(skb->dev), opt, skb, NULL))
rcu_read_lock();
res = __ip_options_compile(dev_net(skb->dev), opt, skb, NULL);
rcu_read_unlock();
if (res)
return;
if (gateway)

View File

@@ -60,7 +60,9 @@ int gre_del_protocol(const struct gre_protocol *proto, u8 version)
}
EXPORT_SYMBOL_GPL(gre_del_protocol);
/* Fills in tpi and returns header length to be pulled. */
/* Fills in tpi and returns header length to be pulled.
* Note that caller must use pskb_may_pull() before pulling GRE header.
*/
int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
bool *csum_err, __be16 proto, int nhs)
{
@@ -114,8 +116,14 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
* - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
*/
if (greh->flags == 0 && tpi->proto == htons(ETH_P_WCCP)) {
u8 _val, *val;
val = skb_header_pointer(skb, nhs + hdr_len,
sizeof(_val), &_val);
if (!val)
return -EINVAL;
tpi->proto = proto;
if ((*(u8 *)options & 0xF0) != 0x40)
if ((*val & 0xF0) != 0x40)
hdr_len += 4;
}
tpi->hdr_len = hdr_len;

View File

@@ -475,8 +475,28 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern)
}
spin_unlock_bh(&queue->fastopenq.lock);
}
out:
release_sock(sk);
if (newsk && mem_cgroup_sockets_enabled) {
int amt;
/* atomically get the memory usage, set and charge the
* newsk->sk_memcg.
*/
lock_sock(newsk);
/* The socket has not been accepted yet, no need to look at
* newsk->sk_wmem_queued.
*/
amt = sk_mem_pages(newsk->sk_forward_alloc +
atomic_read(&newsk->sk_rmem_alloc));
mem_cgroup_sk_alloc(newsk);
if (newsk->sk_memcg && amt)
mem_cgroup_charge_skmem(newsk->sk_memcg, amt);
release_sock(newsk);
}
if (req)
reqsk_put(req);
return newsk;

View File

@@ -105,13 +105,9 @@ static size_t inet_sk_attr_size(struct sock *sk,
aux = handler->idiag_get_aux_size(sk, net_admin);
return nla_total_size(sizeof(struct tcp_info))
+ nla_total_size(1) /* INET_DIAG_SHUTDOWN */
+ nla_total_size(1) /* INET_DIAG_TOS */
+ nla_total_size(1) /* INET_DIAG_TCLASS */
+ nla_total_size(4) /* INET_DIAG_MARK */
+ nla_total_size(4) /* INET_DIAG_CLASS_ID */
+ nla_total_size(sizeof(struct inet_diag_meminfo))
+ nla_total_size(sizeof(struct inet_diag_msg))
+ inet_diag_msg_attrs_size()
+ nla_total_size(sizeof(struct inet_diag_meminfo))
+ nla_total_size(SK_MEMINFO_VARS * sizeof(u32))
+ nla_total_size(TCP_CA_NAME_MAX)
+ nla_total_size(sizeof(struct tcpvegas_info))
@@ -152,6 +148,24 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, sk->sk_mark))
goto errout;
if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) ||
ext & (1 << (INET_DIAG_TCLASS - 1))) {
u32 classid = 0;
#ifdef CONFIG_SOCK_CGROUP_DATA
classid = sock_cgroup_classid(&sk->sk_cgrp_data);
#endif
/* Fallback to socket priority if class id isn't set.
* Classful qdiscs use it as direct reference to class.
* For cgroup2 classid is always zero.
*/
if (!classid)
classid = sk->sk_priority;
if (nla_put_u32(skb, INET_DIAG_CLASS_ID, classid))
goto errout;
}
r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
r->idiag_inode = sock_i_ino(sk);
@@ -289,24 +303,6 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
goto errout;
}
if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) ||
ext & (1 << (INET_DIAG_TCLASS - 1))) {
u32 classid = 0;
#ifdef CONFIG_SOCK_CGROUP_DATA
classid = sock_cgroup_classid(&sk->sk_cgrp_data);
#endif
/* Fallback to socket priority if class id isn't set.
* Classful qdiscs use it as direct reference to class.
* For cgroup2 classid is always zero.
*/
if (!classid)
classid = sk->sk_priority;
if (nla_put_u32(skb, INET_DIAG_CLASS_ID, classid))
goto errout;
}
out:
nlmsg_end(skb, nlh);
return 0;

View File

@@ -99,8 +99,9 @@ static int raw_diag_dump_one(struct sk_buff *in_skb,
if (IS_ERR(sk))
return PTR_ERR(sk);
rep = nlmsg_new(sizeof(struct inet_diag_msg) +
sizeof(struct inet_diag_meminfo) + 64,
rep = nlmsg_new(nla_total_size(sizeof(struct inet_diag_msg)) +
inet_diag_msg_attrs_size() +
nla_total_size(sizeof(struct inet_diag_meminfo)) + 64,
GFP_KERNEL);
if (!rep) {
sock_put(sk);

View File

@@ -67,8 +67,9 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
goto out;
err = -ENOMEM;
rep = nlmsg_new(sizeof(struct inet_diag_msg) +
sizeof(struct inet_diag_meminfo) + 64,
rep = nlmsg_new(nla_total_size(sizeof(struct inet_diag_msg)) +
inet_diag_msg_attrs_size() +
nla_total_size(sizeof(struct inet_diag_meminfo)) + 64,
GFP_KERNEL);
if (!rep)
goto out;

View File

@@ -3250,6 +3250,10 @@ static void addrconf_dev_config(struct net_device *dev)
(dev->type != ARPHRD_TUNNEL) &&
(dev->type != ARPHRD_NONE)) {
/* Alas, we support only Ethernet autoconfiguration. */
idev = __in6_dev_get(dev);
if (!IS_ERR_OR_NULL(idev) && dev->flags & IFF_UP &&
dev->flags & IFF_MULTICAST)
ipv6_mc_up(idev);
return;
}

View File

@@ -185,9 +185,15 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
retv = -EBUSY;
break;
}
} else if (sk->sk_protocol != IPPROTO_TCP)
} else if (sk->sk_protocol == IPPROTO_TCP) {
if (sk->sk_prot != &tcpv6_prot) {
retv = -EBUSY;
break;
}
break;
} else {
break;
}
if (sk->sk_state != TCP_ESTABLISHED) {
retv = -ENOTCONN;
break;

View File

@@ -3862,7 +3862,7 @@ void __ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata)
lockdep_assert_held(&local->sta_mtx);
list_for_each_entry_rcu(sta, &local->sta_list, list) {
list_for_each_entry(sta, &local->sta_list, list) {
if (sdata != sta->sdata &&
(!sta->sdata->bss || sta->sdata->bss != sdata->bss))
continue;

View File

@@ -733,6 +733,8 @@ static const struct nla_policy nfnl_cthelper_policy[NFCTH_MAX+1] = {
[NFCTH_NAME] = { .type = NLA_NUL_STRING,
.len = NF_CT_HELPER_NAME_LEN-1 },
[NFCTH_QUEUE_NUM] = { .type = NLA_U32, },
[NFCTH_PRIV_DATA_LEN] = { .type = NLA_U32, },
[NFCTH_STATUS] = { .type = NLA_U32, },
};
static const struct nfnl_callback nfnl_cthelper_cb[NFNL_MSG_CTHELPER_MAX] = {

View File

@@ -121,6 +121,7 @@ static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = {
[NFTA_PAYLOAD_LEN] = { .type = NLA_U32 },
[NFTA_PAYLOAD_CSUM_TYPE] = { .type = NLA_U32 },
[NFTA_PAYLOAD_CSUM_OFFSET] = { .type = NLA_U32 },
[NFTA_PAYLOAD_CSUM_FLAGS] = { .type = NLA_U32 },
};
static int nft_payload_init(const struct nft_ctx *ctx,

View File

@@ -2389,7 +2389,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
in_skb->len))
WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS,
(u8 *)extack->bad_attr -
in_skb->data));
(u8 *)nlh));
} else {
if (extack->cookie_len)
WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE,

View File

@@ -193,13 +193,20 @@ exit:
void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
struct sk_buff *skb)
{
u8 gate = hdev->pipes[pipe].gate;
u8 status = NFC_HCI_ANY_OK;
struct hci_create_pipe_resp *create_info;
struct hci_delete_pipe_noti *delete_info;
struct hci_all_pipe_cleared_noti *cleared_info;
u8 gate;
pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd);
pr_debug("from pipe %x cmd %x\n", pipe, cmd);
if (pipe >= NFC_HCI_MAX_PIPES) {
status = NFC_HCI_ANY_E_NOK;
goto exit;
}
gate = hdev->pipes[pipe].gate;
switch (cmd) {
case NFC_HCI_ADM_NOTIFY_PIPE_CREATED:
@@ -387,8 +394,14 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event,
struct sk_buff *skb)
{
int r = 0;
u8 gate = hdev->pipes[pipe].gate;
u8 gate;
if (pipe >= NFC_HCI_MAX_PIPES) {
pr_err("Discarded event %x to invalid pipe %x\n", event, pipe);
goto exit;
}
gate = hdev->pipes[pipe].gate;
if (gate == NFC_HCI_INVALID_GATE) {
pr_err("Discarded event %x to unopened pipe %x\n", event, pipe);
goto exit;

View File

@@ -55,7 +55,10 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
[NFC_ATTR_LLC_SDP] = { .type = NLA_NESTED },
[NFC_ATTR_FIRMWARE_NAME] = { .type = NLA_STRING,
.len = NFC_FIRMWARE_NAME_MAXSIZE },
[NFC_ATTR_SE_INDEX] = { .type = NLA_U32 },
[NFC_ATTR_SE_APDU] = { .type = NLA_BINARY },
[NFC_ATTR_VENDOR_ID] = { .type = NLA_U32 },
[NFC_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
[NFC_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
};

View File

@@ -2299,6 +2299,13 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
TP_STATUS_KERNEL, (macoff+snaplen));
if (!h.raw)
goto drop_n_account;
if (do_vnet &&
virtio_net_hdr_from_skb(skb, h.raw + macoff -
sizeof(struct virtio_net_hdr),
vio_le(), true, 0))
goto drop_n_account;
if (po->tp_version <= TPACKET_V2) {
packet_increment_rx_head(po, &po->rx_ring);
/*
@@ -2311,12 +2318,6 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
status |= TP_STATUS_LOSING;
}
if (do_vnet &&
virtio_net_hdr_from_skb(skb, h.raw + macoff -
sizeof(struct virtio_net_hdr),
vio_le(), true, 0))
goto drop_n_account;
po->stats.stats1.tp_packets++;
if (copy_skb) {
status |= TP_STATUS_COPY;

View File

@@ -695,6 +695,7 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = {
[TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 },
[TCA_FQ_BUCKETS_LOG] = { .type = NLA_U32 },
[TCA_FQ_FLOW_REFILL_DELAY] = { .type = NLA_U32 },
[TCA_FQ_ORPHAN_MASK] = { .type = NLA_U32 },
[TCA_FQ_LOW_RATE_THRESHOLD] = { .type = NLA_U32 },
};

View File

@@ -221,15 +221,11 @@ static size_t inet_assoc_attr_size(struct sctp_association *asoc)
addrcnt++;
return nla_total_size(sizeof(struct sctp_info))
+ nla_total_size(1) /* INET_DIAG_SHUTDOWN */
+ nla_total_size(1) /* INET_DIAG_TOS */
+ nla_total_size(1) /* INET_DIAG_TCLASS */
+ nla_total_size(4) /* INET_DIAG_MARK */
+ nla_total_size(4) /* INET_DIAG_CLASS_ID */
+ nla_total_size(addrlen * asoc->peer.transport_count)
+ nla_total_size(addrlen * addrcnt)
+ nla_total_size(sizeof(struct inet_diag_meminfo))
+ nla_total_size(sizeof(struct inet_diag_msg))
+ inet_diag_msg_attrs_size()
+ nla_total_size(sizeof(struct inet_diag_meminfo))
+ 64;
}

View File

@@ -513,6 +513,8 @@ static void smc_ib_remove_dev(struct ib_device *ibdev, void *client_data)
struct smc_ib_device *smcibdev;
smcibdev = ib_get_client_data(ibdev, &smc_ib_client);
if (!smcibdev || smcibdev->ibdev != ibdev)
return;
ib_set_client_data(ibdev, &smc_ib_client, NULL);
spin_lock(&smc_ib_devices.lock);
list_del_init(&smcibdev->list); /* remove from smc_ib_devices */

View File

@@ -347,6 +347,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
[NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
[NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
[NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 },
[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG },
[NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
[NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
[NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
@@ -395,6 +397,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_MDID] = { .type = NLA_U16 },
[NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
[NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 },
[NL80211_ATTR_MAX_CRIT_PROT_DURATION] = { .type = NLA_U16 },
[NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
[NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
[NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
@@ -420,6 +424,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 },
[NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
[NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
[NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 },
[NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
[NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
[NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },

View File

@@ -1733,7 +1733,7 @@ static void handle_channel_custom(struct wiphy *wiphy,
break;
}
if (IS_ERR(reg_rule)) {
if (IS_ERR_OR_NULL(reg_rule)) {
pr_debug("Disabling freq %d MHz as custom regd has no rule that fits it\n",
chan->center_freq);
if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {

View File

@@ -1345,7 +1345,7 @@ sub reboot {
} else {
# Make sure everything has been written to disk
run_ssh("sync");
run_ssh("sync", 10);
if (defined($time)) {
start_monitor;