[DRBD-cvs] r1450 - trunk/drbd
drbd-user@lists.linbit.com
drbd-user@lists.linbit.com
Fri, 23 Jul 2004 14:17:18 +0200 (CEST)
Author: lars
Date: 2004-07-23 14:17:17 +0200 (Fri, 23 Jul 2004)
New Revision: 1450
Modified:
trunk/drbd/drbd_main.c
Log:
fallback to sendmsg instead of sendpage under certain conditions
Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c 2004-07-23 11:50:08 UTC (rev 1449)
+++ trunk/drbd/drbd_main.c 2004-07-23 12:17:17 UTC (rev 1450)
@@ -883,16 +883,62 @@
that we do not reuse our own buffer pages (EEs) to early, therefore
we have the net_ee list.
*/
+int _drbd_no_send_page(drbd_dev *mdev, struct page *page,
+ int offset, size_t size)
+{
+ int ret;
+ ret = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, 0);
+ kunmap(page);
+ return ret;
+}
+
int _drbd_send_page(drbd_dev *mdev, struct page *page,
int offset, size_t size)
{
int sent,ok;
int len = size;
+ static unsigned long total = 0;
+ static unsigned long fallback = 0;
+ static unsigned long last_rep = 0;
+ /* report statistics, every 4096 calls,
+ * if we had at least one fallback,
+ * but at most once every five minutes */
+ if ( (++total & 0xfffUL) == 0 ) {
+ unsigned long now = jiffies;
+ if (fallback && time_before(last_rep+300*HZ, now)) {
+ last_rep = now;
+ INFO("sendpage fallback/total: %lu/%lu\n",
+ fallback, total);
+ }
+ }
+
spin_lock(&mdev->send_task_lock);
mdev->send_task=current;
spin_unlock(&mdev->send_task_lock);
+ /* PARANOIA. if this ever triggers,
+ * something in the layers above us is really kaputt */
+ ERR_IF (page_count(page) < 1) {
+ ERR("someone wants to send a free page!\n");
+ dump_stack();
+ ++fallback;
+ sent = _drbd_no_send_page(mdev, page, offset, size);
+ if (likely(sent > 0)) len -= sent;
+ goto out;
+ }
+
+ if (PageSlab(page)) {
+ /* probably xfs. fall back to sendmsg instead of sendpage.
+ * FIXME
+ * we should rather understand and fix the real problem...
+ */
+ ++fallback;
+ sent = _drbd_no_send_page(mdev, page, offset, size);
+ if (likely(sent > 0)) len -= sent;
+ goto out;
+ }
+
do {
sent = mdev->data.socket->ops->sendpage(mdev->data.socket,page,
offset,len,
@@ -914,6 +960,7 @@
// FIXME test "last_received" ...
} while(len > 0 /* THINK && mdev->cstate >= Connected*/);
+ out:
spin_lock(&mdev->send_task_lock);
mdev->send_task=NULL;
spin_unlock(&mdev->send_task_lock);