Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion drivers/i2c/i2c-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* i2c-core.h - interfaces internal to the I2C framework
*/

#include <linux/kconfig.h>
#include <linux/rwsem.h>

struct i2c_devinfo {
Expand All @@ -29,7 +30,8 @@ int i2c_dev_irq_from_resources(const struct resource *resources,
*/
static inline bool i2c_in_atomic_xfer_mode(void)
{
return system_state > SYSTEM_RUNNING && irqs_disabled();
return system_state > SYSTEM_RUNNING &&
(IS_ENABLED(CONFIG_PREEMPT_COUNT) ? !preemptible() : irqs_disabled());
}

static inline int __i2c_lock_bus_helper(struct i2c_adapter *adap)
Expand Down
16 changes: 12 additions & 4 deletions drivers/infiniband/sw/siw/siw_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,7 @@ static void siw_accept_newconn(struct siw_cep *cep)
siw_cep_put(cep);
new_cep->listen_cep = NULL;
if (rv) {
siw_cancel_mpatimer(new_cep);
siw_cep_set_free(new_cep);
goto error;
}
Expand Down Expand Up @@ -1100,9 +1101,12 @@ static void siw_cm_work_handler(struct work_struct *w)
/*
* Socket close before MPA request received.
*/
siw_dbg_cep(cep, "no mpareq: drop listener\n");
siw_cep_put(cep->listen_cep);
cep->listen_cep = NULL;
if (cep->listen_cep) {
siw_dbg_cep(cep,
"no mpareq: drop listener\n");
siw_cep_put(cep->listen_cep);
cep->listen_cep = NULL;
}
}
}
release_cep = 1;
Expand Down Expand Up @@ -1227,7 +1231,11 @@ static void siw_cm_llp_data_ready(struct sock *sk)
if (!cep)
goto out;

siw_dbg_cep(cep, "state: %d\n", cep->state);
siw_dbg_cep(cep, "cep state: %d, socket state %d\n",
cep->state, sk->sk_state);

if (sk->sk_state != TCP_ESTABLISHED)
goto out;

switch (cep->state) {
case SIW_EPSTATE_RDMA_MODE:
Expand Down
17 changes: 14 additions & 3 deletions drivers/mmc/core/sdio_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,12 @@ static void sdio_release_func(struct device *dev)

sdio_free_func_cis(func);

/*
* We have now removed the link to the tuples in the
* card structure, so remove the reference.
*/
put_device(&func->card->dev);

kfree(func->info);
kfree(func->tmpbuf);
kfree(func);
Expand Down Expand Up @@ -322,6 +328,12 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card)

device_initialize(&func->dev);

/*
* We may link to tuples in the card structure,
* we need make sure we have a reference to it.
*/
get_device(&func->card->dev);

func->dev.parent = &card->dev;
func->dev.bus = &sdio_bus_type;
func->dev.release = sdio_release_func;
Expand Down Expand Up @@ -375,10 +387,9 @@ int sdio_add_func(struct sdio_func *func)
*/
void sdio_remove_func(struct sdio_func *func)
{
if (!sdio_func_present(func))
return;
if (sdio_func_present(func))
device_del(&func->dev);

device_del(&func->dev);
of_node_put(func->dev.of_node);
put_device(&func->dev);
}
Expand Down
12 changes: 0 additions & 12 deletions drivers/mmc/core/sdio_cis.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,12 +391,6 @@ int sdio_read_func_cis(struct sdio_func *func)
if (ret)
return ret;

/*
* Since we've linked to tuples in the card structure,
* we must make sure we have a reference to it.
*/
get_device(&func->card->dev);

/*
* Vendor/device id is optional for function CIS, so
* copy it from the card structure as needed.
Expand All @@ -422,11 +416,5 @@ void sdio_free_func_cis(struct sdio_func *func)
}

func->tuples = NULL;

/*
* We have now removed the link to the tuples in the
* card structure, so remove the reference.
*/
put_device(&func->card->dev);
}

3 changes: 0 additions & 3 deletions drivers/net/ethernet/atheros/atl1c/atl1c.h
Original file line number Diff line number Diff line change
Expand Up @@ -504,15 +504,12 @@ struct atl1c_rrd_ring {
u16 next_to_use;
u16 next_to_clean;
struct napi_struct napi;
struct page *rx_page;
unsigned int rx_page_offset;
};

