Merge branch 'linus' into x86/asm, to resolve conflict

Conflicts:
	arch/x86/mm/mem_encrypt.c

Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Ingo Molnar 2017-11-10 08:06:47 +01:00
commit 91a6a6cfee
67 changed files with 470 additions and 209 deletions

View File

@ -2113,6 +2113,10 @@ S: J. Obrechtstr 23
S: NL-5216 GP 's-Hertogenbosch S: NL-5216 GP 's-Hertogenbosch
S: The Netherlands S: The Netherlands
N: Ashley Lai
E: ashleydlai@gmail.com
D: IBM VTPM driver
N: Savio Lam N: Savio Lam
E: lam836@cs.cuhk.hk E: lam836@cs.cuhk.hk
D: Author of the dialog utility, foundation D: Author of the dialog utility, foundation
@ -3333,6 +3337,10 @@ S: Braunschweiger Strasse 79
S: 31134 Hildesheim S: 31134 Hildesheim
S: Germany S: Germany
N: Marcel Selhorst
E: tpmdd@selhorst.net
D: TPM driver
N: Darren Senn N: Darren Senn
E: sinster@darkwater.com E: sinster@darkwater.com
D: Whatever I notice needs doing (so far: itimers, /proc) D: Whatever I notice needs doing (so far: itimers, /proc)
@ -4128,7 +4136,6 @@ D: MD driver
D: EISA/sysfs subsystem D: EISA/sysfs subsystem
S: France S: France
# Don't add your name here, unless you really _are_ after Marc # Don't add your name here, unless you really _are_ after Marc
# alphabetically. Leonard used to be very proud of being the # alphabetically. Leonard used to be very proud of being the
# last entry, and he'll get positively pissed if he can't even # last entry, and he'll get positively pissed if he can't even

View File

@ -10341,7 +10341,6 @@ F: drivers/pci/host/vmd.c
PCI DRIVER FOR MICROSEMI SWITCHTEC PCI DRIVER FOR MICROSEMI SWITCHTEC
M: Kurt Schwemmer <kurt.schwemmer@microsemi.com> M: Kurt Schwemmer <kurt.schwemmer@microsemi.com>
M: Stephen Bates <stephen.bates@microsemi.com>
M: Logan Gunthorpe <logang@deltatee.com> M: Logan Gunthorpe <logang@deltatee.com>
L: linux-pci@vger.kernel.org L: linux-pci@vger.kernel.org
S: Maintained S: Maintained
@ -10406,6 +10405,7 @@ F: drivers/pci/dwc/*keystone*
PCI ENDPOINT SUBSYSTEM PCI ENDPOINT SUBSYSTEM
M: Kishon Vijay Abraham I <kishon@ti.com> M: Kishon Vijay Abraham I <kishon@ti.com>
M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
L: linux-pci@vger.kernel.org L: linux-pci@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/pci-endpoint.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/pci-endpoint.git
S: Supported S: Supported
@ -10457,6 +10457,15 @@ F: include/linux/pci*
F: arch/x86/pci/ F: arch/x86/pci/
F: arch/x86/kernel/quirks.c F: arch/x86/kernel/quirks.c
PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS
M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
L: linux-pci@vger.kernel.org
Q: http://patchwork.ozlabs.org/project/linux-pci/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git/
S: Supported
F: drivers/pci/host/
F: drivers/pci/dwc/
PCIE DRIVER FOR AXIS ARTPEC PCIE DRIVER FOR AXIS ARTPEC
M: Niklas Cassel <niklas.cassel@axis.com> M: Niklas Cassel <niklas.cassel@axis.com>
M: Jesper Nilsson <jesper.nilsson@axis.com> M: Jesper Nilsson <jesper.nilsson@axis.com>
@ -10476,7 +10485,6 @@ F: drivers/pci/host/pci-thunder-*
PCIE DRIVER FOR HISILICON PCIE DRIVER FOR HISILICON
M: Zhou Wang <wangzhou1@hisilicon.com> M: Zhou Wang <wangzhou1@hisilicon.com>
M: Gabriele Paoloni <gabriele.paoloni@huawei.com>
L: linux-pci@vger.kernel.org L: linux-pci@vger.kernel.org
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
@ -13603,23 +13611,14 @@ F: drivers/platform/x86/toshiba-wmi.c
TPM DEVICE DRIVER TPM DEVICE DRIVER
M: Peter Huewe <peterhuewe@gmx.de> M: Peter Huewe <peterhuewe@gmx.de>
M: Marcel Selhorst <tpmdd@selhorst.net>
M: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> M: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
R: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> R: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
W: http://tpmdd.sourceforge.net L: linux-integrity@vger.kernel.org
L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) Q: https://patchwork.kernel.org/project/linux-integrity/list/
Q: https://patchwork.kernel.org/project/tpmdd-devel/list/
T: git git://git.infradead.org/users/jjs/linux-tpmdd.git T: git git://git.infradead.org/users/jjs/linux-tpmdd.git
S: Maintained S: Maintained
F: drivers/char/tpm/ F: drivers/char/tpm/
TPM IBM_VTPM DEVICE DRIVER
M: Ashley Lai <ashleydlai@gmail.com>
W: http://tpmdd.sourceforge.net
L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
F: drivers/char/tpm/tpm_ibmvtpm*
TRACING TRACING
M: Steven Rostedt <rostedt@goodmis.org> M: Steven Rostedt <rostedt@goodmis.org>
M: Ingo Molnar <mingo@redhat.com> M: Ingo Molnar <mingo@redhat.com>

View File

@ -154,30 +154,26 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
set_fs(fs); set_fs(fs);
} }
static void dump_instr(const char *lvl, struct pt_regs *regs) static void __dump_instr(const char *lvl, struct pt_regs *regs)
{ {
unsigned long addr = instruction_pointer(regs); unsigned long addr = instruction_pointer(regs);
const int thumb = thumb_mode(regs); const int thumb = thumb_mode(regs);
const int width = thumb ? 4 : 8; const int width = thumb ? 4 : 8;
mm_segment_t fs;
char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str; char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
int i; int i;
/* /*
* We need to switch to kernel mode so that we can use __get_user * Note that we now dump the code first, just in case the backtrace
* to safely read from kernel space. Note that we now dump the * kills us.
* code first, just in case the backtrace kills us.
*/ */
fs = get_fs();
set_fs(KERNEL_DS);
for (i = -4; i < 1 + !!thumb; i++) { for (i = -4; i < 1 + !!thumb; i++) {
unsigned int val, bad; unsigned int val, bad;
if (thumb) if (thumb)
bad = __get_user(val, &((u16 *)addr)[i]); bad = get_user(val, &((u16 *)addr)[i]);
else else
bad = __get_user(val, &((u32 *)addr)[i]); bad = get_user(val, &((u32 *)addr)[i]);
if (!bad) if (!bad)
p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ", p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
@ -188,8 +184,20 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
} }
} }
printk("%sCode: %s\n", lvl, str); printk("%sCode: %s\n", lvl, str);
}
set_fs(fs); static void dump_instr(const char *lvl, struct pt_regs *regs)
{
mm_segment_t fs;
if (!user_mode(regs)) {
fs = get_fs();
set_fs(KERNEL_DS);
__dump_instr(lvl, regs);
set_fs(fs);
} else {
__dump_instr(lvl, regs);
}
} }
#ifdef CONFIG_ARM_UNWIND #ifdef CONFIG_ARM_UNWIND

View File

@ -42,7 +42,7 @@ static char sme_cmdline_off[] __initdata = "off";
* section is later cleared. * section is later cleared.
*/ */
u64 sme_me_mask __section(.data) = 0; u64 sme_me_mask __section(.data) = 0;
EXPORT_SYMBOL_GPL(sme_me_mask); EXPORT_SYMBOL(sme_me_mask);
DEFINE_STATIC_KEY_FALSE(sev_enable_key); DEFINE_STATIC_KEY_FALSE(sev_enable_key);
EXPORT_SYMBOL_GPL(sev_enable_key); EXPORT_SYMBOL_GPL(sev_enable_key);

View File

@ -160,6 +160,14 @@ static int __init init_nvs_nosave(const struct dmi_system_id *d)
return 0; return 0;
} }
static bool acpi_sleep_no_lps0;
static int __init init_no_lps0(const struct dmi_system_id *d)
{
acpi_sleep_no_lps0 = true;
return 0;
}
static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {
{ {
.callback = init_old_suspend_ordering, .callback = init_old_suspend_ordering,
@ -343,6 +351,19 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {
DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), DMI_MATCH(DMI_PRODUCT_NAME, "80E3"),
}, },
}, },
/*
* https://bugzilla.kernel.org/show_bug.cgi?id=196907
* Some Dell XPS13 9360 cannot do suspend-to-idle using the Low Power
* S0 Idle firmware interface.
*/
{
.callback = init_no_lps0,
.ident = "Dell XPS13 9360",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9360"),
},
},
{}, {},
}; };
@ -485,6 +506,7 @@ static void acpi_pm_end(void)
} }
#else /* !CONFIG_ACPI_SLEEP */ #else /* !CONFIG_ACPI_SLEEP */
#define acpi_target_sleep_state ACPI_STATE_S0 #define acpi_target_sleep_state ACPI_STATE_S0
#define acpi_sleep_no_lps0 (false)
static inline void acpi_sleep_dmi_check(void) {} static inline void acpi_sleep_dmi_check(void) {}
#endif /* CONFIG_ACPI_SLEEP */ #endif /* CONFIG_ACPI_SLEEP */
@ -863,6 +885,12 @@ static int lps0_device_attach(struct acpi_device *adev,
if (lps0_device_handle) if (lps0_device_handle)
return 0; return 0;
if (acpi_sleep_no_lps0) {
acpi_handle_info(adev->handle,
"Low Power S0 Idle interface disabled\n");
return 0;
}
if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0))
return 0; return 0;

View File

