Add a semaphore to some ML2 operations

This patch adds a semaphore for serializing the delete port API
calls and update_port_status calls to avoid simultaneous
attempts to acquire SQL update locks on the port table from
the same thread pool.

This semaphore has been introduced to avoid undesired eventlet
yields which trigger 'lock wait timeout' errors in the DB backend;
it should have a negligible impact on the overall performance.

Change-Id: I0ec947086e533945942ae93402943dec69b218ef
Partial-Bug: 1283522
This commit is contained in:
Salvatore Orlando 2014-03-13 15:06:12 -07:00 committed by Kevin Benton
parent 3ccb3be933
commit 1dab002ff5

View File

@ -12,6 +12,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import contextlib
from oslo.config import cfg
from sqlalchemy import exc as sql_exc
@ -41,6 +42,7 @@ from neutron.openstack.common import db as os_db
from neutron.openstack.common import excutils
from neutron.openstack.common import importutils
from neutron.openstack.common import jsonutils
from neutron.openstack.common import lockutils
from neutron.openstack.common import log
from neutron.openstack.common import rpc as c_rpc
from neutron.plugins.common import constants as service_constants
@ -699,7 +701,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
l3plugin.prevent_l3_port_deletion(context, id)
session = context.session
with session.begin(subtransactions=True):
# REVISIT: Serialize this operation with a semaphore to prevent
# undesired eventlet yields leading to 'lock wait timeout' errors
with contextlib.nested(lockutils.lock('db-access'),
session.begin(subtransactions=True)):
try:
port_db = (session.query(models_v2.Port).
enable_eagerloads(False).
@ -735,7 +740,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
def update_port_status(self, context, port_id, status):
updated = False
session = context.session
with session.begin(subtransactions=True):
# REVISIT: Serialize this operation with a semaphore to prevent
# undesired eventlet yields leading to 'lock wait timeout' errors
with contextlib.nested(lockutils.lock('db-access'),
session.begin(subtransactions=True)):
port = db.get_port(session, port_id)
if not port:
LOG.warning(_("Port %(port)s updated up by agent not found"),