/* board specific private data structure */
struct atl1c_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
unsigned int rx_frag_size;
struct atl1c_hw hw;
struct atl1c_hw_stats hw_stats;
struct mii_if_info mii; /* MII interface info */
Expand Down
67 changes: 16 additions & 51 deletions drivers/net/ethernet/atheros/atl1c/atl1c_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,15 +493,10 @@ static int atl1c_set_mac_addr(struct net_device *netdev, void *p)
static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter,
struct net_device *dev)
{
unsigned int head_size;
int mtu = dev->mtu;

adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ?
roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE;

head_size = SKB_DATA_ALIGN(adapter->rx_buffer_len + NET_SKB_PAD + NET_IP_ALIGN) +
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
adapter->rx_frag_size = roundup_pow_of_two(head_size);
}

static netdev_features_t atl1c_fix_features(struct net_device *netdev,
Expand Down Expand Up @@ -974,7 +969,6 @@ static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
static void atl1c_free_ring_resources(struct atl1c_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
int i;

dma_free_coherent(&pdev->dev, adapter->ring_header.size,
adapter->ring_header.desc, adapter->ring_header.dma);
Expand All @@ -987,12 +981,6 @@ static void atl1c_free_ring_resources(struct atl1c_adapter *adapter)
kfree(adapter->tpd_ring[0].buffer_info);
adapter->tpd_ring[0].buffer_info = NULL;
}
for (i = 0; i < adapter->rx_queue_count; ++i) {
if (adapter->rrd_ring[i].rx_page) {
put_page(adapter->rrd_ring[i].rx_page);
adapter->rrd_ring[i].rx_page = NULL;
}
}
}

/**
Expand Down Expand Up @@ -1764,48 +1752,11 @@ static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter,
skb_checksum_none_assert(skb);
}

static struct sk_buff *atl1c_alloc_skb(struct atl1c_adapter *adapter,
u32 queue, bool napi_mode)
{
struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[queue];
struct sk_buff *skb;
struct page *page;

if (adapter->rx_frag_size > PAGE_SIZE) {
if (likely(napi_mode))
return napi_alloc_skb(&rrd_ring->napi,
adapter->rx_buffer_len);
else
return netdev_alloc_skb_ip_align(adapter->netdev,
adapter->rx_buffer_len);
}

page = rrd_ring->rx_page;
if (!page) {
page = alloc_page(GFP_ATOMIC);
if (unlikely(!page))
return NULL;
rrd_ring->rx_page = page;
rrd_ring->rx_page_offset = 0;
}

skb = build_skb(page_address(page) + rrd_ring->rx_page_offset,
adapter->rx_frag_size);
if (likely(skb)) {
skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
rrd_ring->rx_page_offset += adapter->rx_frag_size;
if (rrd_ring->rx_page_offset >= PAGE_SIZE)
rrd_ring->rx_page = NULL;
else
get_page(page);
}
return skb;
}

static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, u32 queue,
bool napi_mode)
{
struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[queue];
struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[queue];
struct pci_dev *pdev = adapter->pdev;
struct atl1c_buffer *buffer_info, *next_info;
struct sk_buff *skb;
Expand All @@ -1824,13 +1775,27 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, u32 queue,
while (next_info->flags & ATL1C_BUFFER_FREE) {
rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);

skb = atl1c_alloc_skb(adapter, queue, napi_mode);
/* When DMA RX address is set to something like
* 0x....fc0, it will be very likely to cause DMA
* RFD overflow issue.
*
* To work around it, we apply rx skb with 64 bytes
* longer space, and offset the address whenever
* 0x....fc0 is detected.
*/
if (likely(napi_mode))
skb = napi_alloc_skb(&rrd_ring->napi, adapter->rx_buffer_len + 64);
else
skb = netdev_alloc_skb(adapter->netdev, adapter->rx_buffer_len + 64);
if (unlikely(!skb)) {
if (netif_msg_rx_err(adapter))
dev_warn(&pdev->dev, "alloc rx buffer failed\n");
break;
}