@ -867,11 +867,16 @@ static void msf_from_bcd(struct atapi_msf *msf)
int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
{ {
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *cdi = &info->devinfo; struct cdrom_device_info *cdi;
unsigned char cmd[BLK_MAX_CDB]; unsigned char cmd[BLK_MAX_CDB];
ide_debug_log(IDE_DBG_FUNC, "enter"); ide_debug_log(IDE_DBG_FUNC, "enter");
if (!info)
return -EIO;
cdi = &info->devinfo;
memset(cmd, 0, BLK_MAX_CDB); memset(cmd, 0, BLK_MAX_CDB);
cmd[0] = GPCMD_TEST_UNIT_READY; cmd[0] = GPCMD_TEST_UNIT_READY;

View File

@ -2042,6 +2042,7 @@ static int bond_miimon_inspect(struct bonding *bond)
bond_for_each_slave_rcu(bond, slave, iter) { bond_for_each_slave_rcu(bond, slave, iter) {
slave->new_link = BOND_LINK_NOCHANGE; slave->new_link = BOND_LINK_NOCHANGE;
slave->link_new_state = slave->link;
link_state = bond_check_dev_link(bond, slave->dev, 0); link_state = bond_check_dev_link(bond, slave->dev, 0);
@ -3253,7 +3254,7 @@ u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb)
hash ^= (hash >> 16); hash ^= (hash >> 16);
hash ^= (hash >> 8); hash ^= (hash >> 8);
return hash; return hash >> 1;
} }
/*-------------------------- Device entry points ----------------------------*/ /*-------------------------- Device entry points ----------------------------*/

View File

@ -37,7 +37,7 @@
#define T4FW_VERSION_MAJOR 0x01 #define T4FW_VERSION_MAJOR 0x01
#define T4FW_VERSION_MINOR 0x10 #define T4FW_VERSION_MINOR 0x10
#define T4FW_VERSION_MICRO 0x2D #define T4FW_VERSION_MICRO 0x3F
#define T4FW_VERSION_BUILD 0x00 #define T4FW_VERSION_BUILD 0x00
#define T4FW_MIN_VERSION_MAJOR 0x01 #define T4FW_MIN_VERSION_MAJOR 0x01
@ -46,7 +46,7 @@
#define T5FW_VERSION_MAJOR 0x01 #define T5FW_VERSION_MAJOR 0x01
#define T5FW_VERSION_MINOR 0x10 #define T5FW_VERSION_MINOR 0x10
#define T5FW_VERSION_MICRO 0x2D #define T5FW_VERSION_MICRO 0x3F
#define T5FW_VERSION_BUILD 0x00 #define T5FW_VERSION_BUILD 0x00
#define T5FW_MIN_VERSION_MAJOR 0x00 #define T5FW_MIN_VERSION_MAJOR 0x00
@ -55,7 +55,7 @@
#define T6FW_VERSION_MAJOR 0x01 #define T6FW_VERSION_MAJOR 0x01
#define T6FW_VERSION_MINOR 0x10 #define T6FW_VERSION_MINOR 0x10
#define T6FW_VERSION_MICRO 0x2D #define T6FW_VERSION_MICRO 0x3F
#define T6FW_VERSION_BUILD 0x00 #define T6FW_VERSION_BUILD 0x00
#define T6FW_MIN_VERSION_MAJOR 0x00 #define T6FW_MIN_VERSION_MAJOR 0x00

View File

@ -6747,6 +6747,9 @@ static int mvpp2_irqs_init(struct mvpp2_port *port)
for (i = 0; i < port->nqvecs; i++) { for (i = 0; i < port->nqvecs; i++) {
struct mvpp2_queue_vector *qv = port->qvecs + i; struct mvpp2_queue_vector *qv = port->qvecs + i;
if (qv->type == MVPP2_QUEUE_VECTOR_PRIVATE)
irq_set_status_flags(qv->irq, IRQ_NO_BALANCING);
err = request_irq(qv->irq, mvpp2_isr, 0, port->dev->name, qv); err = request_irq(qv->irq, mvpp2_isr, 0, port->dev->name, qv);
if (err) if (err)
goto err; goto err;
@ -6776,6 +6779,7 @@ static void mvpp2_irqs_deinit(struct mvpp2_port *port)
struct mvpp2_queue_vector *qv = port->qvecs + i; struct mvpp2_queue_vector *qv = port->qvecs + i;
irq_set_affinity_hint(qv->irq, NULL); irq_set_affinity_hint(qv->irq, NULL);
irq_clear_status_flags(qv->irq, IRQ_NO_BALANCING);
free_irq(qv->irq, qv); free_irq(qv->irq, qv);
} }
} }

View File

@ -365,21 +365,24 @@ static void mlx5e_execute_l2_action(struct mlx5e_priv *priv,
struct mlx5e_l2_hash_node *hn) struct mlx5e_l2_hash_node *hn)
{ {
u8 action = hn->action; u8 action = hn->action;
u8 mac_addr[ETH_ALEN];
int l2_err = 0; int l2_err = 0;
ether_addr_copy(mac_addr, hn->ai.addr);
switch (action) { switch (action) {
case MLX5E_ACTION_ADD: case MLX5E_ACTION_ADD:
mlx5e_add_l2_flow_rule(priv, &hn->ai, MLX5E_FULLMATCH); mlx5e_add_l2_flow_rule(priv, &hn->ai, MLX5E_FULLMATCH);
if (!is_multicast_ether_addr(hn->ai.addr)) { if (!is_multicast_ether_addr(mac_addr)) {
l2_err = mlx5_mpfs_add_mac(priv->mdev, hn->ai.addr); l2_err = mlx5_mpfs_add_mac(priv->mdev, mac_addr);
hn->mpfs = !l2_err; hn->mpfs = !l2_err;
} }
hn->action = MLX5E_ACTION_NONE; hn->action = MLX5E_ACTION_NONE;
break; break;
case MLX5E_ACTION_DEL: case MLX5E_ACTION_DEL:
if (!is_multicast_ether_addr(hn->ai.addr) && hn->mpfs) if (!is_multicast_ether_addr(mac_addr) && hn->mpfs)
l2_err = mlx5_mpfs_del_mac(priv->mdev, hn->ai.addr); l2_err = mlx5_mpfs_del_mac(priv->mdev, mac_addr);
mlx5e_del_l2_flow_rule(priv, &hn->ai); mlx5e_del_l2_flow_rule(priv, &hn->ai);
mlx5e_del_l2_from_hash(hn); mlx5e_del_l2_from_hash(hn);
break; break;
@ -387,7 +390,7 @@ static void mlx5e_execute_l2_action(struct mlx5e_priv *priv,
if (l2_err) if (l2_err)
netdev_warn(priv->netdev, "MPFS, failed to %s mac %pM, err(%d)\n", netdev_warn(priv->netdev, "MPFS, failed to %s mac %pM, err(%d)\n",
action == MLX5E_ACTION_ADD ? "add" : "del", hn->ai.addr, l2_err); action == MLX5E_ACTION_ADD ? "add" : "del", mac_addr, l2_err);
} }
static void mlx5e_sync_netdev_addr(struct mlx5e_priv *priv) static void mlx5e_sync_netdev_addr(struct mlx5e_priv *priv)

View File

@ -626,7 +626,7 @@ static int asix_suspend(struct usb_interface *intf, pm_message_t message)
struct usbnet *dev = usb_get_intfdata(intf); struct usbnet *dev = usb_get_intfdata(intf);
struct asix_common_private *priv = dev->driver_priv; struct asix_common_private *priv = dev->driver_priv;
if (priv->suspend) if (priv && priv->suspend)
priv->suspend(dev); priv->suspend(dev);
return usbnet_suspend(intf, message); return usbnet_suspend(intf, message);
@ -678,7 +678,7 @@ static int asix_resume(struct usb_interface *intf)
struct usbnet *dev = usb_get_intfdata(intf); struct usbnet *dev = usb_get_intfdata(intf);
struct asix_common_private *priv = dev->driver_priv; struct asix_common_private *priv = dev->driver_priv;
if (priv->resume) if (priv && priv->resume)
priv->resume(dev); priv->resume(dev);
return usbnet_resume(intf); return usbnet_resume(intf);

View File

@ -230,7 +230,7 @@ skip:
goto bad_desc; goto bad_desc;
} }
if (header.usb_cdc_ether_desc) { if (header.usb_cdc_ether_desc && info->ether->wMaxSegmentSize) {
dev->hard_mtu = le16_to_cpu(info->ether->wMaxSegmentSize); dev->hard_mtu = le16_to_cpu(info->ether->wMaxSegmentSize);
/* because of Zaurus, we may be ignoring the host /* because of Zaurus, we may be ignoring the host
* side link address we were given. * side link address we were given.

View File

@ -499,6 +499,7 @@ static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
return 1; return 1;
} }
if (rawip) { if (rawip) {
skb_reset_mac_header(skb);
skb->dev = dev->net; /* normally set by eth_type_trans */ skb->dev = dev->net; /* normally set by eth_type_trans */
skb->protocol = proto; skb->protocol = proto;
return 1; return 1;
@ -681,7 +682,7 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
} }
/* errors aren't fatal - we can live with the dynamic address */ /* errors aren't fatal - we can live with the dynamic address */
if (cdc_ether) { if (cdc_ether && cdc_ether->wMaxSegmentSize) {
dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize); dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize);
usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress); usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress);
} }

View File

