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
56 changes: 21 additions & 35 deletions drivers/infiniband/core/iwcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ static struct workqueue_struct *iwcm_wq;
struct iwcm_work {
struct work_struct work;
struct iwcm_id_private *cm_id;
struct list_head list;
struct iw_cm_event event;
struct list_head free_list;
};
Expand Down Expand Up @@ -177,7 +176,6 @@ static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count)
return -ENOMEM;
}
work->cm_id = cm_id_priv;
INIT_LIST_HEAD(&work->list);
put_work(work);
}
return 0;
Expand Down Expand Up @@ -212,7 +210,6 @@ static void free_cm_id(struct iwcm_id_private *cm_id_priv)
static bool iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
{
if (refcount_dec_and_test(&cm_id_priv->refcount)) {
BUG_ON(!list_empty(&cm_id_priv->work_list));
free_cm_id(cm_id_priv);
return true;
}
Expand Down Expand Up @@ -259,7 +256,6 @@ struct iw_cm_id *iw_create_cm_id(struct ib_device *device,
refcount_set(&cm_id_priv->refcount, 1);
init_waitqueue_head(&cm_id_priv->connect_wait);
init_completion(&cm_id_priv->destroy_comp);
INIT_LIST_HEAD(&cm_id_priv->work_list);
INIT_LIST_HEAD(&cm_id_priv->work_free_list);

return &cm_id_priv->id;
Expand Down Expand Up @@ -1006,13 +1002,13 @@ static int process_event(struct iwcm_id_private *cm_id_priv,
}

/*
* Process events on the work_list for the cm_id. If the callback
* function requests that the cm_id be deleted, a flag is set in the
* cm_id flags to indicate that when the last reference is
* removed, the cm_id is to be destroyed. This is necessary to
* distinguish between an object that will be destroyed by the app
* thread asleep on the destroy_comp list vs. an object destroyed
* here synchronously when the last reference is removed.
* Process events for the cm_id. If the callback function requests
* that the cm_id be deleted, a flag is set in the cm_id flags to
* indicate that when the last reference is removed, the cm_id is
* to be destroyed. This is necessary to distinguish between an
* object that will be destroyed by the app thread asleep on the
* destroy_comp list vs. an object destroyed here synchronously
* when the last reference is removed.
*/
static void cm_work_handler(struct work_struct *_work)
{
Expand All @@ -1023,35 +1019,26 @@ static void cm_work_handler(struct work_struct *_work)
int ret = 0;

spin_lock_irqsave(&cm_id_priv->lock, flags);
while (!list_empty(&cm_id_priv->work_list)) {
work = list_first_entry(&cm_id_priv->work_list,
struct iwcm_work, list);
list_del_init(&work->list);
levent = work->event;
put_work(work);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);

if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) {
ret = process_event(cm_id_priv, &levent);
if (ret) {
destroy_cm_id(&cm_id_priv->id);
WARN_ON_ONCE(iwcm_deref_id(cm_id_priv));
}
} else
pr_debug("dropping event %d\n", levent.event);
if (iwcm_deref_id(cm_id_priv))
return;
spin_lock_irqsave(&cm_id_priv->lock, flags);
}
levent = work->event;
put_work(work);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);

if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) {
ret = process_event(cm_id_priv, &levent);
if (ret) {
destroy_cm_id(&cm_id_priv->id);
WARN_ON_ONCE(iwcm_deref_id(cm_id_priv));
}
} else
pr_debug("dropping event %d\n", levent.event);
if (iwcm_deref_id(cm_id_priv))
return;
}

/*
* This function is called on interrupt context. Schedule events on
* the iwcm_wq thread to allow callback functions to downcall into
* the CM and/or block. Events are queued to a per-CM_ID
* work_list. If this is the first event on the work_list, the work
* element is also queued on the iwcm_wq thread.
* the CM and/or block.
*
* Each event holds a reference on the cm_id. Until the last posted
* event has been delivered and processed, the cm_id cannot be
Expand Down Expand Up @@ -1093,7 +1080,6 @@ static int cm_event_handler(struct iw_cm_id *cm_id,
}

refcount_inc(&cm_id_priv->refcount);
list_add_tail(&work->list, &cm_id_priv->work_list);
queue_work(iwcm_wq, &work->work);
out:
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
Expand Down
1 change: 0 additions & 1 deletion drivers/infiniband/core/iwcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ struct iwcm_id_private {
struct ib_qp *qp;
struct completion destroy_comp;
wait_queue_head_t connect_wait;
struct list_head work_list;
spinlock_t lock;
refcount_t refcount;
struct list_head work_free_list;
Expand Down
36 changes: 28 additions & 8 deletions fs/xfs/libxfs/xfs_attr_leaf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,7 @@ xfs_attr3_leaf_add_work(
struct xfs_attr_leaf_name_local *name_loc;
struct xfs_attr_leaf_name_remote *name_rmt;
struct xfs_mount *mp;
int old_end, new_end;
int tmp;
int i;

Expand Down Expand Up @@ -1499,17 +1500,36 @@ xfs_attr3_leaf_add_work(
if (be16_to_cpu(entry->nameidx) < ichdr->firstused)
ichdr->firstused = be16_to_cpu(entry->nameidx);

ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t)
+ xfs_attr3_leaf_hdr_size(leaf));
tmp = (ichdr->count - 1) * sizeof(xfs_attr_leaf_entry_t)
+ xfs_attr3_leaf_hdr_size(leaf);
new_end = ichdr->count * sizeof(struct xfs_attr_leaf_entry) +
xfs_attr3_leaf_hdr_size(leaf);
old_end = new_end - sizeof(struct xfs_attr_leaf_entry);

ASSERT(ichdr->firstused >= new_end);

for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
if (ichdr->freemap[i].base == tmp) {
ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t);
int diff = 0;

if (ichdr->freemap[i].base == old_end) {
/*
* This freemap entry starts at the old end of the
* leaf entry array, so we need to adjust its base
* upward to accomodate the larger array.
*/
diff = sizeof(struct xfs_attr_leaf_entry);
} else if (ichdr->freemap[i].size > 0 &&
ichdr->freemap[i].base < new_end) {
/*
* This freemap entry starts in the space claimed by
* the new leaf entry. Adjust its base upward to
* reflect that.
*/
diff = new_end - ichdr->freemap[i].base;
}