if (((unsigned long)skb->data & 0xfff) == 0xfc0)
skb_reserve(skb, 64);

/*
* Make buffer alignment 2 beyond a 16 byte boundary
* this will result in a 16 byte aligned IP header after
Expand Down
16 changes: 15 additions & 1 deletion fs/ext4/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,20 @@ static ext4_fsblk_t ext4_valid_block_bitmap_padding(struct super_block *sb,
return (next_zero_bit < bitmap_size ? next_zero_bit : 0);
}

struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
ext4_group_t group)
{
struct ext4_group_info **grp_info;
long indexv, indexh;

if (unlikely(group >= EXT4_SB(sb)->s_groups_count))
return NULL;
indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb));
indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1);
grp_info = sbi_array_rcu_deref(EXT4_SB(sb), s_group_info, indexv);
return grp_info[indexh];
}

/*
* Return the block number which was discovered to be invalid, or 0 if
* the block bitmap is valid.
Expand Down Expand Up @@ -395,7 +409,7 @@ static int ext4_validate_block_bitmap(struct super_block *sb,

if (buffer_verified(bh))
return 0;
if (EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
if (!grp || EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
return -EFSCORRUPTED;

ext4_lock_group(sb, block_group);
Expand Down
15 changes: 2 additions & 13 deletions fs/ext4/ext4.h
Original file line number Diff line number Diff line change
Expand Up @@ -2741,6 +2741,8 @@ extern void ext4_check_blocks_bitmap(struct super_block *);
extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
ext4_group_t block_group,
struct buffer_head ** bh);
extern struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
ext4_group_t group);
extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);

extern struct buffer_head *ext4_read_block_bitmap_nowait(struct super_block *sb,
Expand Down Expand Up @@ -3348,19 +3350,6 @@ static inline void ext4_isize_set(struct ext4_inode *raw_inode, loff_t i_size)
raw_inode->i_size_high = cpu_to_le32(i_size >> 32);
}

static inline
struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
ext4_group_t group)
{
struct ext4_group_info **grp_info;
long indexv, indexh;
BUG_ON(group >= EXT4_SB(sb)->s_groups_count);
indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb));
indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1);
grp_info = sbi_array_rcu_deref(EXT4_SB(sb), s_group_info, indexv);
return grp_info[indexh];
}

/*
* Reading s_groups_count requires using smp_rmb() afterwards. See
* the locking protocol documented in the comments of ext4_group_add()
Expand Down
12 changes: 8 additions & 4 deletions fs/ext4/ialloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ static int ext4_validate_inode_bitmap(struct super_block *sb,

if (buffer_verified(bh))
return 0;
if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
if (!grp || EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
return -EFSCORRUPTED;

ext4_lock_group(sb, block_group);
Expand Down Expand Up @@ -293,7 +293,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
}
if (!(sbi->s_mount_state & EXT4_FC_REPLAY)) {
grp = ext4_get_group_info(sb, block_group);
if (unlikely(EXT4_MB_GRP_IBITMAP_CORRUPT(grp))) {
if (!grp || unlikely(EXT4_MB_GRP_IBITMAP_CORRUPT(grp))) {
fatal = -EFSCORRUPTED;
goto error_return;
}
Expand Down Expand Up @@ -1046,7 +1046,7 @@ struct inode *__ext4_new_inode(struct user_namespace *mnt_userns,
* Skip groups with already-known suspicious inode
* tables
*/
if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
if (!grp || EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
goto next_group;
}

Expand Down Expand Up @@ -1183,6 +1183,10 @@ struct inode *__ext4_new_inode(struct user_namespace *mnt_userns,

if (!(sbi->s_mount_state & EXT4_FC_REPLAY)) {
grp = ext4_get_group_info(sb, group);
if (!grp) {
err = -EFSCORRUPTED;
goto out;
}
down_read(&grp->alloc_sem); /*
* protect vs itable
* lazyinit
Expand Down Expand Up @@ -1526,7 +1530,7 @@ int ext4_init_inode_table(struct super_block *sb, ext4_group_t group,
}

gdp = ext4_get_group_desc(sb, group, &group_desc_bh);
if (!gdp)
if (!gdp || !grp)
goto out;

/*
Expand Down
Loading
Loading