@ -2685,7 +2685,6 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
} }
sdev->sdev_state = state; sdev->sdev_state = state;
sysfs_notify(&sdev->sdev_gendev.kobj, NULL, "state");
return 0; return 0;
illegal: illegal:
@ -3109,7 +3108,6 @@ int scsi_internal_device_unblock_nowait(struct scsi_device *sdev,
case SDEV_BLOCK: case SDEV_BLOCK:
case SDEV_TRANSPORT_OFFLINE: case SDEV_TRANSPORT_OFFLINE:
sdev->sdev_state = new_state; sdev->sdev_state = new_state;
sysfs_notify(&sdev->sdev_gendev.kobj, NULL, "state");
break; break;
case SDEV_CREATED_BLOCK: case SDEV_CREATED_BLOCK:
if (new_state == SDEV_TRANSPORT_OFFLINE || if (new_state == SDEV_TRANSPORT_OFFLINE ||
@ -3117,7 +3115,6 @@ int scsi_internal_device_unblock_nowait(struct scsi_device *sdev,
sdev->sdev_state = new_state; sdev->sdev_state = new_state;
else else
sdev->sdev_state = SDEV_CREATED; sdev->sdev_state = SDEV_CREATED;
sysfs_notify(&sdev->sdev_gendev.kobj, NULL, "state");
break; break;
case SDEV_CANCEL: case SDEV_CANCEL:
case SDEV_OFFLINE: case SDEV_OFFLINE:

View File

@ -556,11 +556,8 @@ int srp_reconnect_rport(struct srp_rport *rport)
*/ */
shost_for_each_device(sdev, shost) { shost_for_each_device(sdev, shost) {
mutex_lock(&sdev->state_mutex); mutex_lock(&sdev->state_mutex);
if (sdev->sdev_state == SDEV_OFFLINE) { if (sdev->sdev_state == SDEV_OFFLINE)
sdev->sdev_state = SDEV_RUNNING; sdev->sdev_state = SDEV_RUNNING;
sysfs_notify(&sdev->sdev_gendev.kobj,
NULL, "state");
}
mutex_unlock(&sdev->state_mutex); mutex_unlock(&sdev->state_mutex);
} }
} else if (rport->state == SRP_RPORT_RUNNING) { } else if (rport->state == SRP_RPORT_RUNNING) {

View File

@ -3770,6 +3770,13 @@ static inline void nf_reset_trace(struct sk_buff *skb)
#endif #endif
} }
static inline void ipvs_reset(struct sk_buff *skb)
{
#if IS_ENABLED(CONFIG_IP_VS)
skb->ipvs_property = 0;
#endif
}
/* Note: This doesn't put any conntrack and bridge info in dst. */ /* Note: This doesn't put any conntrack and bridge info in dst. */
static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src, static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src,
bool copy) bool copy)

View File

@ -213,6 +213,11 @@ static inline struct ctl_table_header *register_sysctl_paths(
return NULL; return NULL;
} }
static inline struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table)
{
return NULL;
}
static inline void unregister_sysctl_table(struct ctl_table_header * table) static inline void unregister_sysctl_table(struct ctl_table_header * table)
{ {
} }

View File

@ -14,7 +14,6 @@
struct tcf_idrinfo { struct tcf_idrinfo {
spinlock_t lock; spinlock_t lock;
struct idr action_idr; struct idr action_idr;
struct net *net;
}; };
struct tc_action_ops; struct tc_action_ops;
@ -106,7 +105,7 @@ struct tc_action_net {
static inline static inline
int tc_action_net_init(struct tc_action_net *tn, int tc_action_net_init(struct tc_action_net *tn,
const struct tc_action_ops *ops, struct net *net) const struct tc_action_ops *ops)
{ {
int err = 0; int err = 0;
@ -114,7 +113,6 @@ int tc_action_net_init(struct tc_action_net *tn,
if (!tn->idrinfo) if (!tn->idrinfo)
return -ENOMEM; return -ENOMEM;
tn->ops = ops; tn->ops = ops;
tn->idrinfo->net = net;
spin_lock_init(&tn->idrinfo->lock); spin_lock_init(&tn->idrinfo->lock);
idr_init(&tn->idrinfo->action_idr); idr_init(&tn->idrinfo->action_idr);
return err; return err;

View File

@ -94,6 +94,7 @@ struct tcf_exts {
__u32 type; /* for backward compat(TCA_OLD_COMPAT) */ __u32 type; /* for backward compat(TCA_OLD_COMPAT) */
int nr_actions; int nr_actions;
struct tc_action **actions; struct tc_action **actions;
struct net *net;
#endif #endif
/* Map to export classifier specific extension TLV types to the /* Map to export classifier specific extension TLV types to the
* generic extensions API. Unsupported extensions must be set to 0. * generic extensions API. Unsupported extensions must be set to 0.
@ -107,6 +108,7 @@ static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police)
#ifdef CONFIG_NET_CLS_ACT #ifdef CONFIG_NET_CLS_ACT
exts->type = 0; exts->type = 0;
exts->nr_actions = 0; exts->nr_actions = 0;
exts->net = NULL;
exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *), exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *),
GFP_KERNEL); GFP_KERNEL);
if (!exts->actions) if (!exts->actions)
@ -117,6 +119,28 @@ static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police)
return 0; return 0;
} }
/* Return false if the netns is being destroyed in cleanup_net(). Callers
* need to do cleanup synchronously in this case, otherwise may race with
* tc_action_net_exit(). Return true for other cases.
*/
static inline bool tcf_exts_get_net(struct tcf_exts *exts)
{
#ifdef CONFIG_NET_CLS_ACT
exts->net = maybe_get_net(exts->net);
return exts->net != NULL;
#else
return true;
#endif
}
static inline void tcf_exts_put_net(struct tcf_exts *exts)
{
#ifdef CONFIG_NET_CLS_ACT
if (exts->net)
put_net(exts->net);
#endif
}
static inline void tcf_exts_to_list(const struct tcf_exts *exts, static inline void tcf_exts_to_list(const struct tcf_exts *exts,
struct list_head *actions) struct list_head *actions)
{ {

View File

@ -49,7 +49,8 @@ typedef union snd_seq_timestamp snd_seq_timestamp_t;
#define SNDRV_SEQ_DEFAULT_CLIENT_EVENTS 200 #define SNDRV_SEQ_DEFAULT_CLIENT_EVENTS 200
/* max delivery path length */ /* max delivery path length */
#define SNDRV_SEQ_MAX_HOPS 10 /* NOTE: this shouldn't be greater than MAX_LOCKDEP_SUBCLASSES */
#define SNDRV_SEQ_MAX_HOPS 8
/* max size of event size */ /* max size of event size */
#define SNDRV_SEQ_MAX_EVENT_LEN 0x3fffffff #define SNDRV_SEQ_MAX_EVENT_LEN 0x3fffffff

View File

@ -90,6 +90,8 @@ struct snd_timer {
struct list_head ack_list_head; struct list_head ack_list_head;
struct list_head sack_list_head; /* slow ack list head */ struct list_head sack_list_head; /* slow ack list head */
struct tasklet_struct task_queue; struct tasklet_struct task_queue;
int max_instances; /* upper limit of timer instances */
int num_instances; /* current number of timer instances */
}; };
struct snd_timer_instance { struct snd_timer_instance {

View File

@ -649,6 +649,7 @@ static int sugov_start(struct cpufreq_policy *policy)
struct sugov_cpu *sg_cpu = &per_cpu(sugov_cpu, cpu); struct sugov_cpu *sg_cpu = &per_cpu(sugov_cpu, cpu);
memset(sg_cpu, 0, sizeof(*sg_cpu)); memset(sg_cpu, 0, sizeof(*sg_cpu));
sg_cpu->cpu = cpu;
sg_cpu->sg_policy = sg_policy; sg_cpu->sg_policy = sg_policy;
sg_cpu->flags = SCHED_CPUFREQ_RT; sg_cpu->flags = SCHED_CPUFREQ_RT;
sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq; sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq;
@ -714,11 +715,6 @@ struct cpufreq_governor *cpufreq_default_governor(void)
static int __init sugov_register(void) static int __init sugov_register(void)
{ {
int cpu;
for_each_possible_cpu(cpu)
per_cpu(sugov_cpu, cpu).cpu = cpu;
return cpufreq_register_governor(&schedutil_gov); return cpufreq_register_governor(&schedutil_gov);
} }
fs_initcall(sugov_register); fs_initcall(sugov_register);

View File

@ -228,7 +228,7 @@ next_op:
hdr = 2; hdr = 2;
/* Extract a tag from the data */ /* Extract a tag from the data */
if (unlikely(dp >= datalen - 1)) if (unlikely(datalen - dp < 2))
goto data_overrun_error; goto data_overrun_error;
tag = data[dp++]; tag = data[dp++];
if (unlikely((tag & 0x1f) == ASN1_LONG_TAG)) if (unlikely((tag & 0x1f) == ASN1_LONG_TAG))
@ -274,7 +274,7 @@ next_op:
int n = len - 0x80; int n = len - 0x80;
if (unlikely(n > 2)) if (unlikely(n > 2))
goto length_too_long; goto length_too_long;
if (unlikely(dp >= datalen - n)) if (unlikely(n > datalen - dp))
goto data_overrun_error; goto data_overrun_error;
hdr += n; hdr += n;
for (len = 0; n > 0; n--) { for (len = 0; n > 0; n--) {

View File

@ -4864,6 +4864,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet)
if (!xnet) if (!xnet)
return; return;
ipvs_reset(skb);
skb_orphan(skb); skb_orphan(skb);
skb->mark = 0; skb->mark = 0;
} }

View File

@ -115,7 +115,7 @@ int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2;
#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED)
#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE) #define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE|FLAG_DSACKING_ACK)
#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) #define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED)
#define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH) #define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH)

View File

@ -123,6 +123,7 @@ static int l2tp_ip_recv(struct sk_buff *skb)
unsigned char *ptr, *optr; unsigned char *ptr, *optr;
struct l2tp_session *session; struct l2tp_session *session;
struct l2tp_tunnel *tunnel = NULL; struct l2tp_tunnel *tunnel = NULL;
struct iphdr *iph;
int length; int length;
if (!pskb_may_pull(skb, 4)) if (!pskb_may_pull(skb, 4))
@ -178,24 +179,17 @@ pass_up:
goto discard; goto discard;
tunnel_id = ntohl(*(__be32 *) &skb->data[4]); tunnel_id = ntohl(*(__be32 *) &skb->data[4]);
tunnel = l2tp_tunnel_find(net, tunnel_id); iph = (struct iphdr *)skb_network_header(skb);
if (tunnel) {
sk = tunnel->sock;
sock_hold(sk);
} else {
struct iphdr *iph = (struct iphdr *) skb_network_header(skb);
read_lock_bh(&l2tp_ip_lock); read_lock_bh(&l2tp_ip_lock);
sk = __l2tp_ip_bind_lookup(net, iph->daddr, iph->saddr, sk = __l2tp_ip_bind_lookup(net, iph->daddr, iph->saddr, inet_iif(skb),
inet_iif(skb), tunnel_id); tunnel_id);
if (!sk) { if (!sk) {
read_unlock_bh(&l2tp_ip_lock);
goto discard;
}
sock_hold(sk);
read_unlock_bh(&l2tp_ip_lock); read_unlock_bh(&l2tp_ip_lock);
goto discard;
} }
sock_hold(sk);
read_unlock_bh(&l2tp_ip_lock);
if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_put; goto discard_put;

View File

@ -136,6 +136,7 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
unsigned char *ptr, *optr; unsigned char *ptr, *optr;
struct l2tp_session *session; struct l2tp_session *session;
struct l2tp_tunnel *tunnel = NULL; struct l2tp_tunnel *tunnel = NULL;
struct ipv6hdr *iph;
int length; int length;
if (!pskb_may_pull(skb, 4)) if (!pskb_may_pull(skb, 4))
@ -192,24 +193,17 @@ pass_up:
goto discard; goto discard;
tunnel_id = ntohl(*(__be32 *) &skb->data[4]); tunnel_id = ntohl(*(__be32 *) &skb->data[4]);
tunnel = l2tp_tunnel_find(net, tunnel_id); iph = ipv6_hdr(skb);
if (tunnel) {
sk = tunnel->sock;
sock_hold(sk);
} else {
struct ipv6hdr *iph = ipv6_hdr(skb);
read_lock_bh(&l2tp_ip6_lock); read_lock_bh(&l2tp_ip6_lock);
sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, &iph->saddr, sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, &iph->saddr,
inet6_iif(skb), tunnel_id); inet6_iif(skb), tunnel_id);
if (!sk) { if (!sk) {
read_unlock_bh(&l2tp_ip6_lock);
goto discard;
}
sock_hold(sk);
read_unlock_bh(&l2tp_ip6_lock); read_unlock_bh(&l2tp_ip6_lock);
goto discard;
} }
sock_hold(sk);
read_unlock_bh(&l2tp_ip6_lock);
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_put; goto discard_put;

View File

@ -1085,7 +1085,7 @@ static int __init qrtr_proto_init(void)
return 0; return 0;
} }
module_init(qrtr_proto_init); postcore_initcall(qrtr_proto_init);
static void __exit qrtr_proto_fini(void) static void __exit qrtr_proto_fini(void)
{ {

View File

@ -78,7 +78,6 @@ static void tcf_idr_remove(struct tcf_idrinfo *idrinfo, struct tc_action *p)
spin_lock_bh(&idrinfo->lock); spin_lock_bh(&idrinfo->lock);
idr_remove_ext(&idrinfo->action_idr, p->tcfa_index); idr_remove_ext(&idrinfo->action_idr, p->tcfa_index);
spin_unlock_bh(&idrinfo->lock); spin_unlock_bh(&idrinfo->lock);
put_net(idrinfo->net);
gen_kill_estimator(&p->tcfa_rate_est); gen_kill_estimator(&p->tcfa_rate_est);
free_tcf(p); free_tcf(p);
} }
@ -337,7 +336,6 @@ err3:
p->idrinfo = idrinfo; p->idrinfo = idrinfo;
p->ops = ops; p->ops = ops;
INIT_LIST_HEAD(&p->list); INIT_LIST_HEAD(&p->list);
get_net(idrinfo->net);
*a = p; *a = p;
return 0; return 0;
} }

View File

@ -398,7 +398,7 @@ static __net_init int bpf_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, bpf_net_id); struct tc_action_net *tn = net_generic(net, bpf_net_id);
return tc_action_net_init(tn, &act_bpf_ops, net); return tc_action_net_init(tn, &act_bpf_ops);
} }
static void __net_exit bpf_exit_net(struct net *net) static void __net_exit bpf_exit_net(struct net *net)