if (diff) {
ichdr->freemap[i].base += diff;
ichdr->freemap[i].size -=
min_t(uint16_t, ichdr->freemap[i].size,
sizeof(xfs_attr_leaf_entry_t));
min_t(uint16_t, ichdr->freemap[i].size, diff);
}
}
ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index);
Expand Down
3 changes: 3 additions & 0 deletions net/ceph/osd_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -4304,6 +4304,9 @@ static void osd_fault(struct ceph_connection *con)
goto out_unlock;
}

osd->o_sparse_op_idx = -1;
ceph_init_sparse_read(&osd->o_sparse_read);

if (!reopen_osd(osd))
kick_osd_requests(osd);
maybe_request_map(osdc);
Expand Down
4 changes: 2 additions & 2 deletions net/mac80211/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -3501,11 +3501,11 @@ void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
struct ieee80211_local *local =
container_of(work, struct ieee80211_local, radar_detected_work);
struct cfg80211_chan_def chandef;
struct ieee80211_chanctx *ctx;
struct ieee80211_chanctx *ctx, *tmp;

lockdep_assert_wiphy(local->hw.wiphy);

list_for_each_entry(ctx, &local->chanctx_list, list) {
list_for_each_entry_safe(ctx, tmp, &local->chanctx_list, list) {
if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
continue;

Expand Down
26 changes: 13 additions & 13 deletions net/smc/smc_clc.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,26 +621,26 @@ static int smc_clc_prfx_match6_rcu(struct net_device *dev,
int smc_clc_prfx_match(struct socket *clcsock,
struct smc_clc_msg_proposal_prefix *prop)
{
struct dst_entry *dst = sk_dst_get(clcsock->sk);
struct net_device *dev;
struct dst_entry *dst;
int rc;

if (!dst) {
rc = -ENOTCONN;
goto out;
}
if (!dst->dev) {
rcu_read_lock();

dst = __sk_dst_get(clcsock->sk);
dev = dst ? dst_dev_rcu(dst) : NULL;
if (!dev) {
rc = -ENODEV;
goto out_rel;
goto out;
}
rcu_read_lock();

if (!prop->ipv6_prefixes_cnt)
rc = smc_clc_prfx_match4_rcu(dst->dev, prop);
rc = smc_clc_prfx_match4_rcu(dev, prop);
else
rc = smc_clc_prfx_match6_rcu(dst->dev, prop);
rcu_read_unlock();
out_rel:
dst_release(dst);
rc = smc_clc_prfx_match6_rcu(dev, prop);
out:
rcu_read_unlock();

return rc;
}

Expand Down
43 changes: 22 additions & 21 deletions net/smc/smc_pnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1129,37 +1129,38 @@ static void smc_pnet_find_ism_by_pnetid(struct net_device *ndev,
*/
void smc_pnet_find_roce_resource(struct sock *sk, struct smc_init_info *ini)
{
struct dst_entry *dst = sk_dst_get(sk);

if (!dst)
goto out;
if (!dst->dev)
goto out_rel;
struct net_device *dev;
struct dst_entry *dst;

smc_pnet_find_roce_by_pnetid(dst->dev, ini);
rcu_read_lock();
dst = __sk_dst_get(sk);
dev = dst ? dst_dev_rcu(dst) : NULL;
dev_hold(dev);
rcu_read_unlock();

out_rel:
dst_release(dst);
out:
return;
if (dev) {
smc_pnet_find_roce_by_pnetid(dev, ini);
dev_put(dev);
}
}

void smc_pnet_find_ism_resource(struct sock *sk, struct smc_init_info *ini)
{
struct dst_entry *dst = sk_dst_get(sk);
struct net_device *dev;
struct dst_entry *dst;

ini->ism_dev[0] = NULL;
if (!dst)
goto out;
if (!dst->dev)
goto out_rel;

smc_pnet_find_ism_by_pnetid(dst->dev, ini);
rcu_read_lock();
dst = __sk_dst_get(sk);
dev = dst ? dst_dev_rcu(dst) : NULL;
dev_hold(dev);
rcu_read_unlock();

out_rel:
dst_release(dst);
out:
return;
if (dev) {
smc_pnet_find_ism_by_pnetid(dev, ini);
dev_put(dev);
}
}

/* Lookup and apply a pnet table entry to the given ib device.
Expand Down
Loading