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

Commit 561c7df6 authored by Andy Grover's avatar Andy Grover Committed by David S. Miller
Browse files

RDS: Do not call set_page_dirty() with irqs off



set_page_dirty() unconditionally re-enables interrupts, so
if we call it with irqs off, they will be on after the call,
and that's bad. This patch moves the call after we've re-enabled
interrupts in send_drop_to(), so it's safe.

Also, add BUG_ONs to let us know if we ever do call set_page_dirty
with interrupts off.

Signed-off-by: default avatarAndy Grover <andy.grover@oracle.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 450d06c0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -440,6 +440,7 @@ static void __rds_ib_teardown_mr(struct rds_ib_mr *ibmr)

			/* FIXME we need a way to tell a r/w MR
			 * from a r/o MR */
			BUG_ON(in_interrupt());
			set_page_dirty(page);
			put_page(page);
		}
+3 −1
Original line number Diff line number Diff line
@@ -438,8 +438,10 @@ void rds_rdma_free_op(struct rds_rdma_op *ro)
		/* Mark page dirty if it was possibly modified, which
		 * is the case for a RDMA_READ which copies from remote
		 * to local memory */
		if (!ro->r_write)
		if (!ro->r_write) {
			BUG_ON(in_interrupt());
			set_page_dirty(page);
		}
		put_page(page);
	}

+8 −6
Original line number Diff line number Diff line
@@ -507,12 +507,13 @@ EXPORT_SYMBOL_GPL(rds_send_get_message);
 */
void rds_send_remove_from_sock(struct list_head *messages, int status)
{
	unsigned long flags = 0; /* silence gcc :P */
	unsigned long flags;
	struct rds_sock *rs = NULL;
	struct rds_message *rm;

	local_irq_save(flags);
	while (!list_empty(messages)) {
		int was_on_sock = 0;

		rm = list_entry(messages->next, struct rds_message,
				m_conn_item);
		list_del_init(&rm->m_conn_item);
@@ -527,7 +528,7 @@ void rds_send_remove_from_sock(struct list_head *messages, int status)
		 * while we're messing with it. It does not prevent the
		 * message from being removed from the socket, though.
		 */
		spin_lock(&rm->m_rs_lock);
		spin_lock_irqsave(&rm->m_rs_lock, flags);
		if (!test_bit(RDS_MSG_ON_SOCK, &rm->m_flags))
			goto unlock_and_drop;

@@ -556,13 +557,15 @@ void rds_send_remove_from_sock(struct list_head *messages, int status)
					notifier->n_status = status;
				rm->m_rdma_op->r_notifier = NULL;
			}
			rds_message_put(rm);
			was_on_sock = 1;
			rm->m_rs = NULL;
		}
		spin_unlock(&rs->rs_lock);

unlock_and_drop:
		spin_unlock(&rm->m_rs_lock);
		spin_unlock_irqrestore(&rm->m_rs_lock, flags);
		rds_message_put(rm);
		if (was_on_sock)
			rds_message_put(rm);
	}

@@ -570,7 +573,6 @@ void rds_send_remove_from_sock(struct list_head *messages, int status)
		rds_wake_sk_sleep(rs);
		sock_put(rds_rs_to_sk(rs));
	}
	local_irq_restore(flags);
}

/*