View File

@ -206,7 +206,7 @@ static __net_init int connmark_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, connmark_net_id); struct tc_action_net *tn = net_generic(net, connmark_net_id);
return tc_action_net_init(tn, &act_connmark_ops, net); return tc_action_net_init(tn, &act_connmark_ops);
} }
static void __net_exit connmark_exit_net(struct net *net) static void __net_exit connmark_exit_net(struct net *net)

View File

@ -626,7 +626,7 @@ static __net_init int csum_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, csum_net_id); struct tc_action_net *tn = net_generic(net, csum_net_id);
return tc_action_net_init(tn, &act_csum_ops, net); return tc_action_net_init(tn, &act_csum_ops);
} }
static void __net_exit csum_exit_net(struct net *net) static void __net_exit csum_exit_net(struct net *net)

View File

@ -232,7 +232,7 @@ static __net_init int gact_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, gact_net_id); struct tc_action_net *tn = net_generic(net, gact_net_id);
return tc_action_net_init(tn, &act_gact_ops, net); return tc_action_net_init(tn, &act_gact_ops);
} }
static void __net_exit gact_exit_net(struct net *net) static void __net_exit gact_exit_net(struct net *net)

View File

@ -818,7 +818,7 @@ static __net_init int ife_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, ife_net_id); struct tc_action_net *tn = net_generic(net, ife_net_id);
return tc_action_net_init(tn, &act_ife_ops, net); return tc_action_net_init(tn, &act_ife_ops);
} }
static void __net_exit ife_exit_net(struct net *net) static void __net_exit ife_exit_net(struct net *net)

View File

@ -334,7 +334,7 @@ static __net_init int ipt_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, ipt_net_id); struct tc_action_net *tn = net_generic(net, ipt_net_id);
return tc_action_net_init(tn, &act_ipt_ops, net); return tc_action_net_init(tn, &act_ipt_ops);
} }
static void __net_exit ipt_exit_net(struct net *net) static void __net_exit ipt_exit_net(struct net *net)
@ -384,7 +384,7 @@ static __net_init int xt_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, xt_net_id); struct tc_action_net *tn = net_generic(net, xt_net_id);
return tc_action_net_init(tn, &act_xt_ops, net); return tc_action_net_init(tn, &act_xt_ops);
} }
static void __net_exit xt_exit_net(struct net *net) static void __net_exit xt_exit_net(struct net *net)

View File

@ -343,7 +343,7 @@ static __net_init int mirred_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, mirred_net_id); struct tc_action_net *tn = net_generic(net, mirred_net_id);
return tc_action_net_init(tn, &act_mirred_ops, net); return tc_action_net_init(tn, &act_mirred_ops);
} }
static void __net_exit mirred_exit_net(struct net *net) static void __net_exit mirred_exit_net(struct net *net)

View File

@ -307,7 +307,7 @@ static __net_init int nat_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, nat_net_id); struct tc_action_net *tn = net_generic(net, nat_net_id);
return tc_action_net_init(tn, &act_nat_ops, net); return tc_action_net_init(tn, &act_nat_ops);
} }
static void __net_exit nat_exit_net(struct net *net) static void __net_exit nat_exit_net(struct net *net)

View File

@ -450,7 +450,7 @@ static __net_init int pedit_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, pedit_net_id); struct tc_action_net *tn = net_generic(net, pedit_net_id);
return tc_action_net_init(tn, &act_pedit_ops, net); return tc_action_net_init(tn, &act_pedit_ops);
} }
static void __net_exit pedit_exit_net(struct net *net) static void __net_exit pedit_exit_net(struct net *net)

View File

@ -331,7 +331,7 @@ static __net_init int police_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, police_net_id); struct tc_action_net *tn = net_generic(net, police_net_id);
return tc_action_net_init(tn, &act_police_ops, net); return tc_action_net_init(tn, &act_police_ops);
} }
static void __net_exit police_exit_net(struct net *net) static void __net_exit police_exit_net(struct net *net)

View File

@ -240,7 +240,7 @@ static __net_init int sample_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, sample_net_id); struct tc_action_net *tn = net_generic(net, sample_net_id);
return tc_action_net_init(tn, &act_sample_ops, net); return tc_action_net_init(tn, &act_sample_ops);
} }
static void __net_exit sample_exit_net(struct net *net) static void __net_exit sample_exit_net(struct net *net)

View File

@ -201,7 +201,7 @@ static __net_init int simp_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, simp_net_id); struct tc_action_net *tn = net_generic(net, simp_net_id);
return tc_action_net_init(tn, &act_simp_ops, net); return tc_action_net_init(tn, &act_simp_ops);
} }
static void __net_exit simp_exit_net(struct net *net) static void __net_exit simp_exit_net(struct net *net)

View File

@ -238,7 +238,7 @@ static __net_init int skbedit_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, skbedit_net_id); struct tc_action_net *tn = net_generic(net, skbedit_net_id);
return tc_action_net_init(tn, &act_skbedit_ops, net); return tc_action_net_init(tn, &act_skbedit_ops);
} }
static void __net_exit skbedit_exit_net(struct net *net) static void __net_exit skbedit_exit_net(struct net *net)

View File

@ -263,7 +263,7 @@ static __net_init int skbmod_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, skbmod_net_id); struct tc_action_net *tn = net_generic(net, skbmod_net_id);
return tc_action_net_init(tn, &act_skbmod_ops, net); return tc_action_net_init(tn, &act_skbmod_ops);
} }
static void __net_exit skbmod_exit_net(struct net *net) static void __net_exit skbmod_exit_net(struct net *net)

View File

@ -322,7 +322,7 @@ static __net_init int tunnel_key_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, tunnel_key_net_id); struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
return tc_action_net_init(tn, &act_tunnel_key_ops, net); return tc_action_net_init(tn, &act_tunnel_key_ops);
} }
static void __net_exit tunnel_key_exit_net(struct net *net) static void __net_exit tunnel_key_exit_net(struct net *net)

View File

@ -269,7 +269,7 @@ static __net_init int vlan_init_net(struct net *net)
{ {
struct tc_action_net *tn = net_generic(net, vlan_net_id); struct tc_action_net *tn = net_generic(net, vlan_net_id);
return tc_action_net_init(tn, &act_vlan_ops, net); return tc_action_net_init(tn, &act_vlan_ops);
} }
static void __net_exit vlan_exit_net(struct net *net) static void __net_exit vlan_exit_net(struct net *net)

View File

