The previous umad deadlock fix left ib_umad_kill_port() stillvulnerable to deadlocking. This patch fixes that by downgrading ourlock to a read lock when we might end up trying to reacquire the lockfor reading.

- list_for_each_entry(file, &port->file_list, port_list)- for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id) {- if (!file->agent[id])- continue;- ib_unregister_mad_agent(file->agent[id]);- file->agent[id] = NULL;- }+ /*+ * Now go through the list of files attached to this port and+ * unregister all of their MAD agents. We need to hold+ * port->mutex while doing this to avoid racing with+ * ib_umad_close(), but we can't hold the mutex for writing+ * while calling ib_unregister_mad_agent(), since that might+ * deadlock by calling back into queue_packet(). So we+ * downgrade our lock to a read lock, and then drop and+ * reacquire the write lock for the next iteration.+ *+ * We do list_del_init() on the file's list_head so that the+ * list_del in ib_umad_close() is still OK, even after the+ * file is removed from the list.+ */+ while (!list_empty(&port->file_list)) {+ file = list_entry(port->file_list.next, struct ib_umad_file,+ port_list);++ file->agents_dead = 1;+ list_del_init(&file->port_list);++ downgrade_write(&port->mutex);++ for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id)+ if (file->agent[id])+ ib_unregister_mad_agent(file->agent[id]);++ up_read(&port->mutex);+ down_write(&port->mutex);+ }