@ -927,6 +927,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
exts->actions[i++] = act; exts->actions[i++] = act;
exts->nr_actions = i; exts->nr_actions = i;
} }
exts->net = net;
} }
#else #else
if ((exts->action && tb[exts->action]) || if ((exts->action && tb[exts->action]) ||

View File

@ -85,16 +85,21 @@ static int basic_init(struct tcf_proto *tp)
return 0; return 0;
} }
static void __basic_delete_filter(struct basic_filter *f)
{
tcf_exts_destroy(&f->exts);
tcf_em_tree_destroy(&f->ematches);
tcf_exts_put_net(&f->exts);
kfree(f);
}
static void basic_delete_filter_work(struct work_struct *work) static void basic_delete_filter_work(struct work_struct *work)
{ {
struct basic_filter *f = container_of(work, struct basic_filter, work); struct basic_filter *f = container_of(work, struct basic_filter, work);
rtnl_lock(); rtnl_lock();
tcf_exts_destroy(&f->exts); __basic_delete_filter(f);
tcf_em_tree_destroy(&f->ematches);
rtnl_unlock(); rtnl_unlock();
kfree(f);
} }
static void basic_delete_filter(struct rcu_head *head) static void basic_delete_filter(struct rcu_head *head)
@ -113,7 +118,10 @@ static void basic_destroy(struct tcf_proto *tp)
list_for_each_entry_safe(f, n, &head->flist, link) { list_for_each_entry_safe(f, n, &head->flist, link) {
list_del_rcu(&f->link); list_del_rcu(&f->link);
tcf_unbind_filter(tp, &f->res); tcf_unbind_filter(tp, &f->res);
call_rcu(&f->rcu, basic_delete_filter); if (tcf_exts_get_net(&f->exts))
call_rcu(&f->rcu, basic_delete_filter);
else
__basic_delete_filter(f);
} }
kfree_rcu(head, rcu); kfree_rcu(head, rcu);
} }
@ -125,6 +133,7 @@ static int basic_delete(struct tcf_proto *tp, void *arg, bool *last)
list_del_rcu(&f->link); list_del_rcu(&f->link);
tcf_unbind_filter(tp, &f->res); tcf_unbind_filter(tp, &f->res);
tcf_exts_get_net(&f->exts);
call_rcu(&f->rcu, basic_delete_filter); call_rcu(&f->rcu, basic_delete_filter);
*last = list_empty(&head->flist); *last = list_empty(&head->flist);
return 0; return 0;
@ -219,6 +228,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb,
if (fold) { if (fold) {
list_replace_rcu(&fold->link, &fnew->link); list_replace_rcu(&fold->link, &fnew->link);
tcf_unbind_filter(tp, &fold->res); tcf_unbind_filter(tp, &fold->res);
tcf_exts_get_net(&fold->exts);
call_rcu(&fold->rcu, basic_delete_filter); call_rcu(&fold->rcu, basic_delete_filter);
} else { } else {
list_add_rcu(&fnew->link, &head->flist); list_add_rcu(&fnew->link, &head->flist);

View File

@ -249,6 +249,7 @@ static int cls_bpf_init(struct tcf_proto *tp)
static void __cls_bpf_delete_prog(struct cls_bpf_prog *prog) static void __cls_bpf_delete_prog(struct cls_bpf_prog *prog)
{ {
tcf_exts_destroy(&prog->exts); tcf_exts_destroy(&prog->exts);
tcf_exts_put_net(&prog->exts);
if (cls_bpf_is_ebpf(prog)) if (cls_bpf_is_ebpf(prog))
bpf_prog_put(prog->filter); bpf_prog_put(prog->filter);
@ -282,7 +283,10 @@ static void __cls_bpf_delete(struct tcf_proto *tp, struct cls_bpf_prog *prog)
cls_bpf_stop_offload(tp, prog); cls_bpf_stop_offload(tp, prog);
list_del_rcu(&prog->link); list_del_rcu(&prog->link);
tcf_unbind_filter(tp, &prog->res); tcf_unbind_filter(tp, &prog->res);
call_rcu(&prog->rcu, cls_bpf_delete_prog_rcu); if (tcf_exts_get_net(&prog->exts))
call_rcu(&prog->rcu, cls_bpf_delete_prog_rcu);
else
__cls_bpf_delete_prog(prog);
} }
static int cls_bpf_delete(struct tcf_proto *tp, void *arg, bool *last) static int cls_bpf_delete(struct tcf_proto *tp, void *arg, bool *last)
@ -516,6 +520,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
if (oldprog) { if (oldprog) {
list_replace_rcu(&oldprog->link, &prog->link); list_replace_rcu(&oldprog->link, &prog->link);
tcf_unbind_filter(tp, &oldprog->res); tcf_unbind_filter(tp, &oldprog->res);
tcf_exts_get_net(&oldprog->exts);
call_rcu(&oldprog->rcu, cls_bpf_delete_prog_rcu); call_rcu(&oldprog->rcu, cls_bpf_delete_prog_rcu);
} else { } else {
list_add_rcu(&prog->link, &head->plist); list_add_rcu(&prog->link, &head->plist);

View File

@ -60,15 +60,21 @@ static const struct nla_policy cgroup_policy[TCA_CGROUP_MAX + 1] = {
[TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED }, [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED },
}; };
static void __cls_cgroup_destroy(struct cls_cgroup_head *head)
{
tcf_exts_destroy(&head->exts);
tcf_em_tree_destroy(&head->ematches);
tcf_exts_put_net(&head->exts);
kfree(head);
}
static void cls_cgroup_destroy_work(struct work_struct *work) static void cls_cgroup_destroy_work(struct work_struct *work)
{ {
struct cls_cgroup_head *head = container_of(work, struct cls_cgroup_head *head = container_of(work,
struct cls_cgroup_head, struct cls_cgroup_head,
work); work);
rtnl_lock(); rtnl_lock();
tcf_exts_destroy(&head->exts); __cls_cgroup_destroy(head);
tcf_em_tree_destroy(&head->ematches);
kfree(head);
rtnl_unlock(); rtnl_unlock();
} }
@ -124,8 +130,10 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
goto errout; goto errout;
rcu_assign_pointer(tp->root, new); rcu_assign_pointer(tp->root, new);
if (head) if (head) {
tcf_exts_get_net(&head->exts);
call_rcu(&head->rcu, cls_cgroup_destroy_rcu); call_rcu(&head->rcu, cls_cgroup_destroy_rcu);
}
return 0; return 0;
errout: errout:
tcf_exts_destroy(&new->exts); tcf_exts_destroy(&new->exts);
@ -138,8 +146,12 @@ static void cls_cgroup_destroy(struct tcf_proto *tp)
struct cls_cgroup_head *head = rtnl_dereference(tp->root); struct cls_cgroup_head *head = rtnl_dereference(tp->root);
/* Head can still be NULL due to cls_cgroup_init(). */ /* Head can still be NULL due to cls_cgroup_init(). */
if (head) if (head) {
call_rcu(&head->rcu, cls_cgroup_destroy_rcu); if (tcf_exts_get_net(&head->exts))
call_rcu(&head->rcu, cls_cgroup_destroy_rcu);
else
__cls_cgroup_destroy(head);
}
} }
static int cls_cgroup_delete(struct tcf_proto *tp, void *arg, bool *last) static int cls_cgroup_delete(struct tcf_proto *tp, void *arg, bool *last)

View File

@ -372,15 +372,21 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = {
[TCA_FLOW_PERTURB] = { .type = NLA_U32 }, [TCA_FLOW_PERTURB] = { .type = NLA_U32 },
}; };
static void __flow_destroy_filter(struct flow_filter *f)
{
del_timer_sync(&f->perturb_timer);
tcf_exts_destroy(&f->exts);
tcf_em_tree_destroy(&f->ematches);
tcf_exts_put_net(&f->exts);
kfree(f);
}
static void flow_destroy_filter_work(struct work_struct *work) static void flow_destroy_filter_work(struct work_struct *work)
{ {
struct flow_filter *f = container_of(work, struct flow_filter, work); struct flow_filter *f = container_of(work, struct flow_filter, work);
rtnl_lock(); rtnl_lock();
del_timer_sync(&f->perturb_timer); __flow_destroy_filter(f);
tcf_exts_destroy(&f->exts);
tcf_em_tree_destroy(&f->ematches);
kfree(f);
rtnl_unlock(); rtnl_unlock();
} }
@ -552,8 +558,10 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
*arg = fnew; *arg = fnew;
if (fold) if (fold) {
tcf_exts_get_net(&fold->exts);
call_rcu(&fold->rcu, flow_destroy_filter); call_rcu(&fold->rcu, flow_destroy_filter);
}
return 0; return 0;
err2: err2:
@ -570,6 +578,7 @@ static int flow_delete(struct tcf_proto *tp, void *arg, bool *last)
struct flow_filter *f = arg; struct flow_filter *f = arg;
list_del_rcu(&f->list); list_del_rcu(&f->list);
tcf_exts_get_net(&f->exts);
call_rcu(&f->rcu, flow_destroy_filter); call_rcu(&f->rcu, flow_destroy_filter);
*last = list_empty(&head->filters); *last = list_empty(&head->filters);
return 0; return 0;
@ -594,7 +603,10 @@ static void flow_destroy(struct tcf_proto *tp)
list_for_each_entry_safe(f, next, &head->filters, list) { list_for_each_entry_safe(f, next, &head->filters, list) {
list_del_rcu(&f->list); list_del_rcu(&f->list);
call_rcu(&f->rcu, flow_destroy_filter); if (tcf_exts_get_net(&f->exts))
call_rcu(&f->rcu, flow_destroy_filter);
else
__flow_destroy_filter(f);
} }
kfree_rcu(head, rcu); kfree_rcu(head, rcu);
} }

View File

@ -218,13 +218,19 @@ static int fl_init(struct tcf_proto *tp)
return 0; return 0;
} }
static void __fl_destroy_filter(struct cls_fl_filter *f)
{
tcf_exts_destroy(&f->exts);
tcf_exts_put_net(&f->exts);
kfree(f);
}
static void fl_destroy_filter_work(struct work_struct *work) static void fl_destroy_filter_work(struct work_struct *work)
{ {
struct cls_fl_filter *f = container_of(work, struct cls_fl_filter, work); struct cls_fl_filter *f = container_of(work, struct cls_fl_filter, work);
rtnl_lock(); rtnl_lock();
tcf_exts_destroy(&f->exts); __fl_destroy_filter(f);
kfree(f);
rtnl_unlock(); rtnl_unlock();
} }
@ -318,7 +324,10 @@ static void __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f)
if (!tc_skip_hw(f->flags)) if (!tc_skip_hw(f->flags))
fl_hw_destroy_filter(tp, f); fl_hw_destroy_filter(tp, f);
tcf_unbind_filter(tp, &f->res); tcf_unbind_filter(tp, &f->res);
call_rcu(&f->rcu, fl_destroy_filter); if (tcf_exts_get_net(&f->exts))
call_rcu(&f->rcu, fl_destroy_filter);
else
__fl_destroy_filter(f);
} }
static void fl_destroy_sleepable(struct work_struct *work) static void fl_destroy_sleepable(struct work_struct *work)
@ -988,6 +997,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
idr_replace_ext(&head->handle_idr, fnew, fnew->handle); idr_replace_ext(&head->handle_idr, fnew, fnew->handle);
list_replace_rcu(&fold->list, &fnew->list); list_replace_rcu(&fold->list, &fnew->list);
tcf_unbind_filter(tp, &fold->res); tcf_unbind_filter(tp, &fold->res);
tcf_exts_get_net(&fold->exts);
call_rcu(&fold->rcu, fl_destroy_filter); call_rcu(&fold->rcu, fl_destroy_filter);
} else { } else {
list_add_tail_rcu(&fnew->list, &head->filters); list_add_tail_rcu(&fnew->list, &head->filters);

View File

@ -122,13 +122,19 @@ static int fw_init(struct tcf_proto *tp)
return 0; return 0;
} }
static void __fw_delete_filter(struct fw_filter *f)
{
tcf_exts_destroy(&f->exts);
tcf_exts_put_net(&f->exts);
kfree(f);
}
static void fw_delete_filter_work(struct work_struct *work) static void fw_delete_filter_work(struct work_struct *work)
{ {
struct fw_filter *f = container_of(work, struct fw_filter, work); struct fw_filter *f = container_of(work, struct fw_filter, work);
rtnl_lock(); rtnl_lock();
tcf_exts_destroy(&f->exts); __fw_delete_filter(f);
kfree(f);
rtnl_unlock(); rtnl_unlock();
} }
@ -154,7 +160,10 @@ static void fw_destroy(struct tcf_proto *tp)
RCU_INIT_POINTER(head->ht[h], RCU_INIT_POINTER(head->ht[h],
rtnl_dereference(f->next)); rtnl_dereference(f->next));
tcf_unbind_filter(tp, &f->res); tcf_unbind_filter(tp, &f->res);
call_rcu(&f->rcu, fw_delete_filter); if (tcf_exts_get_net(&f->exts))
call_rcu(&f->rcu, fw_delete_filter);
else
__fw_delete_filter(f);
} }
} }
kfree_rcu(head, rcu); kfree_rcu(head, rcu);
@ -179,6 +188,7 @@ static int fw_delete(struct tcf_proto *tp, void *arg, bool *last)
if (pfp == f) { if (pfp == f) {
RCU_INIT_POINTER(*fp, rtnl_dereference(f->next)); RCU_INIT_POINTER(*fp, rtnl_dereference(f->next));
tcf_unbind_filter(tp, &f->res); tcf_unbind_filter(tp, &f->res);
tcf_exts_get_net(&f->exts);
call_rcu(&f->rcu, fw_delete_filter); call_rcu(&f->rcu, fw_delete_filter);
ret = 0; ret = 0;
break; break;
@ -299,6 +309,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
RCU_INIT_POINTER(fnew->next, rtnl_dereference(pfp->next)); RCU_INIT_POINTER(fnew->next, rtnl_dereference(pfp->next));
rcu_assign_pointer(*fp, fnew); rcu_assign_pointer(*fp, fnew);
tcf_unbind_filter(tp, &f->res); tcf_unbind_filter(tp, &f->res);
tcf_exts_get_net(&f->exts);
call_rcu(&f->rcu, fw_delete_filter); call_rcu(&f->rcu, fw_delete_filter);
*arg = fnew; *arg = fnew;

View File

@ -44,13 +44,19 @@ static int mall_init(struct tcf_proto *tp)
return 0; return 0;
} }
static void __mall_destroy(struct cls_mall_head *head)
{
tcf_exts_destroy(&head->exts);
tcf_exts_put_net(&head->exts);
kfree(head);
}
static void mall_destroy_work(struct work_struct *work) static void mall_destroy_work(struct work_struct *work)
{ {
struct cls_mall_head *head = container_of(work, struct cls_mall_head, struct cls_mall_head *head = container_of(work, struct cls_mall_head,
work); work);
rtnl_lock(); rtnl_lock();
tcf_exts_destroy(&head->exts); __mall_destroy(head);
kfree(head);
rtnl_unlock(); rtnl_unlock();
} }
@ -109,7 +115,10 @@ static void mall_destroy(struct tcf_proto *tp)
if (tc_should_offload(dev, head->flags)) if (tc_should_offload(dev, head->flags))
mall_destroy_hw_filter(tp, head, (unsigned long) head); mall_destroy_hw_filter(tp, head, (unsigned long) head);
call_rcu(&head->rcu, mall_destroy_rcu); if (tcf_exts_get_net(&head->exts))
call_rcu(&head->rcu, mall_destroy_rcu);
else
__mall_destroy(head);
} }
static void *mall_get(struct tcf_proto *tp, u32 handle) static void *mall_get(struct tcf_proto *tp, u32 handle)

View File

@ -257,13 +257,19 @@ static int route4_init(struct tcf_proto *tp)
return 0; return 0;
} }
static void __route4_delete_filter(struct route4_filter *f)
{
tcf_exts_destroy(&f->exts);
tcf_exts_put_net(&f->exts);
kfree(f);
}
static void route4_delete_filter_work(struct work_struct *work) static void route4_delete_filter_work(struct work_struct *work)
{ {
struct route4_filter *f = container_of(work, struct route4_filter, work); struct route4_filter *f = container_of(work, struct route4_filter, work);
rtnl_lock(); rtnl_lock();
tcf_exts_destroy(&f->exts); __route4_delete_filter(f);
kfree(f);
rtnl_unlock(); rtnl_unlock();
} }
@ -297,7 +303,10 @@ static void route4_destroy(struct tcf_proto *tp)
next = rtnl_dereference(f->next); next = rtnl_dereference(f->next);
RCU_INIT_POINTER(b->ht[h2], next); RCU_INIT_POINTER(b->ht[h2], next);
tcf_unbind_filter(tp, &f->res); tcf_unbind_filter(tp, &f->res);
call_rcu(&f->rcu, route4_delete_filter); if (tcf_exts_get_net(&f->exts))
call_rcu(&f->rcu, route4_delete_filter);
else
__route4_delete_filter(f);
} }
} }
RCU_INIT_POINTER(head->table[h1], NULL); RCU_INIT_POINTER(head->table[h1], NULL);
@ -338,6 +347,7 @@ static int route4_delete(struct tcf_proto *tp, void *arg, bool *last)
/* Delete it */ /* Delete it */
tcf_unbind_filter(tp, &f->res); tcf_unbind_filter(tp, &f->res);
tcf_exts_get_net(&f->exts);
call_rcu(&f->rcu, route4_delete_filter); call_rcu(&f->rcu, route4_delete_filter);
/* Strip RTNL protected tree */ /* Strip RTNL protected tree */
@ -541,6 +551,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
*arg = f; *arg = f;
if (fold) { if (fold) {
tcf_unbind_filter(tp, &fold->res); tcf_unbind_filter(tp, &fold->res);
tcf_exts_get_net(&fold->exts);
call_rcu(&fold->rcu, route4_delete_filter); call_rcu(&fold->rcu, route4_delete_filter);
} }
return 0; return 0;

View File

@ -285,13 +285,19 @@ static int rsvp_init(struct tcf_proto *tp)
return -ENOBUFS; return -ENOBUFS;
} }
static void __rsvp_delete_filter(struct rsvp_filter *f)
{
tcf_exts_destroy(&f->exts);
tcf_exts_put_net(&f->exts);
kfree(f);
}
static void rsvp_delete_filter_work(struct work_struct *work) static void rsvp_delete_filter_work(struct work_struct *work)
{ {
struct rsvp_filter *f = container_of(work, struct rsvp_filter, work); struct rsvp_filter *f = container_of(work, struct rsvp_filter, work);
rtnl_lock(); rtnl_lock();
tcf_exts_destroy(&f->exts); __rsvp_delete_filter(f);
kfree(f);
rtnl_unlock(); rtnl_unlock();
} }
@ -310,7 +316,10 @@ static void rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f)
* grace period, since converted-to-rcu actions are relying on that * grace period, since converted-to-rcu actions are relying on that
* in cleanup() callback * in cleanup() callback
*/ */
call_rcu(&f->rcu, rsvp_delete_filter_rcu); if (tcf_exts_get_net(&f->exts))
call_rcu(&f->rcu, rsvp_delete_filter_rcu);
else
__rsvp_delete_filter(f);
} }
static void rsvp_destroy(struct tcf_proto *tp) static void rsvp_destroy(struct tcf_proto *tp)

View File

@ -139,13 +139,19 @@ static int tcindex_init(struct tcf_proto *tp)
return 0; return 0;
} }
static void __tcindex_destroy_rexts(struct tcindex_filter_result *r)
{
tcf_exts_destroy(&r->exts);
tcf_exts_put_net(&r->exts);
}
static void tcindex_destroy_rexts_work(struct work_struct *work) static void tcindex_destroy_rexts_work(struct work_struct *work)
{ {
struct tcindex_filter_result *r; struct tcindex_filter_result *r;
r = container_of(work, struct tcindex_filter_result, work); r = container_of(work, struct tcindex_filter_result, work);
rtnl_lock(); rtnl_lock();
tcf_exts_destroy(&r->exts); __tcindex_destroy_rexts(r);
rtnl_unlock(); rtnl_unlock();
} }
@ -158,14 +164,20 @@ static void tcindex_destroy_rexts(struct rcu_head *head)
tcf_queue_work(&r->work); tcf_queue_work(&r->work);
} }
static void __tcindex_destroy_fexts(struct tcindex_filter *f)
{
tcf_exts_destroy(&f->result.exts);
tcf_exts_put_net(&f->result.exts);
kfree(f);
}
static void tcindex_destroy_fexts_work(struct work_struct *work) static void tcindex_destroy_fexts_work(struct work_struct *work)
{ {
struct tcindex_filter *f = container_of(work, struct tcindex_filter, struct tcindex_filter *f = container_of(work, struct tcindex_filter,
work); work);
rtnl_lock(); rtnl_lock();
tcf_exts_destroy(&f->result.exts); __tcindex_destroy_fexts(f);
kfree(f);
rtnl_unlock(); rtnl_unlock();
} }
@ -210,10 +222,17 @@ found:
* grace period, since converted-to-rcu actions are relying on that * grace period, since converted-to-rcu actions are relying on that
* in cleanup() callback * in cleanup() callback
*/ */
if (f) if (f) {
call_rcu(&f->rcu, tcindex_destroy_fexts); if (tcf_exts_get_net(&f->result.exts))
else call_rcu(&f->rcu, tcindex_destroy_fexts);
call_rcu(&r->rcu, tcindex_destroy_rexts); else
__tcindex_destroy_fexts(f);
} else {
if (tcf_exts_get_net(&r->exts))
call_rcu(&r->rcu, tcindex_destroy_rexts);
else
__tcindex_destroy_rexts(r);
}
*last = false; *last = false;
return 0; return 0;

View File

@ -399,6 +399,7 @@ static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n,
bool free_pf) bool free_pf)
{ {
tcf_exts_destroy(&n->exts); tcf_exts_destroy(&n->exts);
tcf_exts_put_net(&n->exts);
if (n->ht_down) if (n->ht_down)
n->ht_down->refcnt--; n->ht_down->refcnt--;
#ifdef CONFIG_CLS_U32_PERF #ifdef CONFIG_CLS_U32_PERF
@ -476,6 +477,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
RCU_INIT_POINTER(*kp, key->next); RCU_INIT_POINTER(*kp, key->next);
tcf_unbind_filter(tp, &key->res); tcf_unbind_filter(tp, &key->res);
tcf_exts_get_net(&key->exts);
call_rcu(&key->rcu, u32_delete_key_freepf_rcu); call_rcu(&key->rcu, u32_delete_key_freepf_rcu);
return 0; return 0;
} }
@ -588,7 +590,10 @@ static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht)
rtnl_dereference(n->next)); rtnl_dereference(n->next));
tcf_unbind_filter(tp, &n->res); tcf_unbind_filter(tp, &n->res);
u32_remove_hw_knode(tp, n->handle); u32_remove_hw_knode(tp, n->handle);
call_rcu(&n->rcu, u32_delete_key_freepf_rcu); if (tcf_exts_get_net(&n->exts))
call_rcu(&n->rcu, u32_delete_key_freepf_rcu);
else
u32_destroy_key(n->tp, n, true);
} }
} }
} }
@ -949,6 +954,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
u32_replace_knode(tp, tp_c, new); u32_replace_knode(tp, tp_c, new);
tcf_unbind_filter(tp, &n->res); tcf_unbind_filter(tp, &n->res);
tcf_exts_get_net(&n->exts);
call_rcu(&n->rcu, u32_delete_key_rcu); call_rcu(&n->rcu, u32_delete_key_rcu);
return 0; return 0;
} }

View File

@ -266,8 +266,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
goto lock; goto lock;
} }
daddr = (xfrm_address_t *)(skb_network_header(skb) +
XFRM_SPI_SKB_CB(skb)->daddroff);
family = XFRM_SPI_SKB_CB(skb)->family; family = XFRM_SPI_SKB_CB(skb)->family;
/* if tunnel is present override skb->mark value with tunnel i_key */ /* if tunnel is present override skb->mark value with tunnel i_key */
@ -294,6 +292,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
goto drop; goto drop;
} }
daddr = (xfrm_address_t *)(skb_network_header(skb) +
XFRM_SPI_SKB_CB(skb)->daddroff);
do { do {
if (skb->sp->len == XFRM_MAX_DEPTH) { if (skb->sp->len == XFRM_MAX_DEPTH) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR); XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);

View File

@ -1361,36 +1361,29 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl,
struct net *net = xp_net(policy); struct net *net = xp_net(policy);
int nx; int nx;
int i, error; int i, error;
xfrm_address_t *daddr = xfrm_flowi_daddr(fl, family);
xfrm_address_t *saddr = xfrm_flowi_saddr(fl, family);
xfrm_address_t tmp; xfrm_address_t tmp;
for (nx = 0, i = 0; i < policy->xfrm_nr; i++) { for (nx = 0, i = 0; i < policy->xfrm_nr; i++) {
struct xfrm_state *x; struct xfrm_state *x;
xfrm_address_t *remote = daddr; xfrm_address_t *local;
xfrm_address_t *local = saddr; xfrm_address_t *remote;
struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i]; struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i];
if (tmpl->mode == XFRM_MODE_TUNNEL || remote = &tmpl->id.daddr;
tmpl->mode == XFRM_MODE_BEET) { local = &tmpl->saddr;
remote = &tmpl->id.daddr; if (xfrm_addr_any(local, tmpl->encap_family)) {
local = &tmpl->saddr; error = xfrm_get_saddr(net, fl->flowi_oif,
if (xfrm_addr_any(local, tmpl->encap_family)) { &tmp, remote,
error = xfrm_get_saddr(net, fl->flowi_oif, tmpl->encap_family, 0);
&tmp, remote, if (error)
tmpl->encap_family, 0); goto fail;
if (error) local = &tmp;
goto fail;
local = &tmp;
}
} }
x = xfrm_state_find(remote, local, fl, tmpl, policy, &error, family); x = xfrm_state_find(remote, local, fl, tmpl, policy, &error, family);
if (x && x->km.state == XFRM_STATE_VALID) { if (x && x->km.state == XFRM_STATE_VALID) {
xfrm[nx++] = x; xfrm[nx++] = x;
daddr = remote;
saddr = local;
continue; continue;
} }
if (x) { if (x) {
@ -1787,19 +1780,23 @@ void xfrm_policy_cache_flush(void)
put_online_cpus(); put_online_cpus();
} }
static bool xfrm_pol_dead(struct xfrm_dst *xdst) static bool xfrm_xdst_can_reuse(struct xfrm_dst *xdst,
struct xfrm_state * const xfrm[],
int num)
{ {
unsigned int num_pols = xdst->num_pols; const struct dst_entry *dst = &xdst->u.dst;
unsigned int pol_dead = 0, i; int i;
for (i = 0; i < num_pols; i++) if (xdst->num_xfrms != num)
pol_dead |= xdst->pols[i]->walk.dead; return false;
/* Mark DST_OBSOLETE_DEAD to fail the next xfrm_dst_check() */ for (i = 0; i < num; i++) {
if (pol_dead) if (!dst || dst->xfrm != xfrm[i])
xdst->u.dst.obsolete = DST_OBSOLETE_DEAD; return false;
dst = dst->child;
}
return pol_dead; return xfrm_bundle_ok(xdst);
} }
static struct xfrm_dst * static struct xfrm_dst *
@ -1813,19 +1810,6 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
struct dst_entry *dst; struct dst_entry *dst;
int err; int err;
xdst = this_cpu_read(xfrm_last_dst);
if (xdst &&
xdst->u.dst.dev == dst_orig->dev &&
xdst->num_pols == num_pols &&
!xfrm_pol_dead(xdst) &&
memcmp(xdst->pols, pols,
sizeof(struct xfrm_policy *) * num_pols) == 0 &&
xfrm_bundle_ok(xdst)) {
dst_hold(&xdst->u.dst);
return xdst;
}
old = xdst;
/* Try to instantiate a bundle */ /* Try to instantiate a bundle */
err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family); err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family);
if (err <= 0) { if (err <= 0) {
@ -1834,6 +1818,21 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
return ERR_PTR(err); return ERR_PTR(err);
} }
xdst = this_cpu_read(xfrm_last_dst);
if (xdst &&
xdst->u.dst.dev == dst_orig->dev &&
xdst->num_pols == num_pols &&
memcmp(xdst->pols, pols,
sizeof(struct xfrm_policy *) * num_pols) == 0 &&
xfrm_xdst_can_reuse(xdst, xfrm, err)) {
dst_hold(&xdst->u.dst);
while (err > 0)
xfrm_state_put(xfrm[--err]);
return xdst;
}
old = xdst;
dst = xfrm_bundle_create(pols[0], xfrm, err, fl, dst_orig); dst = xfrm_bundle_create(pols[0], xfrm, err, fl, dst_orig);
if (IS_ERR(dst)) { if (IS_ERR(dst)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLEGENERROR); XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLEGENERROR);

View File

@ -128,7 +128,7 @@ static inline int map_signal_num(int sig)
return SIGUNKNOWN; return SIGUNKNOWN;
else if (sig >= SIGRTMIN) else if (sig >= SIGRTMIN)
return sig - SIGRTMIN + 128; /* rt sigs mapped to 128 */ return sig - SIGRTMIN + 128; /* rt sigs mapped to 128 */
else if (sig <= MAXMAPPED_SIG) else if (sig < MAXMAPPED_SIG)
return sig_map[sig]; return sig_map[sig];
return SIGUNKNOWN; return SIGUNKNOWN;
} }
@ -163,7 +163,7 @@ static void audit_signal_cb(struct audit_buffer *ab, void *va)
audit_signal_mask(ab, aad(sa)->denied); audit_signal_mask(ab, aad(sa)->denied);
} }
} }
if (aad(sa)->signal <= MAXMAPPED_SIG) if (aad(sa)->signal < MAXMAPPED_SIG)
audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]); audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]);
else else
audit_log_format(ab, " signal=rtmin+%d", audit_log_format(ab, " signal=rtmin+%d",

View File

@ -159,6 +159,7 @@ static int __init snd_hrtimer_init(void)
timer->hw = hrtimer_hw; timer->hw = hrtimer_hw;
timer->hw.resolution = resolution; timer->hw.resolution = resolution;
timer->hw.ticks = NANO_SEC / resolution; timer->hw.ticks = NANO_SEC / resolution;
timer->max_instances = 100; /* lower the limit */
err = snd_timer_global_register(timer); err = snd_timer_global_register(timer);
if (err < 0) { if (err < 0) {

View File

@ -612,9 +612,7 @@ send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq
if (!dp->timer->running) if (!dp->timer->running)
len = snd_seq_oss_timer_start(dp->timer); len = snd_seq_oss_timer_start(dp->timer);
if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE) snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev);
snd_seq_oss_readq_puts(dp->readq, mdev->seq_device,
ev->data.ext.ptr, ev->data.ext.len);
} else { } else {
len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev); len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev);
if (len > 0) if (len > 0)

View File

@ -117,6 +117,35 @@ snd_seq_oss_readq_puts(struct seq_oss_readq *q, int dev, unsigned char *data, in
return 0; return 0;
} }
/*
* put MIDI sysex bytes; the event buffer may be chained, thus it has
* to be expanded via snd_seq_dump_var_event().
*/
struct readq_sysex_ctx {
struct seq_oss_readq *readq;
int dev;
};
static int readq_dump_sysex(void *ptr, void *buf, int count)
{
struct readq_sysex_ctx *ctx = ptr;
return snd_seq_oss_readq_puts(ctx->readq, ctx->dev, buf, count);
}
int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev,
struct snd_seq_event *ev)
{
struct readq_sysex_ctx ctx = {
.readq = q,
.dev = dev
};
if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
return 0;
return snd_seq_dump_var_event(ev, readq_dump_sysex, &ctx);
}
/* /*
* copy an event to input queue: * copy an event to input queue:
* return zero if enqueued * return zero if enqueued

View File

@ -44,6 +44,8 @@ void snd_seq_oss_readq_delete(struct seq_oss_readq *q);
void snd_seq_oss_readq_clear(struct seq_oss_readq *readq); void snd_seq_oss_readq_clear(struct seq_oss_readq *readq);
unsigned int snd_seq_oss_readq_poll(struct seq_oss_readq *readq, struct file *file, poll_table *wait); unsigned int snd_seq_oss_readq_poll(struct seq_oss_readq *readq, struct file *file, poll_table *wait);
int snd_seq_oss_readq_puts(struct seq_oss_readq *readq, int dev, unsigned char *data, int len); int snd_seq_oss_readq_puts(struct seq_oss_readq *readq, int dev, unsigned char *data, int len);
int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev,
struct snd_seq_event *ev);
int snd_seq_oss_readq_put_event(struct seq_oss_readq *readq, union evrec *ev); int snd_seq_oss_readq_put_event(struct seq_oss_readq *readq, union evrec *ev);
int snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *readq, unsigned long curt, int seq_mode); int snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *readq, unsigned long curt, int seq_mode);
int snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec); int snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec);

View File

@ -180,7 +180,7 @@ static void snd_timer_request(struct snd_timer_id *tid)
* *
* call this with register_mutex down. * call this with register_mutex down.
*/ */
static void snd_timer_check_slave(struct snd_timer_instance *slave) static int snd_timer_check_slave(struct snd_timer_instance *slave)
{ {
struct snd_timer *timer; struct snd_timer *timer;
struct snd_timer_instance *master; struct snd_timer_instance *master;
@ -190,16 +190,21 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave)
list_for_each_entry(master, &timer->open_list_head, open_list) { list_for_each_entry(master, &timer->open_list_head, open_list) {
if (slave->slave_class == master->slave_class && if (slave->slave_class == master->slave_class &&
slave->slave_id == master->slave_id) { slave->slave_id == master->slave_id) {
if (master->timer->num_instances >=
master->timer->max_instances)
return -EBUSY;
list_move_tail(&slave->open_list, list_move_tail(&slave->open_list,
&master->slave_list_head); &master->slave_list_head);
master->timer->num_instances++;
spin_lock_irq(&slave_active_lock); spin_lock_irq(&slave_active_lock);
slave->master = master; slave->master = master;
slave->timer = master->timer; slave->timer = master->timer;
spin_unlock_irq(&slave_active_lock); spin_unlock_irq(&slave_active_lock);
return; return 0;
} }
} }
} }
return 0;
} }
/* /*
@ -208,7 +213,7 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave)
* *
* call this with register_mutex down. * call this with register_mutex down.
*/ */
static void snd_timer_check_master(struct snd_timer_instance *master) static int snd_timer_check_master(struct snd_timer_instance *master)
{ {
struct snd_timer_instance *slave, *tmp; struct snd_timer_instance *slave, *tmp;
@ -216,7 +221,11 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) { list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) {
if (slave->slave_class == master->slave_class && if (slave->slave_class == master->slave_class &&
slave->slave_id == master->slave_id) { slave->slave_id == master->slave_id) {
if (master->timer->num_instances >=
master->timer->max_instances)
return -EBUSY;
list_move_tail(&slave->open_list, &master->slave_list_head); list_move_tail(&slave->open_list, &master->slave_list_head);
master->timer->num_instances++;
spin_lock_irq(&slave_active_lock); spin_lock_irq(&slave_active_lock);
spin_lock(&master->timer->lock); spin_lock(&master->timer->lock);
slave->master = master; slave->master = master;
@ -228,8 +237,11 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
spin_unlock_irq(&slave_active_lock); spin_unlock_irq(&slave_active_lock);
} }
} }
return 0;
} }
static int snd_timer_close_locked(struct snd_timer_instance *timeri);
/* /*
* open a timer instance * open a timer instance
* when opening a master, the slave id must be here given. * when opening a master, the slave id must be here given.
@ -240,6 +252,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
{ {
struct snd_timer *timer; struct snd_timer *timer;
struct snd_timer_instance *timeri = NULL; struct snd_timer_instance *timeri = NULL;
int err;
if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) { if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
/* open a slave instance */ /* open a slave instance */
@ -259,10 +272,14 @@ int snd_timer_open(struct snd_timer_instance **ti,
timeri->slave_id = tid->device; timeri->slave_id = tid->device;
timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
list_add_tail(&timeri->open_list, &snd_timer_slave_list); list_add_tail(&timeri->open_list, &snd_timer_slave_list);
snd_timer_check_slave(timeri); err = snd_timer_check_slave(timeri);
if (err < 0) {
snd_timer_close_locked(timeri);
timeri = NULL;
}
mutex_unlock(&register_mutex); mutex_unlock(&register_mutex);
*ti = timeri; *ti = timeri;
return 0; return err;
} }
/* open a master instance */ /* open a master instance */
@ -288,6 +305,10 @@ int snd_timer_open(struct snd_timer_instance **ti,
return -EBUSY; return -EBUSY;
} }
} }
if (timer->num_instances >= timer->max_instances) {
mutex_unlock(&register_mutex);
return -EBUSY;
}
timeri = snd_timer_instance_new(owner, timer); timeri = snd_timer_instance_new(owner, timer);
if (!timeri) { if (!timeri) {
mutex_unlock(&register_mutex); mutex_unlock(&register_mutex);
@ -314,25 +335,27 @@ int snd_timer_open(struct snd_timer_instance **ti,
} }
list_add_tail(&timeri->open_list, &timer->open_list_head); list_add_tail(&timeri->open_list, &timer->open_list_head);
snd_timer_check_master(timeri); timer->num_instances++;
err = snd_timer_check_master(timeri);
if (err < 0) {
snd_timer_close_locked(timeri);
timeri = NULL;
}
mutex_unlock(&register_mutex); mutex_unlock(&register_mutex);
*ti = timeri; *ti = timeri;
return 0; return err;
} }
EXPORT_SYMBOL(snd_timer_open); EXPORT_SYMBOL(snd_timer_open);
/* /*
* close a timer instance * close a timer instance
* call this with register_mutex down.
*/ */
int snd_timer_close(struct snd_timer_instance *timeri) static int snd_timer_close_locked(struct snd_timer_instance *timeri)
{ {
struct snd_timer *timer = NULL; struct snd_timer *timer = NULL;
struct snd_timer_instance *slave, *tmp; struct snd_timer_instance *slave, *tmp;
if (snd_BUG_ON(!timeri))
return -ENXIO;
mutex_lock(&register_mutex);
list_del(&timeri->open_list); list_del(&timeri->open_list);
/* force to stop the timer */ /* force to stop the timer */
@ -340,6 +363,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
timer = timeri->timer; timer = timeri->timer;
if (timer) { if (timer) {
timer->num_instances--;
/* wait, until the active callback is finished */ /* wait, until the active callback is finished */
spin_lock_irq(&timer->lock); spin_lock_irq(&timer->lock);
while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) { while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
@ -355,6 +379,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
open_list) { open_list) {
list_move_tail(&slave->open_list, &snd_timer_slave_list); list_move_tail(&slave->open_list, &snd_timer_slave_list);
timer->num_instances--;
slave->master = NULL; slave->master = NULL;
slave->timer = NULL; slave->timer = NULL;
list_del_init(&slave->ack_list); list_del_init(&slave->ack_list);
@ -382,9 +407,24 @@ int snd_timer_close(struct snd_timer_instance *timeri)
module_put(timer->module); module_put(timer->module);
} }
mutex_unlock(&register_mutex);
return 0; return 0;
} }
/*
* close a timer instance
*/
int snd_timer_close(struct snd_timer_instance *timeri)
{
int err;
if (snd_BUG_ON(!timeri))
return -ENXIO;
mutex_lock(&register_mutex);
err = snd_timer_close_locked(timeri);
mutex_unlock(&register_mutex);
return err;
}
EXPORT_SYMBOL(snd_timer_close); EXPORT_SYMBOL(snd_timer_close);
unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
@ -856,6 +896,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
spin_lock_init(&timer->lock); spin_lock_init(&timer->lock);
tasklet_init(&timer->task_queue, snd_timer_tasklet, tasklet_init(&timer->task_queue, snd_timer_tasklet,
(unsigned long)timer); (unsigned long)timer);
timer->max_instances = 1000; /* default limit per timer */
if (card != NULL) { if (card != NULL) {
timer->module = card->module; timer->module = card->module;
err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops); err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);

View File

@ -6544,6 +6544,11 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
{0x14, 0x90170110}, {0x14, 0x90170110},
{0x1b, 0x90a70130}, {0x1b, 0x90a70130},
{0x21, 0x03211020}), {0x21, 0x03211020}),
SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
{0x12, 0xb7a60130},
{0x13, 0xb8a61140},
{0x16, 0x90170110},
{0x21, 0x04211020}),
SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
{0x12, 0x90a60130}, {0x12, 0x90a60130},
{0x14, 0x90170110}, {0x14, 0x90170110},

View File

@ -1375,6 +1375,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
case 0x199: case 0x199:
return SNDRV_PCM_FMTBIT_DSD_U32_LE; return SNDRV_PCM_FMTBIT_DSD_U32_LE;
case 0x19b: case 0x19b:
case 0x203:
return SNDRV_PCM_FMTBIT_DSD_U32_BE; return SNDRV_PCM_FMTBIT_DSD_U32_BE;
default: default:
break; break;